Skip to main content

Register Webhook

Register a URL that Stream calls when a shipment's status or waybill changes, instead of polling Get Orders.

Endpoint

POST /webhooks

Request Body

FieldTypeRequiredDescription
webhook.target_urlstringYesHTTPS (or HTTP) URL Stream will POST events to
webhook.eventsarrayYesOne or more event names from the table below

Events

EventFires when
shipment.updated.statusA shipment's status becomes order_received, in_transit or delivered. Other status changes do not fire an event
shipment.updated.waybillA waybill number is assigned to a shipment, or changed

Request Example

curl -X POST \
https://stream-orders-api-sandbox.herokuapp.com/client_api/v2/webhooks \
-H "Authorization: Bearer YOUR_TOKEN_HERE" \
-H "Content-Type: application/json" \
-d '{
"webhook": {
"target_url": "https://your-system.example.com/stream/webhooks",
"events": ["shipment.updated.status", "shipment.updated.waybill"]
}
}'

Success Response (201 Created)

{
"webhook": {
"id": 42,
"target_url": "https://your-system.example.com/stream/webhooks",
"events": ["shipment.updated.status", "shipment.updated.waybill"],
"token": "k3Jd9vQ2mB7xLp0sTn4wZa",
"status": "active"
}
}

Keep the token. Stream includes it in every delivery so you can confirm the request came from us.

Error Responses

422 Unprocessable Entity

{
"success": false,
"error": "[\"Target url is invalid\"]",
"errors": []
}
{
"success": false,
"error": "[\"Events not permitted: order.updated.status\"]",
"errors": []
}

401 Unauthorized

Access token is missing or invalid.

What Stream sends you

Each event is a POST to your target_url with a JSON body and a Content-Type: application/json header:

{
"object_type": "order",
"object_id": 98765,
"event_type": "shipment.updated.status",
"original_value": "awaiting_pickup",
"updated_value": "in_transit",
"updated_at_utc": "2026-09-09T10:15:00.000Z",
"token": "k3Jd9vQ2mB7xLp0sTn4wZa"
}
FieldDescription
object_typeAlways order
object_idThe order's id, as returned by Get Orders
event_typeThe event name you subscribed to
original_valueThe value before the change
updated_valueThe value after the change
updated_at_utcWhen the change happened
tokenThe token from your registration

Respond with any 2xx status. Stream does not read the response body.

Retries and failure

A non-2xx response or a timeout is retried four times, roughly 20, 40, 60 and 80 seconds later. After the last retry the webhook's status becomes failing and Stream stops sending to it. Contact your account manager to have it re-enabled once your endpoint is healthy.

Hub orders

A hub order has two shipment legs, and each leg fires its own events. Both carry the same object_id, so call Get Orders and read shipments[] to see which leg moved.

Managing a webhook

See Manage Webhooks to read, update or delete a registration.