Webhook

Introduction

You will need to have a webhook server to be able to receive webhook notifications. These notifications will inform you of the status changes for each order, additional information about courier statuses and provide ratings of consumers on a purchase made. 

Notification TypeNotification TriggerCorresponding Order Status
"CREATED" Sent for all new orders which the merchant is receiving on the Wolt marketplace. CREATED, ACKNOWLEDGED
"PRODUCTION"Sent once the order has been accepted or confirmed* by the venue staff, either automatically or manually. *pre-orders should be confirmed upon creation, Wolt will move them automatically in "PRODUCTION" status when it's time to start the food preparation or order collection. PRODUCTION
"READY" Sent once the merchant has completed the preparation or collection of the order. READY
"CANCELED" Sent once the order has been “rejected”, either by the merchant, the customer or Wolt Support. REJECTED
"COURIER ARRIVAL" *optional Sent X* min before the courier's arrival at the merchant's location. *X is configurable per location. not linked
"PICK-UP-COMPLETED" *optional Sent once the courier has completed the pick-up at the merchant's location. not linked
"DELIVERED"Sent once the order is delivered to the customer. DELIVERED
"REVIEW" *optional Sent once a consumer has provided a review or rating of their order.  not linked

Example Webhook JSON

{
  "id": "90f5c25cbbfb3d131a46e643",
  "type": "order.notification",
  "order": {
    "id": "90f5be47fc97e11107f8a480",
    "venue_id": "9a5c7e3102fe6a000c4b562b",
    "status": "PRODUCTION",
    "resource_url": "https://pos-integration-service.wolt.com/orders/90f5be47fc97e11107f8a480"
  },
  "created_at": "2021-07-19T18:20:12.378509Z"
}

Making use of the notification

Your system can fetch the order payload by using the resource_url field. You can also hardcode the base URL and use the order.id field's value to pull order details. Moreover, some notifications can be used to decide the order parsing moment for the POS or using it to submit reminder on pending order to venue staff.

Two Types of order payload

As Wolt runs two versions of the order payload, please make sure you develop towards /v2/orders/{orderId}. This is the most recent and most comprehensive payload.

Venue Events Notifications

Receive real-time notifications when operational events occur at your venues. Ask your Wolt contact to enable these for you.

Notification TypeNotification Trigger
REJECTION_ALERT_TRIGGEREDVenue reached 3 consecutive rejected orders
REJECTION_ALERT_RECOVEREDVenue processed a successful order after a rejection alert
VENUE_OFFLINE_ALERT_TRIGGEREDVenue went offline during business hours
VENUE_OFFLINE_ALERT_RECOVEREDVenue is back online after an offline alert
OPENING_HOURS_UPDATEDRegular or exceptional opening hours were changed

Example Webhook JSON

This is the basic payload format shared by all venue notifications. Events with richer context have additional fields in details as shown in the sections below.

Generic Webhook Example
{
"event_type": "VENUE_OFFLINE_ALERT_TRIGGERED",
"venue_id": "507f191e810c19729de860ea",
"external_venue_id": "STORE-001",
"detected_at": "2026-02-13T14:30:00Z",
"details": {}
}

REJECTION_ALERT_TRIGGERED / REJECTION_ALERT_RECOVERED

Sent when a venue reaches the consecutive rejection threshold (triggered) or processes a successful order after an alert (recovered). The details object is empty for both events

FieldTypeDescription
event_typestringThe type of event (e.g. REJECTION_ALERT_TRIGGERED)
venue_idstringWolt's internal venue identifier
external_venue_idstring | nullYour external venue identifier, if configured
detected_atstringISO 8601 timestamp when the event was detected
detailsobjectEvent-specific payload. Empty {} for rejection alerts; populated for other event types
Webhook Example, Rejection Alert Triggered
{
"event_type": "REJECTION_ALERT_RECOVERED",
"venue_id": "507f191e810c19729de860ea",
"external_venue_id": "STORE-001",
"detected_at": "2026-02-13T15:10:00Z",
"details": {}
}

