Webhooks
Webhooks are used to automatically receive notifications of events that happen. For example, when an order has a schedule change.
Once you receive an event on your server, you can process and act on it as you need.
You can manage your webhooks on the Duffel Dashboard.
Events
We'll progressively add more events. The currently supported events are:
order.created
: This event is sent whenever an order is created. An example response for this event type:
{"id": "wev_0000A4tQSmKyqOrcySrGbo","api_version": "v2","type": "order.created","data": {"object": { .. },},"live_mode": true,"idempotency_key": "ord_0000ABd6wggSct7BoraU1o","created_at": "2020-04-11T15:48:11.642000Z","identity_organisation_id": "org_0000APMFjhs4X2rJ6k7UIE"}
order.creation_failed
: This event is sent when creating an order has failed after the order creation request has been accepted but not yet confirmed (202 status code). An example response for this event type:
{"id": "wev_0000A4tQSmKyqOrcySrGbo","api_version": "v2","type": "order.creation_failed","data": {"object": { .. },},"live_mode": true,"idempotency_key": "ZmFpbGVkLXBvcl8wMDAwQW5KMjhnQ0lxU3k5RURDeFRV","created_at": "2020-04-11T15:48:11.642000Z","identity_organisation_id": "org_0000APMFjhs4X2rJ6k7UIE"}
payment.created
: This event is sent whenever a payment is created for a hold order. An example response for this event type:
{"id": "wev_0000A4tQSmKyqOrcySrGbo","api_version": "v2","type": "payment.created","data": {"object": { .. },},"live_mode": true,"idempotency_key": "pay_0000ABd6wggSct7BoraU1o","created_at": "2020-04-11T15:48:11.642000Z","identity_organisation_id": "org_0000APMFjhs4X2rJ6k7UIE"}
order.airline_initiated_change_detected
: This event is sent whenever we detect airline-initiated schedule changes to your order. An example response for this event type:
{"id": "wev_0000A4tQSmKyqOrcySrGbo","api_version": "v2","type": "order.airline_initiated_change_detected","data": {"object": { .. },},"live_mode": true,"idempotency_key": "aic_0011AJSACO83RgsiSySpzH","created_at": "2020-03-11T12:18:12.642000Z","identity_organisation_id": "org_0000APMFjhs4X2rJ6k7UIE"}
stays.booking.created
: This event is sent whenever a Stays booking is created. An example response for this event type:
{"id": "wev_0000A4tQSmKyqOrcySrGbo","api_version": "v2","type": "stays.booking.created","data": {"object": { .. },},"live_mode": true,"idempotency_key": "bok_0000AcTKWKVb0RWQOUazJo","created_at": "2024-04-18T16:32:11.642000Z","identity_organisation_id": "org_0000APMFjhs4X2rJ6k7UIE"}
stays.booking.cancelled
: This event is sent whenever a Stays booking is cancelled. An example response for this event type:
{"id": "wev_0000A4tQSmKyqOrcySrGbo","api_version": "v2","type": "stays.booking.cancelled","data": {"object": { .. },},"live_mode": true,"idempotency_key": "cancelled-bok_0000AcTKWKVb0RWQOUazJo","created_at": "2024-04-18T16:32:11.642000Z","identity_organisation_id": "org_0000APMFjhs4X2rJ6k7UIE"}
stays.booking_creation_failed
: This event is sent whenever it is unable to create a booking after a Stays booking creation attempt that resulted in a response status code 202.
{"id": "wev_0000A4tQSmKyqOrcySrGbo","api_version": "v2","type": "stays.booking_creation_failed","data": {"object": { .. },},"live_mode": true,"idempotency_key": "ZmFpbGVkLWJhdF9vYWthb2FrYWthb2ZBa2RsZGtkMjM=","created_at": "2024-10-14T11:49:32.246000Z","identity_organisation_id": "org_0000APMFjhs4X2rJ6k7UIE"}
The api_version
represents the version of our API that produced the data
property.
System guarantees
Duffel's webhooks system guarantees the following properties:
It makes at least one delivery attempt per event.
Events are not delivered in any particular order.
Events are sent at least once.
Failed deliveries are retried for 72 hours on an exponetial backoff policy.
It also has the following security properties:
It always makes HTTPS requests.
It signs the events.
Schema
POST https://api.duffel.com/air/webhooks/{id}/actions/ping
curl -X POST --compressed "https://api.duffel.com/air/webhooks/{id}/actions/ping" \-H "Accept-Encoding: gzip" \-H "Accept: application/json" \-H "Duffel-Version: v2" \-H "Authorization: Bearer <YOUR_ACCESS_TOKEN>"
No response body
DELETE https://api.duffel.com/air/webhooks/{id}
curl -X DELETE --compressed "https://api.duffel.com/air/webhooks/{id}" \-H "Accept-Encoding: gzip" \-H "Accept: application/json" \-H "Duffel-Version: v2" \-H "Authorization: Bearer <YOUR_ACCESS_TOKEN>"
No response body
Update a webhook
Update a webhook
URL parameters
PATCH https://api.duffel.com/air/webhooks/{id}
curl -X PATCH --compressed "https://api.duffel.com/air/webhooks/{id}" \-H "Accept-Encoding: gzip" \-H "Accept: application/json" \-H "Duffel-Version: v2" \-H "Authorization: Bearer <YOUR_ACCESS_TOKEN>" \-d '{"data": {"url": "https://example.com/duffel/webhook","events": ["order.created","order.airline_initiated_change_detected"],"active": true}}'
{"data": {"url": "https://www.example.com:4000/webhooks","updated_at": "2020-04-11T15:48:11.642Z","live_mode": true,"id": "end_0000A3tQSmKyqOrcySrGbo","events": ["order.created","order.airline_initiated_change_detected"],"created_at": "2020-04-11T15:48:11.642Z","active": true}}
List webhooks
Retrieve a paginated list of webhooks
Query parameters
The maximum number of records to return per page. Defaults to 50
.
May be set to any integer between 1
and 200
. For more information on how to paginate through records, see the Pagination section.
1
50
A cursor pointing to the next page of records. For more information on how to paginate through records, see the Pagination section.
"g2wAAAACbQAAABBBZXJvbWlzdC1LaGFya2l2bQAAAB="
A cursor pointing to the previous page of records. For more information on how to paginate through records, see the Pagination section.
"g2wAAAACbQAAABBBZXJvbWlzdC1LaGFya2l2bQAAAB="
GET https://api.duffel.com/air/webhooks
curl -X GET --compressed "https://api.duffel.com/air/webhooks?limit=1&before=g2wAAAACbQAAABBBZXJvbWlzdC1LaGFya2l2bQAAAB=&after=g2wAAAACbQAAABBBZXJvbWlzdC1LaGFya2l2bQAAAB=" \-H "Accept: application/json" \-H "Accept-Encoding: gzip" \-H "Duffel-Version: v2" \-H "Authorization: Bearer <YOUR_ACCESS_TOKEN>"
{"meta": {"limit": 50,"after": "g2wAAAACbQAAABBBZXJvbWlzdC1LaGFya2l2bQAAAB="},"data": [{"url": "https://www.example.com:4000/webhooks","updated_at": "2020-04-11T15:48:11.642Z","live_mode": true,"id": "end_0000A3tQSmKyqOrcySrGbo","events": ["order.created","order.airline_initiated_change_detected"],"created_at": "2020-04-11T15:48:11.642Z","active": true}]}
Create a webhook
To start receiving notifications of events, you'll need to create a webhook that details the server that will receive the notifications. The webhook will be created in live mode or test mode based on the access token you're using. If you're using a test mode access token, the webhook will be created in test mode and will receive events related to test mode resources. If you're using a live mode access token, it'll receive events related to live mode.
Duffel only allows one webhook to be defined per live mode value, basically your organisation can only have
one url with live_mode: true
and another with live_mode: false
.
To ensure the highest level of security we run some checks on the URL we receive, the URL must be for an https server, we do not accept IP addresses and some URLs are blacklisted (e.g. https://localhost).
By default, the webhook will be active.
POST https://api.duffel.com/air/webhooks
curl -X POST --compressed "https://api.duffel.com/air/webhooks" \-H "Accept-Encoding: gzip" \-H "Accept: application/json" \-H "Content-Type: application/json" \-H "Duffel-Version: v2" \-H "Authorization: Bearer <YOUR_ACCESS_TOKEN>" \-d '{"data": {"url": "https://www.example.com/webhooks","events": ["order.created","order.airline_initiated_change_detected"]}}'
{"data": {"secret": "QKfUULLQh+8SegYmIsF6kA==","url": "https://www.example.com:4000/webhooks","updated_at": "2020-04-11T15:48:11.642Z","live_mode": true,"id": "end_0000A3tQSmKyqOrcySrGbo","events": ["order.created","order.airline_initiated_change_detected"],"created_at": "2020-04-11T15:48:11.642Z","active": true}}