Wolt Drive API webhook service

Webhooks provide a mechanism for the merchant to receive information related to e.g. status changes of a single delivery. The Wolt Drive API contains CRUD endpoints for managing the webhooks.

The webhooks operate in the merchant level: the webhook events related to all the venues of the merchant will be sent to the same endpoint. I.e. the merchant needs to configure only a single webhook in order to receive all the events related to all the stores.

The merchant system will need to provide a callback_urland client_secret for each webhook it registers.

Each event is encoded into a JSON Web Token (JWT) and will be sent in the format: "token": "<payload as HS256 encoded JWT>". After receiving and decoding the payload, the system can validate the event origin by verifying the secret (signature) which it provided while registering the webhook. Signature is not base64 encoded.

The following sequence diagram visualizes the webhook related operations.

Drive API webhook service sequence diagram

Endpoints for managing webhooks

All requests to Drive API endpoints must be authorized with a Bearer Token.

All the requests must contain Authorization: Bearer <token> header. This token is often referred as Merchant Key. Staging token will be provided by Wolt when you start the integration development and the production token when you successfully complete the testing phase. Only one token per merchant is needed.

Create a webhook

Create a webhook to be used to send events

POST /v1/merchants/{merchant_id}/webhooks

POST /v1/merchants/{merchant_id}/webhooks
{
"callback_config": {
"exponential_retry_backoff": {
"exponent_base": 2,
"max_retry_count": 10
}
},
"callback_url": "string",
"client_secret": "string",
"disabled": false
}
NameInTypeRequiredDescription
merchant_idpathstringtrue
bodybodyWebhookCreatePayloadV1true

Create webhook response

Response example
201 Created
{
"callback_config": {
"exponential_retry_backoff": {
"exponent_base": 0,
"max_retry_count": 0
}
},
"callback_url": "string",
"created_at": "string",
"disabled": true,
"id": "string",
"modified_at": "string",
"subscribed_events": [
"string"
]
}
StatusMeaningDescription
201CreatedSuccessful Response
400Bad RequestBad Request
401UnauthorizedUnauthorized
422Unprocessable EntityValidation Error

Get a list of webhooks

Get a list of all webhook configured under the merchant ID.

GET /v1/merchants/{merchant_id}/webhooks

GET /v1/merchants/{merchant_id}/webhooks
curl {{host}}/v1/merchants/{merchant_id}/webhooks \
-H "Authorization: Bearer (token)" \
-H "Content-Type: application/json"
NameInTypeRequired
merchant_idpathstringtrue

List all webhooks response

Response example
200 Ok
[
{
"callback_config": {
"exponential_retry_backoff": {
"exponent_base": 0,
"max_retry_count": 0
}
},
"callback_url": "string",
"created_at": "string",
"disabled": true,
"id": "string",
"modified_at": "string",
"subscribed_events": [
"string"
]
}
]
ParameterTypeRequiredDescription
callback_configWebhookCallbackConfigV1Required
callback_urlstringRequiredEnd-point url where webhook events are sent.
created_atstringRequired
disabledbooleanRequiredDetermines whether the webhook is in use and events should be sent.
idstringRequired
modified_atstringRequired
subscribed_events[string]RequiredThe list of events a webhook sends updates about. See available events
StatusMeaningDescription
200OkSuccessful Response
400Bad RequestBad Request
401UnauthorizedUnauthorized
422Unprocessable EntityValidation Error

Get a single webhook

GET /v1/merchants/{merchant_id}/webhooks/{webhook_id}

GET /v1/merchants/{merchant_id}/webhooks/{webhook_id}
curl {{host}}/v1/merchants/{merchant_id}/webhooks/{webhook_id} \
-H "Authorization: Bearer (token)" \
-H "Content-Type: application/json"

Get webhook request parameters

NameLocationTypeRequired
merchant_idIn: pathstringRequired
webhook_idIn: pathstringRequired

Get a webhooks response

