Webhooks
This section contains all the information necessary to understand and manage the messages received through our webhook system.
Whenever something relevant happens in Onebox (a new purchase, a refund, a catalog change, an access validation…), the platform sends an HTTP POST request to the URL you configured for that webhook. The request body is always JSON, and the most important information for your integration travels in a set of dedicated headers.
Message structure
Headers
Every webhook request includes the following headers:
| Header | Description |
|---|---|
ob-event | Type of event that occurred. See Event types. |
ob-action | Business situation behind the event (e.g. PURCHASE, REFUND, UPDATE). See Actions. |
ob-delivery-id | Unique identifier of this delivery attempt. Useful for tracing or de-duplicating on your side. |
ob-hook-id | Identifier of the webhook configuration that triggered this delivery. Use it to look up the API key used for signing. |
ob-signature | Signature of the message body. See Signature generation and validation. |
ob-subtype | (Optional) Extra granularity for some events — for example, distinguishing which specific change happened on an event, session, promotion, product, channel or item. Only present when the event type makes use of it. |
Body
The body is a JSON object whose fields depend on the event type. Order-related events share a common base:
| Field | Description |
|---|---|
code | Identifier of the order that triggered the notification. |
url | Link to the API endpoint that returns the order details. See Get order details by order code. |
previous_code | (Only on order replacements/relocations) Identifier of the previous order being replaced by this one. When this field is present, a second notification is also sent with action UPDATE against the previous order. |
Other events (catalog, promotions, channels, products, B2B balance…) use different fields — typically numeric identifiers (id, eventId, sessionId, channelId…) instead of code/url. The exact shape of the payload depends on the event type; always rely on ob-event and ob-action to decide how to interpret the body.
Example
curl --location --request POST {{configured_url}} \
--header 'ob-event: ORDER' \
--header 'ob-action: PURCHASE' \
--header 'ob-delivery-id: 5b9f3c1a-7e2d-4a16-9c40-1b3a4d57e802' \
--header 'ob-hook-id: c244aa20-afa7-4734-8b95-67d37b66ac04' \
--header 'ob-signature: 9f86d081884c7d659a2feaa0c55ad015a3bf4f1b2b0b822cd15d6c15b0f00a08' \
--header 'Content-Type: application/json' \
--data-raw '{
"code": "9N1FTEJKTQH2",
"url": "https://api.example.com/orders/9N1FTEJKTQH2"
}'
Event types
The value of the ob-event header tells you what happened. These are all the possible values:
| Event | Meaning |
|---|---|
ORDER | A full sales order changed state (purchase, booking, refund, cancellation, update, print). |
ITEM | An individual ticket inside an existing order changed (typically a transfer between holders or an access validation). |
MEMBERORDER | A movement happened on a membership/season-ticket order. |
PREORDER | A purchase was started but the buyer abandoned it before completing the payment. |
EVENT_UPDATE | The configuration of a catalog event changed (general data, communication, prices, surcharges, etc.). |
SESSION_UPDATE | The configuration of a specific session of an event changed. |
PROMOTION | A promotion or discount changed (created, edited, activated or removed). |
CHANNEL | The configuration of a sales channel changed. |
PRODUCT | The configuration of a product (pack/combo) changed. |
B2BBALANCE | A movement happened on the B2B balance of an entity (top-up, adjustment). |
Actions
The value of the ob-action header narrows down what kind of change happened. The same event type can carry different actions over its life cycle:
| Action | Meaning |
|---|---|
PURCHASE | Purchase confirmed. |
BOOKING | Reservation confirmed. |
REFUND | Total or partial refund of a previous purchase. |
CANCEL | Cancellation. |
UPDATE | Update on an existing entity. |
CATALOG | Change in a catalog entity (event, session, product). |
ABANDONED | A purchase was started and abandoned before payment. |
PRINT | The print status of an order changed. |
RELOCATE | A new order replaced a previous one because of a seat relocation. The previous order is referenced through previous_code. |
TRANSFER | A ticket was transferred to another holder or recovered from a previous transfer. The exact case is reported in ob-subtype. |
BARCODE_VALIDATION | A barcode was validated at access control. |
Event × Action matrix
Not every action can travel with every event. This is the list of combinations you can actually receive:
| Event | Possible actions |
|---|---|
ORDER | PURCHASE, BOOKING, REFUND, CANCEL, RELOCATE, PRINT, UPDATE (only as the companion notification described in Delivery and retries) |
ITEM | TRANSFER, BARCODE_VALIDATION |
MEMBERORDER | PURCHASE, UPDATE |
PREORDER | ABANDONED |
EVENT_UPDATE | CATALOG |
SESSION_UPDATE | CATALOG |
PRODUCT | CATALOG |
PROMOTION | UPDATE |
CHANNEL | UPDATE |
B2BBALANCE | UPDATE |
Signature generation and validation
Every webhook request carries an ob-signature header. Use it to verify that the message comes from Onebox and that the payload was not tampered with in transit.
Generation
The signature is computed as follows:
- Take the JSON body of the request exactly as it travels on the wire (raw bytes — do not re-serialize, reorder keys or normalize whitespace).
- Concatenate the raw payload with the API key configured for this webhook:
payload + apiKey. - Compute
SHA-256over the concatenated string. - The result is encoded as a lowercase hexadecimal string of 64 characters and sent in the
ob-signatureheader.
signature = SHA256(payload + apiKey) // hex, lowercase, 64 chars
Validation
To verify a request:
- Retrieve the API key associated with the webhook configuration. You can identify the configuration using the
ob-hook-idheader. - Read the raw payload from the HTTP request body (the bytes received, without parsing and re-serializing).
- Concatenate
payload + apiKeyand compute itsSHA-256digest as a lowercase hexadecimal string. - Compare the result with the value of the
ob-signatureheader. If they match, the message is valid.
Notes:
- The payload used to validate the signature must be the raw body received. Re-serializing the JSON (for example with a different key order or different whitespace) will produce a different hash and the signature will not match.
- The signature applies to the body only. Headers are not part of the signed content.
Delivery and retries
- Webhooks are delivered over HTTPS with
Content-Type: application/json. - If the destination URL fails to respond with a successful status code, the platform retries the delivery up to 3 times with exponential backoff between 1 and 10 seconds before giving up. All retries reuse the same
ob-delivery-id— use it on your side to avoid processing the same message twice. - On order modifications (
previous_codeset), two separate notifications are sent to the same URL: one for the new order and a second one with actionUPDATEagainst the previous order. They share the sameob-delivery-idbut have their own signatures.