Webhooks
Webhooks notify your system of events in Carriyo. When a shipment status changes, an order is updated, inventory levels shift, or a return request moves through its lifecycle, Carriyo POSTs a JSON payload to a URL you configure. Your system then reacts: update an OMS, fire a notification, trigger a refund, sync stock to your storefront.
Webhooks are the integration pattern Carriyo recommends for status tracking. Polling individual endpoints is fine for occasional lookups. Webhooks scale more cleanly to high event volumes and remove the need to manage polling cadence on your side.
What Carriyo's webhooks do
- Per-tenant configurations. A tenant can register multiple webhook endpoints. A per-tenant limit may apply; check with your Carriyo contact if you're configuring many endpoints.
- Event-driven delivery. When an event happens, Carriyo
POSTs the payload to the configured URL. If your endpoint
responds with
2xx, the delivery is complete. If not, Carriyo retries. - Authentication options. Each webhook supports static
custom headers (for example, a fixed
Authorizationheader) or OAuth2 client-credentials. For OAuth2, Carriyo fetches a token from your token endpoint and attaches it to each call. - Retry with exponential delay. Failed deliveries are retried on a defined schedule. Persistent failures end up visible in the Integration Monitor for manual replay. See Retry and idempotency.
- Replay from the Dashboard. Once an underlying issue is fixed, failed events can be retriggered manually.
The model
Two concepts:
- A webhook configuration: your registered endpoint. It carries a name, URL, triggers, optional conditions, optional authentication, and an active flag. Configured in the Dashboard under Settings → Webhooks.
- An event: the record of something that happened in Carriyo. Each event has an entity type (shipment, order, return request, or inventory), an entity id, and the data describing the change. Events are emitted whether or not anyone is subscribed.
When an event fires, Carriyo evaluates the tenant's webhook configurations. Every configuration whose triggers and conditions match gets called.
Shipment webhooks
Shipment events make up the bulk of webhook traffic. Every status transition, label generation, and scheduling change on a shipment can fire a webhook. The payload is the full Shipment object as JSON — no wrapper, no diff.
Shipment webhooks support 27 triggers across three
categories: status changes (19 statuses from draft through
return_in_transit), metadata triggers like
default_label_update for label-printing automation, and
reason-code triggers for specific carrier events. Conditions
let you filter by shipment type, delivery type, geography,
pickup location, and creation source.
See Shipment webhook events for the full trigger catalogue, payload example, and conditions reference.
Order webhooks
Order webhooks cover the order and fulfillment-order
lifecycle — from creation through allocation, fulfillment,
shipping, and closure. The payload is an envelope containing
the order state before and after the change (oldImage and
newImage, camelCase).
Order webhooks support 18 triggers covering order-level
events (ORDER_CREATE, ORDER_CANCEL, ORDER_CLOSED, etc.)
and fulfillment-order events (fulfill, allocate, split, merge,
ship line items, and more). The only available condition is
creation source type.
See Order webhook events for the full trigger catalogue, payload example, and conditions reference.
Return request webhooks
Return-request webhooks track the return lifecycle — approvals, rejections, item receipt, and completion. The payload is the full ReturnRequest object as JSON.
Return-request webhooks support 8 status triggers (from
pending through received) and 2 item-level triggers. The
trigger header carries return_status_update or
return_received_update. No entity-specific conditions are
available.
See Return webhook events for the full trigger catalogue and payload example.
Inventory webhooks
Inventory webhooks fire on every stock-level change for any
product in the tenant. The payload is an envelope containing
the inventory state before and after the change (old_image
and new_image, snake_case).
A single trigger, ALL_INVENTORY_UPDATES, covers all stock
mutations. There is no way to subscribe to a subset of
changes — filter by product or location in your handler.
Inventory webhooks are tenant-scoped (not merchant-scoped)
and are configured via the API.
See Inventory webhook events for the trigger, payload example, and configuration details.
Retry and idempotency
When your endpoint returns non-2xx or times out, Carriyo retries the delivery on a defined schedule. The same event is retried, not a new one, so your handler will see the same payload more than once in normal operation. Make it idempotent.
Full retry cadence (standard and extended), idempotency strategies, and replay options are covered in Retry and idempotency.
Sequence is not guaranteed
Events for the same entity can arrive out of sequence,
especially during retry cycles or when a carrier batch-updates
multiple statuses at once. A delivered event might arrive
before out_for_delivery if the carrier reported both in one
update.
Don't rely on arrival order. Use timestamps on the payload to
work out the actual sequence. Don't apply an earlier state
over a later one: in_transit shouldn't overwrite delivered.
How it fits with other modules
- Orders. Order lifecycle events flow through the order webhook family.
- Shipping. Most webhook traffic is shipment-related. The status flow drives most events.
- Returns. Return-request lifecycle events.
- Inventory. Stock-level changes fire inventory webhooks.
- Post-purchase CX. Tracking pages and notifications consume the same events your systems do, in parallel.
- Event model. The broader event taxonomy and status-flow semantics behind the webhook payloads.