Skip to main content

Webhooks

Webhooks allow you to receive real-time notifications when events occur in OlaClick. Instead of polling, OlaClick sends a POST to your endpoint every time something relevant happens.

How it works

1. You register a URL via the API (with your merchant_id)
2. An event occurs in OlaClick (e.g. an order is created)
3. OlaClick sends a POST to your URL with the event payload
4. Your server responds with 2xx to confirm receipt

Integration flow

1. Register a webhook

What is merchant_id? It's an identifier you define — not generated by OlaClick. Use any string that makes sense in your system (e.g., your internal restaurant ID, a store code, or an account reference). OlaClick stores it and includes it in every webhook delivery so your server knows which merchant the event belongs to. This is especially useful if you manage multiple OlaClick accounts from a single webhook endpoint.

Examples: "restaurant_042", "store-lima-01", "acc_7f3b2a"

curl -X POST https://public-api.olaclick.app/v1/webhooks \
-H "Authorization: Bearer olk_live_..." \
-H "Content-Type: application/json" \
-d '{
"webhook_url": "https://your-server.com/webhooks/olaclick",
"merchant_id": "restaurant_042",
"ack_http_codes": [200, 201, 202],
"event_types": ["ORDER_CREATED", "ORDER_UPDATED"]
}'

Response:

{
"data": {
"company_id": "your-company-uuid",
"webhook_id": "webhook-uuid",
"webhook_url": "https://your-server.com/webhooks/olaclick",
"webhook_headers": {},
"is_active": true,
"max_retry": 3,
"ack_http_codes": [200, 201, 202],
"merchant_id": "restaurant_042",
"created_at": "2026-06-20T12:00:00.000Z",
"updated_at": "2026-06-20T12:00:00.000Z"
}
}

2. Receive events

When an event occurs, OlaClick sends a POST to your webhook_url with the following headers:

POST https://your-server.com/webhooks/olaclick
Content-Type: application/json
source: OlaClick

If you configured custom webhook_headers, they are included in every delivery.

Payload structure:

{
"event_type": "ORDER_CREATED",
"event_id": "unique-event-uuid",
"merchant_id": "restaurant_042",
"timestamp": "2026-06-20T15:30:00.000Z",
"data": {
"order_id": "order-uuid",
"public_id": "PE-1234567890",
"status": "PENDING",
"service_type": "DELIVERY",
"source": "INBOUND",
"payment_status": "UNPAID",
"delivered_by": "MERCHANT",
"total": 15000,
"currency": "COP",
"daily_id": 42,
"pending_at": "2026-06-20T15:30:00.000Z",
"created_at": "2026-06-20T15:30:00.000Z",
"updated_at": "2026-06-20T15:30:00.000Z"
}
}
FieldTypeDescription
event_typestringThe event that occurred (ORDER_CREATED, ORDER_UPDATED, ORDER_DELETED)
event_idstringUnique identifier for this delivery (use for idempotency)
merchant_idstringYour merchant ID as you defined it when registering the webhook
timestampstringISO 8601 timestamp of when the event occurred
dataobjectThe event payload (see below)

data fields:

FieldTypeDescription
order_idstringOrder UUID
public_idstringPublic order ID (e.g. PE-1234567890)
statusstringOrder status: PENDING, PREPARING, READY, DELIVERED, FINALIZED, CANCELLED
service_typestring | nullDELIVERY, ONSITE, TABLE, TAKEAWAY
sourcestring | nullINBOUND, OUTBOUND, CHATBOT, IFOOD, RAPPI, DIDI, etc.
payment_statusstring | nullPAID, UNPAID, PARTIAL, OVERPAID
delivered_bystring | nullMERCHANT, IFOOD, DIDI, RAPPI, PICKER, etc.
totalnumberOrder total (in local currency)
currencystring | nullISO 4217 currency code (e.g. COP, BRL, PEN)
daily_idnumber | nullSequential daily order number
pending_atstring | nullWhen the order entered PENDING status (ISO 8601)
created_atstringOrder creation timestamp (ISO 8601)
updated_atstringLast update timestamp (ISO 8601)

3. Acknowledge receipt

