{
"event": "inventoryMovement",
"occurred_at": "2026-10-12T16:25:00-06:00",
"sequence": 42,
"store_id": 1234,
"products": [
{
"product_name": "Red T-Shirt M",
"product_code": "7501234567890",
"skus": [
"SKU-RED-M"
],
"quantity": 148
},
{
"product_name": "Smartphone 128GB",
"product_code": "7509876543210",
"skus": [
"SKU-PHONE-128"
],
"quantity": 2,
"units": [
{
"unit_code": "356789012345678",
"status": "ACTIVE"
},
{
"unit_code": "356789012345679",
"status": "RESERVED"
},
{
"unit_code": "356789012345680",
"status": "DAMAGED",
"damaged_source": "RETURN"
}
]
},
{
"product_name": "Vitamin C 500mg",
"product_code": "7501111222333",
"skus": [
"SKU-VITC-500"
],
"quantity": 8,
"lots": [
{
"lot_code": "LOT-2026A",
"expiration_date": "2026-12-31",
"quantity": 3
},
{
"lot_code": "LOT-2027B",
"expiration_date": "2027-06-30",
"quantity": 5
}
]
}
]
}Inventory snapshot after a stock movement
Cubbo sends this event to your inventory webhook URL whenever the stock of one or more products changes (an order ships, stock is received or put away, a return is reentered, an adjustment is made, and so on). The body is a snapshot of the current stock of the affected products, not a delta. When Cubbo runs a full resynchronization for your store, the snapshot contains every product of the store.
- This feed must be enabled for your integration (it is opt-in and requires the order webhook feed to be active). It can point at a different URL than the order feed and can carry its own custom headers.
- Products without any SKU are omitted. If no product remains, nothing is sent.
- Events for one integration are delivered one at a time, in order.
sequenceis a monotonic counter per integration: process events bysequence, not by arrival time, and treat a lowersequencethan the last one you processed as stale. Gaps are possible. X-Cubbo-Idempotency-Keyis a UUID that stays the same on every retry of the same event.- The payload is additive: ignore fields you do not know.
{
"event": "inventoryMovement",
"occurred_at": "2026-10-12T16:25:00-06:00",
"sequence": 42,
"store_id": 1234,
"products": [
{
"product_name": "Red T-Shirt M",
"product_code": "7501234567890",
"skus": [
"SKU-RED-M"
],
"quantity": 148
},
{
"product_name": "Smartphone 128GB",
"product_code": "7509876543210",
"skus": [
"SKU-PHONE-128"
],
"quantity": 2,
"units": [
{
"unit_code": "356789012345678",
"status": "ACTIVE"
},
{
"unit_code": "356789012345679",
"status": "RESERVED"
},
{
"unit_code": "356789012345680",
"status": "DAMAGED",
"damaged_source": "RETURN"
}
]
},
{
"product_name": "Vitamin C 500mg",
"product_code": "7501111222333",
"skus": [
"SKU-VITC-500"
],
"quantity": 8,
"lots": [
{
"lot_code": "LOT-2026A",
"expiration_date": "2026-12-31",
"quantity": 3
},
{
"lot_code": "LOT-2027B",
"expiration_date": "2027-06-30",
"quantity": 5
}
]
}
]
}Authorizations
Headers
Name of the event (orderUpdated, orderFulfilled, shippingUpdated, inventoryMovement,
replenishmentStatus, replenishmentCreated, replenishmentScheduled). Route on this header,
not on the URL: all feeds can share one endpoint. Treat a request without this header as an order
event.
orderUpdated, orderFulfilled, shippingUpdated, inventoryMovement, replenishmentStatus, replenishmentCreated, replenishmentScheduled Body
Payload of the inventoryMovement event.
Response
Acknowledge receipt with any 2xx status. The response body is ignored. A 429 or any 5xx response is retried; any other 4xx response is treated as a permanent rejection and is not retried. While a delivery is pending, later inventory events for the same integration wait behind it.