Delivery status webhook
Receive a call on your server each time a delivery you dispatched changes status: driver assigned, at pickup, picked up, at drop-off, delivered, cancelled.
1. Register your endpoint
Register once, with the same API key you use for quotes and cancels. One endpoint per integration: every delivery you dispatch is reported there. It works the same way as the push_order webhook: we send back the header you give us, so you can check the call comes from OrderOut.
curl -X POST https://api.orderout.co/api/webhooks/delivery_status \
-H "api-key: $ORDEROUT_API_KEY" -H "Content-Type: application/json" \
-d '{
"endpoint": "https://example.com/orderout/delivery-status",
"method": "POST",
"authorization_header": {"Authorization": "Bearer your-secret"}
}'endpointmust be a publichttps(orhttp) URL.methodis required:POST,PUT,GETorDELETE(case doesn't matter). We recommendPOST.authorization_headeris required: a JSON object of header names to values, sent back on every call. Use{}if you don't need one.GET /api/webhooks/delivery_statusreturns your registration, andDELETE /api/webhooks/delivery_statusremoves it. To change the URL, delete it and register again. A secondPOSTanswers409.
2. What you receive
{
"event": "delivery.en_route_dropoff",
"event_id": "5843160318214144:3",
"emitted_at": "2026-10-15T18:42:10.512Z",
"source": {
"order_id": "4743465852338176",
"delivery_id": "5843160318214144",
"tracker_id": "5b1f3c20-0e4a-11f1-8c2d-3f9a7e6b1d42"
},
"destination": {
"restaurantId": "5343190423044096",
"restaurantName": "Acme's Restaurant"
},
"payload": {
"status": "en_route_dropoff",
"driver": {
"name": "Sam R.",
"phone": "+15555550188",
"latitude": 40.7398,
"longitude": -73.9903,
"transport_type": "Bicycle"
},
"tracking_url": "https://trackdelivery.io/?orderId=5b1f3c20-0e4a-11f1-8c2d-3f9a7e6b1d42",
"eta_pickup": "2026-10-15T18:31:00.000Z",
"eta_dropoff": "2026-10-15T18:44:00.000Z"
}
}source.order_idis theorder_idreturned byPOST /api/channel/order/push.delivery_idis the id you can also pass to Cancel Order.- Driver fields are
nulluntil a driver is assigned. - Every update has its own
event_id:<delivery_id>:<n>, wherengoes up by one for each update of that delivery. Usen(oremitted_at) to put updates in order. The same status can arrive more than once: the courier network may send it again, and after areassignthe new driver's statuses start over fromen_route_pickup. Outside areassign, treat a status you already have as a repeat. - Each update is sent once. If your endpoint is down or answers an error, that update is not sent again, so answer quickly (any
2xx) and do your processing afterwards.
3. Statuses
| Status | Meaning |
|---|---|
scheduled | The delivery is booked and waiting for a driver. |
en_route_pickup | A driver is assigned and on the way to the restaurant. |
arrived_pickup | The driver is at the restaurant. |
en_route_dropoff | The driver picked up the order and is on the way to the customer. |
arrived_dropoff | The driver is at the customer's address. |
completed | Delivered. |
reassign | The delivery moved to another courier. The previous one may then report cancelled, followed by a new en_route_pickup. |
cancelled | The delivery was cancelled, by you, the restaurant or the courier network. After a reassign, a cancelled is not final. |
unknown | A status we don't recognise yet. |
The first update you receive is usually scheduled. Answer 2xx to any event you don't handle, including ones not listed here. payload.status always carries the delivery's current status.
Deliveries onapi.orderout.coare realA delivery not cancelled before a driver is assigned costs a $10 cancellation fee, for you and for OrderOut.
Updated 12 days ago
Did this page help you?