Your server must respond with an HTTP status code within ack_http_codes (default: 200, 201, 202). If it doesn't respond or returns a different code, OlaClick retries.

// Express.js example
app.post('/webhooks/olaclick', (req, res) => {
const { event_type, event_id, data } = req.body;

// 1. Check the source header
if (req.headers['source'] !== 'OlaClick') {
return res.status(401).send('Unknown source');
}

// 2. Deduplicate by event_id
if (alreadyProcessed(event_id)) {
return res.status(200).send('Already processed');
}

// 3. Process the event
switch (event_type) {
case 'ORDER_CREATED':
handleNewOrder(data);
break;
case 'ORDER_UPDATED':
handleOrderUpdate(data);
break;
case 'ORDER_DELETED':
handleOrderDeleted(data);
break;
}

// 4. Acknowledge receipt
res.status(200).send('OK');
});

Available events

EventDescriptionTriggered when
ORDER_CREATEDNew order createdA customer completes an order
ORDER_UPDATEDOrder updatedStatus change (confirmed, preparing, delivered, cancelled), payment update, rider assigned, etc.
ORDER_DELETEDOrder deletedAn order is permanently removed from the system

Delivery headers

Every webhook delivery includes these headers:

HeaderValueDescription
Content-Typeapplication/jsonAlways JSON
sourceOlaClickIdentifies the sender
(your custom headers)(your values)Any headers configured via webhook_headers

Retries

If your endpoint doesn't respond with a success code (one of your ack_http_codes), OlaClick retries up to max_retry times (default: 3, max: 10) with exponential backoff:

AttemptDelay
130 seconds
260 seconds
3120 seconds

If all retries are exhausted, the delivery is marked as failed.

Custom headers

You can add custom headers that OlaClick will include in every delivery. Useful for passing an auth token to your server:

curl -X POST https://public-api.olaclick.app/v1/webhooks \
-H "Authorization: Bearer olk_live_..." \
-H "Content-Type: application/json" \
-d '{
"webhook_url": "https://your-server.com/webhooks/olaclick",
"merchant_id": "restaurant_042",
"webhook_headers": {
"Authorization": "Bearer my-secret-token"
}
}'

This way you can authenticate incoming webhook deliveries on your end using your own token.

Manage webhooks

OperationMethodEndpointRequired scope
CreatePOST/v1/webhookswebhooks:write
ListGET/v1/webhookswebhooks:read
GetGET/v1/webhooks/{id}webhooks:read
UpdatePATCH/v1/webhooks/{id}webhooks:write
DeleteDELETE/v1/webhooks/{id}webhooks:write

Request body reference

Create (POST /v1/webhooks)

FieldTypeRequiredDefaultDescription
webhook_urlstringHTTPS endpoint URL for deliveries
merchant_idstringYour own identifier for this merchant (free-form, 1–64 chars). Included in every delivery payload for routing.
webhook_headersobject{}Custom headers included in every delivery
max_retryinteger3Max retries on failure (1–10)
ack_http_codesinteger[][200, 201, 202]HTTP codes considered successful
event_typesstring[]all eventsEvent types to subscribe to. Values: ORDER_CREATED, ORDER_UPDATED, ORDER_DELETED

Update (PATCH /v1/webhooks/{id})

All fields optional (at least one required):

FieldTypeDescription
webhook_urlstringNew HTTPS endpoint URL
webhook_headersobjectNew custom headers (replaces existing)
is_activebooleanEnable/disable the webhook
max_retryintegerNew retry count (1–10)
ack_http_codesinteger[]New success HTTP codes
event_typesstring[]Event types to subscribe to. Replaces existing list. Values: ORDER_CREATED, ORDER_UPDATED, ORDER_DELETED

Best practices

  1. Use event_types to filter events — subscribe only to the events you need to reduce noise
  2. Respond 200 immediately and process the event in background
  3. Store the raw event before processing — useful for debugging
  4. Deduplicate by event_id — the same event may arrive more than once due to retries
  5. Verify the source header — check that it equals OlaClick
  6. Use custom webhook_headers to authenticate deliveries on your server
  7. Monitor your endpoint — if it starts failing consistently, deliveries stop after max retries