Docs βΊ Webhooks
Webhooks overview
Register endpoints and receive signed delivery events.
Webhooks push every change on your orders to your HTTPS endpoint within seconds: driver assigned, pickup, dropoff, proof-of-delivery photos, failures, cancellations. They're signed, retried and logged.
Register an endpoint
bash
curl -s https://api.trydragonfly.com/v1/webhooks \
-H "Authorization: Bearer $DRAGONFLY_API_KEY" -H 'content-type: application/json' \
-d '{ "url": "https://your-app.example.com/dragonfly", "events": ["delivery.*"], "description": "production" }'json
{ "success": true, "data": { "id": "cmβ¦", "url": "https://your-app.example.com/dragonfly", "events": ["delivery.*"], "secret": "whsec_β¦", "isActive": true } }Important:
secret is shown once. Store it to verify signatures.events: []subscribes to everything. Wildcards likedelivery.*and*work. See the event catalog.- Endpoints belong to the API key that created them. Each key receives events for the orders it created.
- Register several endpoints (for example, one per environment or consumer).
Manage endpoints
| Method | Path | Does |
|---|---|---|
GET | /v1/webhooks | List your endpoints (secrets redacted). |
POST | /v1/webhooks | Create an endpoint. |
PATCH | /v1/webhooks/{id} | Change url, events, description, or re-enable with isActive: true. |
DELETE | /v1/webhooks/{id} | Remove an endpoint. |
GET | /v1/webhooks/{id}/deliveries | Recent delivery attempts: status, response code, error. |
POST | /v1/webhooks/{id}/test | Replay your latest order's current state as delivery.updated. |
GET | /v1/webhooks/events | The event catalog. |
The message
http
POST /dragonfly HTTP/1.1
content-type: application/json
dragonfly-id: msg_2Lk9β¦
dragonfly-timestamp: 1791400501
dragonfly-signature: v1,K5oZfzN95Z9UVu1EsfQmfVNQhnkZ2pj9o9NDN/H/pI4=
dragonfly-event: delivery.dropoff_completejson
{
"type": "delivery",
"event": "delivery.dropoff_complete",
"id": "msg_2Lk9β¦",
"occurredAt": "2026-10-09T16:38:12.000Z",
"data": {
"delivery": {
"id": "cmβ¦",
"externalId": "cater-88412",
"status": "dropoff_complete",
"orderStatus": "DELIVERED",
"pickup": { "address": { "formatted": "100 W Randolph St, Chicago, IL 60601" } },
"dropoffs": [{ "address": { "formatted": "233 S Wacker Dr, Chicago, IL 60606" }, "completion": { "photoUrl": "https://β¦" } }],
"courier": { "name": "Driver name", "phone": "+1β¦" },
"proofOfDelivery": [{ "type": "photo_proof_of_delivery", "url": "https://β¦", "capturedAt": "2026-10-09T16:38:10.000Z" }],
"publicTrackingUrl": "https://β¦",
"onTime": true
},
"nashStatus": "dropoff_complete",
"onfleetTrigger": "taskCompleted"
}
}data.delivery is a superset of Nash's Delivery object and Onfleet's Task, so a receiver written for either maps cleanly. Timestamps are ISO 8601 UTC.
Respond fast
Return any 2xx within a few seconds, then process asynchronously. Anything else is retried. Deduplicate on dragonfly-id: a message can arrive more than once.
Something unclear or missing? Tell us.