Response example
200 Ok
{
"callback_config": {
"exponential_retry_backoff": {
"exponent_base": 0,
"max_retry_count": 0
}
},
"callback_url": "string",
"created_at": "string",
"disabled": true,
"id": "string",
"modified_at": "string",
"subscribed_events": [
"string"
]
}
ParameterTypeRequiredDescription
callback_configWebhookCallbackConfigV1Required
callback_urlstringRequiredEnd-point url where webhook events are sent.
created_atstringRequired
disabledbooleanRequiredDetermines whether the webhook is in use and events should be sent.
idstringRequired
modified_atstringRequired
subscribed_events[string]RequiredThe list of events a webhook sends updates about. See available events
StatusMeaningDescription
200OkSuccessful Response
400Bad RequestBad Request
401UnauthorizedUnauthorized
422Unprocessable EntityValidation Error

Get webhook response

Response example
200 Ok
{
"callback_config": {
"exponential_retry_backoff": {
"exponent_base": 0,
"max_retry_count": 0
}
},
"callback_url": "string",
"created_at": "string",
"disabled": true,
"id": "string",
"modified_at": "string",
"subscribed_events": [
"string"
]
}

Update a webhook

Change the webhook configuration and the subscribed events.

PATCH /v1/merchants/{merchant_id}/webhooks/{webhook_id}

PATCH /v1/merchants/{merchant_id}/webhooks/{webhook_id}
{
"callback_config": {
"exponential_retry_backoff": {
"exponent_base": 0,
"max_retry_count": 0
}
},
"callback_url": "string",
"client_secret": "string",
"disabled": false,
"subscribed_events": ["order.received"]
}
NameInTypeRequiredDescription
webhook_idpathstringtrue
merchant_idpathstringtrue
bodybodyWebhookUpdatePayloadtrue
Response example
200 Ok
{
"callback_config": {
"exponential_retry_backoff": {
"exponent_base": 0,
"max_retry_count": 0
}
},
"callback_url": "string",
"created_at": "string",
"disabled": true,
"id": "string",
"modified_at": "string",
"subscribed_events": [
"string"
]
}

Delete a webhook

DELETE /v1/merchants/{merchant_id}/webhooks/{webhook_id}

DELETE /v1/merchants/{merchant_id}/webhooks/{webhook_id}
curl -X DELETE {{host}}/v1/merchants/{merchant_id}/webhooks/{webhook_id} \
-H "Authorization: Bearer (token)" \
-H "Content-Type: application/json"
Response example
204 No content

Webhook order events

Note that we release new features constantly and may add optional fields in our API without creating a new API version. In practice, this could mean that some new fields are also introduced in the webhook payloads. The client side should allow unknown events and keys in the payloads.

Events that are triggered by the same action, like order.dropoff_completed and order.delivered, may be sent at seemingly random order.

Webhook order event types

Event typeAuto-subscribedDescription
order.receivedYesOrder has been received successfully.
order.rejectedYesOrder has been rejected.
order.pickup_eta_updatedYesOrder pickup ETA is updated. New time is included in event details.
order.pickup_startedYesCourier has started a pickup task.
order.picked_upYesOrder has been picked up from venue.
order.pickup_arrivalYesCourier is arriving to pickup location. Triggered when courier enters 150 meter geo-fence radius.
order.dropoff_startedYesCourier has started a dropoff task.
order.dropoff_arrivalYesCourier is arriving to dropoff location. Triggered when courier enters 150 meter geo-fence radius.
order.dropoff_completedYesCourier has completed the dropoff task.
order.deliveredYesComplete order has been delivered.
order.customer_no_showNoCustomer not reached and delivery could not be made.
order.location_updatedNoCourier location info. When enabled, expect heavy event load and consider using a separate configuration for this event.
order.dropoff_eta_updatedYesOrder dropoff ETA is updated.
order.handshake_deliveryYesSent when delivery handshake verification is enabled.

Order event payload