VENUE_OFFLINE_ALERT_TRIGGERED

FieldTypeDescription
details.offline_sincestringTimestamp when the venue went offline
details.expected_open_untilstring | nullScheduled close time of the current opening slot. null if no slot found
details.offline_period_endingstring | nullThe "until" time of a timed offline period. null for indefinite offline
details.change_contextobject | nullWho made the change — changeSource, changeReason, changedBy. May be null
Webhook Example, Venue Offline Alert
{
"event_type": "VENUE_OFFLINE_ALERT_TRIGGERED",
"venue_id": "507f191e810c19729de860ea",
"external_venue_id": "STORE-001",
"detected_at": "2026-02-13T14:30:00Z",
"details": {
"offline_since": "2026-02-13T14:25:00Z",
"expected_open_until": "2026-02-13T22:00:00Z",
"offline_period_ending": "2026-02-13T16:00:00Z",
"change_context": {
"change_source": "merchant-app",
"change_reason": "closing early",
"changed_by": "user@example.com"
}
}
}

VENUE_OFFLINE_ALERT_RECOVERED

Only sent if a VENUE_OFFLINE_ALERT_TRIGGERED was previously delivered for that venue.

FieldTypeDescription
details.back_online_sincestringTimestamp when the venue came back online
details.change_contextobject | nullWho made the change. May be null
Webhook Example, Venue Offline Alert Recovered
{
"event_type": "VENUE_OFFLINE_ALERT_RECOVERED",
"venue_id": "507f191e810c19729de860ea",
"external_venue_id": "STORE-001",
"detected_at": "2026-02-13T14:35:00Z",
"details": {
"back_online_since": "2026-02-13T14:34:00Z",
"change_context": {
"change_source": "merchant-app",
"change_reason": "reopening after break",
"changed_by": "user@example.com"
}
}
}

OPENING_HOURS_UPDATED

FieldTypeDescription
details.changed_fieldsstring[]Which fields changed: REGULAR_HOURS, EXCEPTIONAL_HOURS, or both
details.previousobjectOpening hours snapshot before the change
details.currentobjectOpening hours snapshot after the change
details.change_contextobject | nullWho made the change. changeReason is not available for this event type
Webhook Example, Opening Hours Change
{
"event_type": "OPENING_HOURS_UPDATED",
"venue_id": "507f191e810c19729de860ea",
"external_venue_id": "STORE-001",
"detected_at": "2026-02-13T09:00:00Z",
"details": {
"changed_fields": ["REGULAR_HOURS", "EXCEPTIONAL_HOURS"],
"previous": {
"regular_hours": {
"monday": [{ "open": "10:00", "close": "22:00" }]
},
"exceptional_hours": null,
"offline_period": null
},
"current": {
"regular_hours": {
"monday": [{ "open": "09:00", "close": "23:00" }]
},
"exceptional_hours": [
{
"date": "2026-02-20",
"hours": [{ "open": "10:00", "close": "18:00" }]
}
],
"offline_period": null
},
"change_context": {
"change_source": "merchant-admin",
"changed_by": "admin@merchant.com"
}
}
}

Webhook server security

Please provide a client secret that is cryptographically random and at least 128 bits in length. This will be used to sign the webhook body using HMAC-SHA256.

Wolt signs the request by generating a signature from the request body, using the client secret, and sending it alongside the request.

Wolt signature specification

  • Notifications are signed with HMAC-SHA256.

  • String format for the signature is HEX.

  • The signature is placed to the WOLT-SIGNATURE HTTP request header.

  • The secret key for generating the signature from the request body is the client secret

Wolt signature example

  • Client secret: example-hmac-sha256-wolt

To generate the signature of the body, use HMAC-SHA256 with the client secret provided to Wolt. Generate it from the request body (i.e. the notification), and compare it to the value in the wolt-signature header.

Expected response

We require a 200 response to acknowledge our notification was received correctly. Otherwise, the notification will fall back into the retry logic. 

Retry logic

We will submit the first retry after 5 seconds, followed by two additional retries at 5-second intervals.