Event catalogue
Every webhook event type, the scope that entitles it, when it fires and its payload.
lead.confirmation_status_changedThe order’s status moved before shipping: it was confirmed with the customer and locked for shipping ("confirmed", confirmed_at set), cancelled ("cancelled"), sent back to the call centre ("new"), or is waiting for stock ("out_of_stock").
lead.items_changedA line was added, removed, or its quantity or unit price changed, or the articles total moved.
lead.delivery_status_changedThe delivery moved: the parcel left with the deliveryman or the carrier (status: "shipped"), was delivered ("delivered"), came back for good ("returned"), or a delivery attempt failed or was rescheduled (still "shipped").
product.changedA product (own or adopted) changed: its name, text, category, image or variants.
product.removedA product left what your app can read: the seller switched it off or deleted it, or the adoption was given back, paused, blocked or no longer shared with apps, or the seller’s COD Drop access was closed (adopted products). Sent once; the product coming back sends product.changed.
price.changedThe seller’s sale price of a product in one country changed, or — for an adopted product — the COD Drop price the seller pays (one event per country).
adoption.createdThe seller adopted a COD Drop product, adopted it again after giving it back, or shared it with apps again.
adoption.updatedAn adoption was paused, resumed, blocked or unblocked by the creator, or its sale prices, discount ladder or SKU changed.
adoption.removedThe adoption was given back, the seller stopped sharing it with apps, or the product was deleted.
cod_drop.catalog_changedA product of the COD Drop catalogue the seller may adopt from was published, unpublished or changed.
test.pingSandbox only: you clicked « Send test event » on your app (test event).
Every event arrives in the envelope. Ignore event types you do not know — new ones may be added.
Order events (lead.*)
All three carry the Order object as data — the same short object as GET /orders/{externalId} — so you can simply store it. They are sent only for orders your app created or claimed, and only to your app.
- There is no
lead.created: the201answer ofPOST /ordersis the creation. - One change can produce several events, emitted in this order:
lead.confirmation_status_changed,lead.items_changed,lead.delivery_status_changed.
lead.confirmation_status_changed
The order was confirmed with the customer and locked for shipping: status: "confirmed", confirmed_at set.
{
"data": {
"articles_amount": "398.00",
"confirmed_at": "2026-11-03T10:15:05.000Z",
"country": "MA",
"created_at": "2026-11-03T09:58:41.000Z",
"currency": "MAD",
"external_id": "shop_10482",
"lead_id": "6f1c2a9e-3b7d-4c11-9a52-0d8e4b7f2c10",
"lines": [
{
"line_id": "c0a8e1f2-5d6b-4a7c-9e8f-1a2b3c4d5e6f",
"product_id": "9e8d7c6b-5a4f-4e3d-2c1b-0a9f8e7d6c5b",
"product_name": "Sérum à l'huile d'argan 30 ml",
"product_reference": "SERUM-ARGAN-30",
"quantity": 2,
"unit_price": "199.00",
"variant_id": null,
"variant_label": null
}
],
"order_code": "MA03112026-0042",
"status": "confirmed",
"store_id": "b2d4e6f8-1a3c-4e5f-8a9b-0c1d2e3f4a5b",
"updated_at": "2026-11-03T10:15:05.000Z"
},
"event": "lead.confirmation_status_changed",
"event_id": "evt_5f1c9a0b2d3e4f5a6b7c8d9e",
"occurred_at": "2026-11-02T11:20:41.302Z",
"seller_id": "6a1c2f0e-3b7d-4c55-9e10-2f8a4b7c9d01",
"sequence": 4012
}The customer cancelled: status becomes cancelled.
{
"data": {
"articles_amount": "398.00",
"confirmed_at": null,
"country": "MA",
"created_at": "2026-11-03T09:58:41.000Z",
"currency": "MAD",
"external_id": "shop_10482",
"lead_id": "6f1c2a9e-3b7d-4c11-9a52-0d8e4b7f2c10",
"lines": [
{
"line_id": "c0a8e1f2-5d6b-4a7c-9e8f-1a2b3c4d5e6f",
"product_id": "9e8d7c6b-5a4f-4e3d-2c1b-0a9f8e7d6c5b",
"product_name": "Sérum à l'huile d'argan 30 ml",
"product_reference": "SERUM-ARGAN-30",
"quantity": 2,
"unit_price": "199.00",
"variant_id": null,
"variant_label": null
}
],
"order_code": "MA03112026-0042",
"status": "cancelled",
"store_id": "b2d4e6f8-1a3c-4e5f-8a9b-0c1d2e3f4a5b",
"updated_at": "2026-11-03T10:14:22.000Z"
},
"event": "lead.confirmation_status_changed",
"event_id": "evt_5f1c9a0b2d3e4f5a6b7c8d9e",
"occurred_at": "2026-11-02T11:20:41.302Z",
"seller_id": "6a1c2f0e-3b7d-4c55-9e10-2f8a4b7c9d01",
"sequence": 4013
}lead.delivery_status_changed
{
"data": {
"articles_amount": "398.00",
"confirmed_at": "2026-11-03T10:15:05.000Z",
"country": "MA",
"created_at": "2026-11-03T09:58:41.000Z",
"currency": "MAD",
"external_id": "shop_10482",
"lead_id": "6f1c2a9e-3b7d-4c11-9a52-0d8e4b7f2c10",
"lines": [
{
"line_id": "c0a8e1f2-5d6b-4a7c-9e8f-1a2b3c4d5e6f",
"product_id": "9e8d7c6b-5a4f-4e3d-2c1b-0a9f8e7d6c5b",
"product_name": "Sérum à l'huile d'argan 30 ml",
"product_reference": "SERUM-ARGAN-30",
"quantity": 2,
"unit_price": "199.00",
"variant_id": null,
"variant_label": null
}
],
"order_code": "MA03112026-0042",
"status": "delivered",
"store_id": "b2d4e6f8-1a3c-4e5f-8a9b-0c1d2e3f4a5b",
"updated_at": "2026-11-04T15:47:12.000Z"
},
"event": "lead.delivery_status_changed",
"event_id": "evt_5f1c9a0b2d3e4f5a6b7c8d9e",
"occurred_at": "2026-11-02T11:20:41.302Z",
"seller_id": "6a1c2f0e-3b7d-4c55-9e10-2f8a4b7c9d01",
"sequence": 4398
}Catalogue events
product.changed
A product of the seller changed — their own product, or a COD Drop product they adopted ("adopted": true). It is sent when the name, text, category or image changes, and when a variant is added, renamed, re-SKU’d or removed. The payload does not list variants or prices: read the product back with GET /products/{id} — a 404 means it is no longer for sale.
{
"data": {
"category": "beauty",
"description": "Brightening serum.",
"image_url": "https://cdn.example.com/serum.jpg",
"label": "Vitamin C serum 30 ml",
"product_id": "5e6f7a8b-9c0d-4e1f-a2b3-c4d5e6f7a8b9",
"reference": "SER-01"
},
"event": "product.changed",
"event_id": "evt_5f1c9a0b2d3e4f5a6b7c8d9e",
"occurred_at": "2026-11-02T11:20:41.302Z",
"seller_id": "6a1c2f0e-3b7d-4c55-9e10-2f8a4b7c9d01",
"sequence": 4101
}{
"data": {
"adopted": true,
"category": "electronics",
"description": "Warm sunset light, USB powered.",
"image_url": "https://cdn.example.com/lamp.jpg",
"label": "Sunset lamp",
"product_id": "3d4e5f6a-7b8c-4d9e-a0f1-b2c3d4e5f6a7",
"reference": "CRE-LAMP-02"
},
"event": "product.changed",
"event_id": "evt_5f1c9a0b2d3e4f5a6b7c8d9e",
"occurred_at": "2026-11-02T11:20:41.302Z",
"seller_id": "6a1c2f0e-3b7d-4c55-9e10-2f8a4b7c9d01",
"sequence": 4120
}product_id · referencestringThe product and its SKU.
label · category · description · image_urlstring | nullThe product’s current values.
adoptedtruePresent only on an adopted COD Drop product.
product.removed
The product is no longer in what GET /products returns to your app — switched off or deleted by the seller, or an adoption given back, paused, blocked by the creator or no longer shared with apps, or the seller’s COD Drop access closed (all their adopted products leave; reopening it sends product.changed for each). Remove it from your copy (or stop selling it). Sent once, at the move; while it stays out you hear nothing more about it (no product.changed, no price.changed). When it comes back, product.changed is sent. The payload is the id only.
{
"data": {
"product_id": "5e6f7a8b-9c0d-4e1f-a2b3-c4d5e6f7a8b9"
},
"event": "product.removed",
"event_id": "evt_5f1c9a0b2d3e4f5a6b7c8d9e",
"occurred_at": "2026-11-02T11:20:41.302Z",
"seller_id": "6a1c2f0e-3b7d-4c55-9e10-2f8a4b7c9d01",
"sequence": 4122
}Polling instead of listening? GET /products?updatedSince=… lists products that are for sale, so a removed product simply stops appearing: re-read the ids you hold with GET /products/{id} — a 404 means removed.
price.changed
One event per country whose price moved. sale is the seller’s sale price there (for an adopted product, the seller’s own price), a 4-decimal string, absent when not set.
{
"data": {
"country": "MA",
"product_id": "5e6f7a8b-9c0d-4e1f-a2b3-c4d5e6f7a8b9",
"reference": "SER-01",
"sale": "199.0000"
},
"event": "price.changed",
"event_id": "evt_5f1c9a0b2d3e4f5a6b7c8d9e",
"occurred_at": "2026-11-02T11:20:41.302Z",
"seller_id": "6a1c2f0e-3b7d-4c55-9e10-2f8a4b7c9d01",
"sequence": 4121
}For an adopted COD Drop product the event is also sent when the creator changes the COD Drop price, and carries cost: the COD Drop price you pay per unit in that country, with its currency (always USD).
{
"data": {
"cost": "6.0000",
"country": "MA",
"currency": "USD",
"product_id": "3d4e5f6a-7b8c-4d9e-a0f1-b2c3d4e5f6a7",
"reference": "CRE-LAMP-02",
"sale": "149.0000"
},
"event": "price.changed",
"event_id": "evt_5f1c9a0b2d3e4f5a6b7c8d9e",
"occurred_at": "2026-11-02T11:20:41.302Z",
"seller_id": "6a1c2f0e-3b7d-4c55-9e10-2f8a4b7c9d01",
"sequence": 4123
}adoption.created · adoption.updated · adoption.removed
The life of one adoption of the connected seller, whoever made the change: the seller in ColiSwift, your app or another app through the API, the creator blocking the seller.
{
"data": {
"adoption_id": "7f8e9d0c-1b2a-4c3d-9e4f-5a6b7c8d9e0f",
"previous_status": null,
"prices": [
{
"cession": "6.0000",
"country": "MA",
"sale": "149.0000"
}
],
"product": {
"adopted": true,
"category": "electronics",
"description": "Warm sunset light, USB powered.",
"image_url": "https://cdn.example.com/lamp.jpg",
"label": "Sunset lamp",
"product_id": "3d4e5f6a-7b8c-4d9e-a0f1-b2c3d4e5f6a7",
"reference": "CRE-LAMP-02"
},
"product_id": "3d4e5f6a-7b8c-4d9e-a0f1-b2c3d4e5f6a7",
"reason": "adopted",
"reasons": [
"adopted"
],
"status": "active",
"variants": [
{
"label": "White",
"sku": "CRE-LAMP-02-W",
"variant_id": "2b3c4d5e-6f7a-4b8c-9d0e-1f2a3b4c5d6e"
}
]
},
"event": "adoption.created",
"event_id": "evt_5f1c9a0b2d3e4f5a6b7c8d9e",
"occurred_at": "2026-11-02T11:20:41.302Z",
"seller_id": "6a1c2f0e-3b7d-4c55-9e10-2f8a4b7c9d01",
"sequence": 4119
}adoption_idstringThe adoption. One per (seller, product); a re-adoption keeps the same id.
product_idstringThe COD Drop product — the id resale orders and
/cod-drop/adoptions/{productId}use.reasonstringThe first of
reasons.reasonsstring[]adoption.created:adoptedorshared.adoption.removed:removedorunshared.adoption.updated: one or more of the others, in this order.adoptedsharedpausedresumedblockedunblockedstatus_changedprice_changeddiscounts_changedsku_changedremovedunshared
status · previous_statusstringThe adoption’s status after and before the change (
previous_statusisnullon a first adoption). Sell only whileactive.activepausedblockedremoved
productobject | nullThe
dataofproduct.changedfor this product.variants[]object[]variant_id,label,sku.prices[]object[]Per country:
country,sale(the seller’s own sale price there) andcession(the COD Drop price, USD). 4-decimal strings.
- Treat
adoption.createdas an upsert keyed onproduct_id: the same adoption can be created again after a removal (re-adoption, re-sharing) with the sameadoption_id. - Nothing moved, nothing sent: saving an adoption with the same values fires no event.
- Received with
catalogue:readorcod_drop:write. An app with an explicit event filter must list these types to get them.
cod_drop.catalog_changed
The COD Drop catalogue the seller may adopt from moved: a product was published, unpublished or changed (prices, countries, visibility…). The payload carries only productId and reason: re-read GET /cod-drop/catalog/{productId} — a 404 means remove it from your copy. It is also sent to sellers who just lost access to the product (a country removed, the product made private), so their copy can be cleaned up. Never sent to the product’s creator.
- Delivered only to apps for which ColiSwift enabled the COD Drop catalogue synchronisation — off by default, even with
catalogue:readand an empty event filter, and never on a sandbox app. An app without it gets403 COD_DROP_CATALOG_NOT_ENABLEDon the catalogue endpoints anyway. - Delivered only for sellers whose COD Drop access is open: a seller whose access is closed would get
403 COD_DROP_ACCESS_CLOSEDwhen you re-read the item. - Both conditions are checked again when the event is sent (and on a replay): an event queued before the synchronisation or the access was closed is cancelled, not delivered.
{
"data": {
"productId": "3d4e5f6a-7b8c-4d9e-a0f1-b2c3d4e5f6a7",
"reason": "published"
},
"event": "cod_drop.catalog_changed",
"event_id": "evt_5f1c9a0b2d3e4f5a6b7c8d9e",
"occurred_at": "2026-11-02T11:20:41.302Z",
"seller_id": "6a1c2f0e-3b7d-4c55-9e10-2f8a4b7c9d01",
"sequence": 4150
}test.ping (sandbox)
Sent only when you click « Send test event » on one of your sandbox apps, and only to that app. Signed and retried like any event; no scope, no seller connection needed. It never exists in production.
{
"data": {
"client_id": "cs_client_0f1e2d3c4b5a69788796a5b4c3d2e1f0",
"message": "Test event from the ColiSwift sandbox. Verify X-Coliswift-Signature with your webhook secret."
},
"event": "test.ping",
"event_id": "evt_5f1c9a0b2d3e4f5a6b7c8d9e",
"occurred_at": "2026-11-02T11:20:41.302Z",
"seller_id": "6a1c2f0e-3b7d-4c55-9e10-2f8a4b7c9d01",
"sequence": 4201
}