Example payload format does not apply to order.location_updated and order.handshake_delivery events. Notice that some fields may be null in some events. Event details refer to order details.

The real payload format of all webhook events is {"token": "<payload as HS256 encoded JWT>"}. The schemas documented here for the body refer to the decoded payload.

{
"dispatched_at": "2023-01-01T00:00:00.000Z",
"type": "order.received",
"details": {
"id": "string",
"venue_id": "string",
"wolt_order_reference_id": "string",
"tracking_reference": "string",
"merchant_order_reference_id": "string",
"order_number": "string",
"price": {
"amount": 0,
"currency": "string"
},
"pickup": {
"eta": "2023-01-01T00:00:00.000Z"
},
"dropoff": null,
"courier": null,
"parcels": []
}
}
ParameterTypeRequiredDescription
dispatched_atstringRequiredTimestamp is in ISO8601 format e.g. 2020-01-30T10:00:13.123Z
typeOrderEventTypeRequiredAn enumeration.
idstringRequiredEvent ID.
venue_idstringRequiredWolt venue ID.
wolt_order_reference_idstringRequiredWolt order reference ID.
tracking_referencestringRequiredWolt tracking reference.
merchant_order_reference_idstringThe merchant_order_reference_ID received in delivery creation.
order_numberstringThe order_number received in delivery creation.
pricePriceRequiredPrice for delivery.
pickup.etastringRequiredPickup ETA. Timestamp is in ISO8601 format e.g. 2020-01-30T10:00:13.123Z
dropoffWebhookDropoffEtaRequiredIncluded only in order.dropoff_eta_updated and order.delivered events. Otherwise null.
courierCourierRequiredInfo on assigned courier. Included only in order.pickup_started event. Otherwise null.
parcelsWebhookParcelArrayRequiredArray of related parcel items. Included only in order.picked_up and order.dropoff_completed events. Otherwise null.

Location updated

This event type order.location_updated is optional. When enabled, expect a heavy event load and consider creating a separate configuration for the event. Location refers to the current location of assigned courier partner.

{
"dispatched_at": "2023-01-01T00:00:00.000Z",
"type": "order.location_updated",
"details": {
"id": "string",
"wolt_order_reference_id": "string",
"merchant_order_reference_id": "string",
"order_number": "string",
"tracking_id": "string",
"courier_location": {
"lat": 0.0,
"lon": 0.0
}
}
}
ParameterTypeRequiredDescription
dispatched_atstringRequiredTimestamp is in ISO8601 format e.g. 2020-01-30T10:00:13.123Z
typeOrderEventTypeRequiredAn enumeration.
idstringRequiredEvent ID.
wolt_order_reference_idstringRequiredWolt order reference ID.
merchant_order_reference_idstringThe merchant_order_reference_ID received in delivery creation.
order_numberstringThe order_number received in delivery creation.
tracking_idstringRequiredCourier tracking ID.
courier_location.latnumberRequiredLatitude value in EPSG:3857 Coordinate Reference System
courier_location.lonnumberRequiredLatitude value in EPSG:3857 Coordinate Reference System

Handshake delivery

This event type order.handshake_delivery is only sent when the order has delivery handshake verification enabled.

{
"dispatched_at": "2023-01-01T00:00:00.000Z",
"type": "order.handshake_delivery",
"details": {
"id": "string",
"wolt_order_reference_id": "string",
"merchant_order_reference_id": null,
"order_number": "string",
"pin_code": "string"
}
}
ParameterTypeRequiredDescription
dispatched_atstringRequiredTimestamp is in ISO8601 format e.g. 2020-01-30T10:00:13.123Z
typeOrderEventTypeRequiredAn enumeration.
idstringRequiredEvent ID.
wolt_order_reference_idstringRequiredWolt order reference ID.
merchant_order_reference_idstringThe merchant_order_reference_ID received in delivery creation.
order_numberstringThe order_number received in delivery creation.
pin_codestringRequiredThe PIN code assigned for the delivery.