Developers

Event catalogue

Every webhook event type, the scope that entitles it, when it fires and its payload.

lead.confirmation_status_changed
Scopeorders:write

The 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_changed
Scopeorders:write

A line was added, removed, or its quantity or unit price changed, or the articles total moved.

lead.delivery_status_changed
Scopeorders:write

The 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.changed
Scopecatalogue:read or cod_drop:write

A product (own or adopted) changed: its name, text, category, image or variants.

product.removed
Scopecatalogue:read or cod_drop:write

A 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.changed
Scopecatalogue:read

The 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.created
Scopecatalogue:read or cod_drop:write

The seller adopted a COD Drop product, adopted it again after giving it back, or shared it with apps again.

adoption.updated
Scopecatalogue:read or cod_drop:write

An adoption was paused, resumed, blocked or unblocked by the creator, or its sale prices, discount ladder or SKU changed.

adoption.removed
Scopecatalogue:read or cod_drop:write

The adoption was given back, the seller stopped sharing it with apps, or the product was deleted.

cod_drop.catalog_changed
Scopecatalogue:read + app enabled by ColiSwift

A product of the COD Drop catalogue the seller may adopt from was published, unpublished or changed.

test.ping
Scope—

Sandbox 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: the 201 answer of POST /orders is 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.

Payload
{
  "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.

Payload
{
  "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

Payload
{
  "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.

Own product
{
  "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
}
Adopted product
{
  "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
}
data
product_id · referencestring

The product and its SKU.

label · category · description · image_urlstring | null

The product’s current values.

adoptedtrue

Present 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.

Payload
{
  "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.

Payload
{
  "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).

Payload — adopted product
{
  "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.

adoption.created
{
  "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
}
data
adoption_idstring

The adoption. One per (seller, product); a re-adoption keeps the same id.

product_idstring

The COD Drop product — the id resale orders and /cod-drop/adoptions/{productId} use.

reasonstring

The first of reasons.

reasonsstring[]

adoption.created: adopted or shared. adoption.removed: removed or unshared. adoption.updated: one or more of the others, in this order.

  • adopted
  • shared
  • paused
  • resumed
  • blocked
  • unblocked
  • status_changed
  • price_changed
  • discounts_changed
  • sku_changed
  • removed
  • unshared
status · previous_statusstring

The adoption’s status after and before the change (previous_status is null on a first adoption). Sell only while active.

  • active
  • paused
  • blocked
  • removed
productobject | null

The data of product.changed for this product.

variants[]object[]

variant_id, label, sku.

prices[]object[]

Per country: country, sale (the seller’s own sale price there) and cession (the COD Drop price, USD). 4-decimal strings.

  • Treat adoption.created as an upsert keyed on product_id: the same adoption can be created again after a removal (re-adoption, re-sharing) with the same adoption_id.
  • Nothing moved, nothing sent: saving an adoption with the same values fires no event.
  • Received with catalogue:read or cod_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:read and an empty event filter, and never on a sandbox app. An app without it gets 403 COD_DROP_CATALOG_NOT_ENABLED on 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_CLOSED when 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.
Payload
{
  "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.

Payload
{
  "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
}