{
"id": "evt_47351d65d53840ce8f4ff7d6d83f1be9",
"type": "delivery.delivered",
"api_version": "2026-08-20",
"environment": "test",
"created_at": "2026-08-20T14:30:00Z",
"sequence": 5,
"data": {
"delivery": {
"id": "dlv_3f1a821cdb58498cbb52f4706545a089",
"external_id": "shop-order-1842",
"reference": "H-RS83223",
"environment": "test",
"simulated": true,
"status": "delivered",
"currency": "GHS",
"delivery_fee": 20,
"requires_custom_quote": false,
"tracking_url": null,
"created_at": "2026-08-20T14:20:00Z",
"updated_at": "2026-08-20T14:30:00Z"
}
}
}Webhooks
Receive a delivery lifecycle event
HaulStow sends this request to each active subscribed webhook endpoint.
Delivery is at least once: deduplicate with the stable event id.
Verify Haulstow-Signature over
<unix_timestamp>.<exact_raw_request_body> using HMAC-SHA256 and reject
timestamps more than five minutes old. During secret rotation the header
can contain two v1 signatures; accept either valid value.
WEBHOOK
lifecycleEvent
{
"id": "evt_47351d65d53840ce8f4ff7d6d83f1be9",
"type": "delivery.delivered",
"api_version": "2026-08-20",
"environment": "test",
"created_at": "2026-08-20T14:30:00Z",
"sequence": 5,
"data": {
"delivery": {
"id": "dlv_3f1a821cdb58498cbb52f4706545a089",
"external_id": "shop-order-1842",
"reference": "H-RS83223",
"environment": "test",
"simulated": true,
"status": "delivered",
"currency": "GHS",
"delivery_fee": 20,
"requires_custom_quote": false,
"tracking_url": null,
"created_at": "2026-08-20T14:20:00Z",
"updated_at": "2026-08-20T14:30:00Z"
}
}
}Headers
t=<unix_timestamp>,v1=<hex-digest>[,v1=<previous-hex-digest>]
Pattern:
^evt_[a-f0-9]{32}$Example:
"evt_47351d65d53840ce8f4ff7d6d83f1be9"
Identifies this callback delivery attempt stream. Manual replay gets a new value.
Pattern:
^whd_[a-f0-9]{32}$Allowed value:
"Haulstow-Webhooks/1.0"Body
application/json
Pattern:
^evt_[a-f0-9]{32}$Example:
"evt_47351d65d53840ce8f4ff7d6d83f1be9"
Available options:
delivery.created, delivery.assigned, delivery.picked_up, delivery.in_transit, delivery.delivered, delivery.failed, delivery.cancelled, delivery.outsourced, delivery.payment_collected, delivery.settled, settlement.paid, settlement.failed, webhook.test Allowed value:
"2026-08-20"Available options:
test, live Example:
"live"
Required range:
x >= 1Show child attributes
Show child attributes
Response
Callback accepted. Any 2xx response marks delivery successful.
