Skip to main content

Webhooks API

The Webhooks API delivers real-time notifications about order events. Events are delivered at-least-once and may arrive out of order. Use updatedAt timestamps to reconcile and ensure idempotent processing.

Base URL​

https://public-api.onetablet.co/api/v1/webhooks

Authentication​

All requests to the Webhooks API require authentication through API Gateway. Pass your API key in the x-api-key header.

Endpoints​

Get All Webhooks​

Retrieve all webhook configurations for your organization.

GET /api/v1/webhooks

Example Request​

curl -X GET "https://public-api.onetablet.co/api/v1/webhooks" \
-H "x-api-key: your-api-key"

Example Response​

[
{
"id": "webhook-001",
"url": "https://your-app.com/webhooks/orders",
"organizationId": "org-123",
"createdAt": "2024-01-15T10:30:00Z",
"updatedAt": "2024-01-15T10:30:00Z"
}
]

Webhook Configuration​

To enable webhooks for your organization, please contact the OneTablet technical support team. They will assist you with the setup process.

Webhook Events​

When webhooks are configured, your endpoint will receive POST requests with the following event types:

Events​

  • order.created — emitted when a new order is created
  • order.status.updated — emitted when the order status changes (e.g., future → new, new → ready, ready → finished)
  • order.delivery.updated — emitted when the delivery status changes (delivery orders only). Delivery statuses: ASSIGNED, EN_ROUTE_TO_STORE_LOCATION, EN_ROUTE_TO_CUSTOMER, COMPLETED, CANCELED.
  • order.canceled — emitted when the order is canceled

All events include an Order payload.

The order.created event is sent immediately for all orders, including those with a future status. This allows you to be aware of scheduled orders as soon as they are placed.

Example: order.created​

Order Created Webhook Event
{
"event": "order.created",
"timestamp": "2022-06-13T16:20:41.759Z",
"data": {
"id": "3475e4e5-ff33-4acd-bdc6-2937670d10f8",
"status": "ready",
"deliveryStatus": "EN_ROUTE_TO_CUSTOMER",
"createdAt": "2022-06-13T16:20:46.100Z",
"updatedAt": "2022-06-13T16:25:00.000Z",
"store": {
"id": "a1b2c3d4-e5f6-7890-1234-567890abcdef",
"externalId": "gh-les1-tributo",
"location": "Tributo LES",
"brand": "Tributo",
"platform": "grubhub"
},
"details": {
"externalId": "tE3_Qes0Eeyf_V8y5nw54Q",
"externalReadableOrderNum": "56141916-4846305",
"placedAt": "2022-06-13T16:20:46.062Z",
"estimatedPickupAt": "2022-06-13T17:01:00.000Z",
"isPickup": false,
"consumer": {
"id": null,
"name": "Jacob Yee",
"email": "",
"phone": "9548958785"
},
"consumers": [],
"isGroupOrder": false,
"note": "Include napkins and utensils",
"deliveryNote": "Will need to come to the lobby to collect from person Company Name: DailyPay",
"isMerchantDelivery": false,
"deliveryAddress": {
"googlePlaceId": "ChIJVTPokywQkFQRmtVEaUZlJRA",
"lat": 40.7034,
"lng": -74.0098,
"label": "55 Water St, New York, NY 10041",
"raw": "{\"address_line1\":\"55 Water St\",\"city\":\"New York\"}"
},
"total": 2197,
"subtotal": 1975,
"tax": 122,
"tip": 100,
"deliveryFee": 0,
"utensils": true,
"promotions": [
{
"name": "Free delivery",
"discountValue": 349
}
],
"items": [
{
"id": "e1809cd4-7948-4a16-861c-501e094ef02b",
"sku": "SKU-TACO-001",
"name": "Salt & Pepper Shrimp Taco",
"quantity": 1,
"price": {
"base": 1375,
"menu": 1375,
"unit": 1375,
"total": 1375
},
"modifiers": [
{
"id": "66561a41-5f7c-47fc-b44c-31ada1453276",
"sku": "SKU-PROTEIN-BEEF",
"name": "Beef",
"quantity": 1,
"price": {
"base": 0,
"menu": 0,
"unit": 0,
"total": 0
},
"modifierGroup": {
"id": "grp-protein",
"name": "Protein Choice"
}
},
{
"id": "3f20c307-e97e-4111-a476-53039f64a083",
"name": "Salsa Verde",
"quantity": 1,
"price": {
"base": 0,
"menu": 0,
"unit": 0,
"total": 0
}
},
{
"id": "opt-combo-001",
"name": "Combo Extras",
"quantity": 1,
"price": {
"base": 200,
"menu": 200,
"unit": 200,
"total": 200
},
"modifiers": [
{
"id": "sauce-side",
"name": "Sauce on the Side",
"quantity": 1,
"price": {
"base": 0,
"menu": 0,
"unit": 0,
"total": 0
}
}
]
}
]
},
{
"id": "04645392-0bb1-482a-afaf-479df05787b1",
"sku": "SKU-RICE-002",
"name": "Fried Rice",
"quantity": 1,
"price": {
"base": 600,
"menu": 600,
"unit": 600,
"total": 600
},
"note": "No onions",
"modifiers": [
{
"id": "22bbcd65-14d2-4809-a5c1-563c58a0bea8",
"name": "Add Egg",
"quantity": 1,
"price": {
"base": 0,
"menu": 0,
"unit": 0,
"total": 0
}
}
]
}
]
}
}
}

Example: order.status.updated​

Order Status Updated
{
"event": "order.status.updated",
"timestamp": "2022-06-13T16:25:00.000Z",
"data": {
"id": "3475e4e5-ff33-4acd-bdc6-2937670d10f8",
"status": "ready",
"deliveryStatus": "EN_ROUTE_TO_CUSTOMER",
"createdAt": "2022-06-13T16:20:46.100Z",
"updatedAt": "2022-06-13T16:25:00.000Z",
"store": {
"id": "a1b2c3d4-e5f6-7890-1234-567890abcdef",
"externalId": "gh-les1-tributo",
"location": "Tributo LES",
"brand": "Tributo",
"platform": "grubhub"
},
"details": {
"externalId": "tE3_Qes0Eeyf_V8y5nw54Q",
"externalReadableOrderNum": "56141916-4846305",
"placedAt": "2022-06-13T16:20:46.062Z",
"estimatedPickupAt": "2022-06-13T17:01:00.000Z",
"isPickup": false,
"consumer": {
"id": null,
"name": "Jacob Yee",
"email": "",
"phone": "9548958785"
},
"consumers": [],
"isGroupOrder": false,
"note": "Include napkins and utensils",
"deliveryNote": "Will need to come to the lobby to collect from person Company Name: DailyPay",
"isMerchantDelivery": false,
"deliveryAddress": {
"googlePlaceId": "ChIJVTPokywQkFQRmtVEaUZlJRA",
"lat": 40.7034,
"lng": -74.0098,
"label": "55 Water St, New York, NY 10041",
"raw": "{\"address_line1\":\"55 Water St\",\"city\":\"New York\"}"
},
"total": 2197,
"subtotal": 1975,
"tax": 122,
"tip": 100,
"deliveryFee": 0,
"utensils": true,
"promotions": [
{
"name": "Free delivery",
"discountValue": 349
}
],
"items": [
{
"id": "e1809cd4-7948-4a16-861c-501e094ef02b",
"sku": "SKU-TACO-001",
"name": "Salt & Pepper Shrimp Taco",
"quantity": 1,
"price": {
"base": 1375,
"menu": 1375,
"unit": 1375,
"total": 1375
},
"modifiers": [
{
"id": "66561a41-5f7c-47fc-b44c-31ada1453276",
"sku": "SKU-PROTEIN-BEEF",
"name": "Beef",
"quantity": 1,
"price": {
"base": 0,
"menu": 0,
"unit": 0,
"total": 0
},
"modifierGroup": {
"id": "grp-protein",
"name": "Protein Choice"
}
},
{
"id": "3f20c307-e97e-4111-a476-53039f64a083",
"name": "Salsa Verde",
"quantity": 1,
"price": {
"base": 0,
"menu": 0,
"unit": 0,
"total": 0
}
},
{
"id": "opt-combo-001",
"name": "Combo Extras",
"quantity": 1,
"price": {
"base": 200,
"menu": 200,
"unit": 200,
"total": 200
},
"modifiers": [
{
"id": "sauce-side",
"name": "Sauce on the Side",
"quantity": 1,
"price": {
"base": 0,
"menu": 0,
"unit": 0,
"total": 0
}
}
]
}
]
},
{
"id": "04645392-0bb1-482a-afaf-479df05787b1",
"sku": "SKU-RICE-002",
"name": "Fried Rice",
"quantity": 1,
"price": {
"base": 600,
"menu": 600,
"unit": 600,
"total": 600
},
"note": "No onions",
"modifiers": [
{
"id": "22bbcd65-14d2-4809-a5c1-563c58a0bea8",
"name": "Add Egg",
"quantity": 1,
"price": {
"base": 0,
"menu": 0,
"unit": 0,
"total": 0
}
}
]
}
]
}
}
}

Example: order.delivery.updated​

Order Delivery Updated
{
"event": "order.delivery.updated",
"timestamp": "2022-06-13T16:35:00.000Z",
"data": {
"id": "3475e4e5-ff33-4acd-bdc6-2937670d10f8",
"status": "ready",
"deliveryStatus": "EN_ROUTE_TO_CUSTOMER",
"createdAt": "2022-06-13T16:20:46.100Z",
"updatedAt": "2022-06-13T16:35:00.000Z",
"store": {
"id": "a1b2c3d4-e5f6-7890-1234-567890abcdef",
"externalId": "gh-les1-tributo",
"location": "Tributo LES",
"brand": "Tributo",
"platform": "grubhub"
},
"details": {
"externalId": "tE3_Qes0Eeyf_V8y5nw54Q",
"externalReadableOrderNum": "56141916-4846305",
"placedAt": "2022-06-13T16:20:46.062Z",
"estimatedPickupAt": "2022-06-13T17:01:00.000Z",
"isPickup": false,
"consumer": {
"id": null,
"name": "Jacob Yee",
"email": "",
"phone": "9548958785"
},
"consumers": [],
"isGroupOrder": false,
"note": "Include napkins and utensils",
"deliveryNote": "Will need to come to the lobby to collect from person Company Name: DailyPay",
"isMerchantDelivery": false,
"deliveryAddress": {
"googlePlaceId": "ChIJVTPokywQkFQRmtVEaUZlJRA",
"lat": 40.7034,
"lng": -74.0098,
"label": "55 Water St, New York, NY 10041",
"raw": "{\"address_line1\":\"55 Water St\",\"city\":\"New York\"}"
},
"total": 2197,
"subtotal": 1975,
"tax": 122,
"tip": 100,
"deliveryFee": 0,
"utensils": true,
"promotions": [
{
"name": "Free delivery",
"discountValue": 349
}
],
"items": [
{
"id": "e1809cd4-7948-4a16-861c-501e094ef02b",
"sku": "SKU-TACO-001",
"name": "Salt & Pepper Shrimp Taco",
"quantity": 1,
"price": {
"base": 1375,
"menu": 1375,
"unit": 1375,
"total": 1375
},
"modifiers": [
{
"id": "66561a41-5f7c-47fc-b44c-31ada1453276",
"sku": "SKU-PROTEIN-BEEF",
"name": "Beef",
"quantity": 1,
"price": {
"base": 0,
"menu": 0,
"unit": 0,
"total": 0
},
"modifierGroup": {
"id": "grp-protein",
"name": "Protein Choice"
}
},
{
"id": "3f20c307-e97e-4111-a476-53039f64a083",
"name": "Salsa Verde",
"quantity": 1,
"price": {
"base": 0,
"menu": 0,
"unit": 0,
"total": 0
}
},
{
"id": "opt-combo-001",
"name": "Combo Extras",
"quantity": 1,
"price": {
"base": 200,
"menu": 200,
"unit": 200,
"total": 200
},
"modifiers": [
{
"id": "sauce-side",
"name": "Sauce on the Side",
"quantity": 1,
"price": {
"base": 0,
"menu": 0,
"unit": 0,
"total": 0
}
}
]
}
]
},
{
"id": "04645392-0bb1-482a-afaf-479df05787b1",
"sku": "SKU-RICE-002",
"name": "Fried Rice",
"quantity": 1,
"price": {
"base": 600,
"menu": 600,
"unit": 600,
"total": 600
},
"note": "No onions",
"modifiers": [
{
"id": "22bbcd65-14d2-4809-a5c1-563c58a0bea8",
"name": "Add Egg",
"quantity": 1,
"price": {
"base": 0,
"menu": 0,
"unit": 0,
"total": 0
}
}
]
}
]
}
}
}

Example: order.canceled​

Order Canceled
{
"event": "order.canceled",
"timestamp": "2022-06-13T16:40:00.000Z",
"data": {
"id": "3475e4e5-ff33-4acd-bdc6-2937670d10f8",
"status": "cancelled",
"deliveryStatus": "EN_ROUTE_TO_CUSTOMER",
"createdAt": "2022-06-13T16:20:46.100Z",
"updatedAt": "2022-06-13T16:40:00.000Z",
"store": {
"id": "a1b2c3d4-e5f6-7890-1234-567890abcdef",
"externalId": "gh-les1-tributo",
"location": "Tributo LES",
"brand": "Tributo",
"platform": "grubhub"
},
"details": {
"externalId": "tE3_Qes0Eeyf_V8y5nw54Q",
"externalReadableOrderNum": "56141916-4846305",
"placedAt": "2022-06-13T16:20:46.062Z",
"estimatedPickupAt": "2022-06-13T17:01:00.000Z",
"isPickup": false,
"consumer": {
"id": null,
"name": "Jacob Yee",
"email": "",
"phone": "9548958785"
},
"consumers": [],
"isGroupOrder": false,
"note": "Include napkins and utensils",
"deliveryNote": "Will need to come to the lobby to collect from person Company Name: DailyPay",
"isMerchantDelivery": false,
"deliveryAddress": {
"googlePlaceId": "ChIJVTPokywQkFQRmtVEaUZlJRA",
"lat": 40.7034,
"lng": -74.0098,
"label": "55 Water St, New York, NY 10041",
"raw": "{\"address_line1\":\"55 Water St\",\"city\":\"New York\"}"
},
"total": 2197,
"subtotal": 1975,
"tax": 122,
"tip": 100,
"deliveryFee": 0,
"utensils": true,
"promotions": [
{
"name": "Free delivery",
"discountValue": 349
}
],
"items": [
{
"id": "e1809cd4-7948-4a16-861c-501e094ef02b",
"sku": "SKU-TACO-001",
"name": "Salt & Pepper Shrimp Taco",
"quantity": 1,
"price": {
"base": 1375,
"menu": 1375,
"unit": 1375,
"total": 1375
},
"modifiers": [
{
"id": "66561a41-5f7c-47fc-b44c-31ada1453276",
"sku": "SKU-PROTEIN-BEEF",
"name": "Beef",
"quantity": 1,
"price": {
"base": 0,
"menu": 0,
"unit": 0,
"total": 0
},
"modifierGroup": {
"id": "grp-protein",
"name": "Protein Choice"
}
},
{
"id": "3f20c307-e97e-4111-a476-53039f64a083",
"name": "Salsa Verde",
"quantity": 1,
"price": {
"base": 0,
"menu": 0,
"unit": 0,
"total": 0
}
},
{
"id": "opt-combo-001",
"name": "Combo Extras",
"quantity": 1,
"price": {
"base": 200,
"menu": 200,
"unit": 200,
"total": 200
},
"modifiers": [
{
"id": "sauce-side",
"name": "Sauce on the Side",
"quantity": 1,
"price": {
"base": 0,
"menu": 0,
"unit": 0,
"total": 0
}
}
]
}
]
},
{
"id": "04645392-0bb1-482a-afaf-479df05787b1",
"sku": "SKU-RICE-002",
"name": "Fried Rice",
"quantity": 1,
"price": {
"base": 600,
"menu": 600,
"unit": 600,
"total": 600
},
"note": "No onions",
"modifiers": [
{
"id": "22bbcd65-14d2-4809-a5c1-563c58a0bea8",
"name": "Add Egg",
"quantity": 1,
"price": {
"base": 0,
"menu": 0,
"unit": 0,
"total": 0
}
}
]
}
]
},
"cancellation": {
"by": "platform",
"reason": "customer canceled",
"at": "2022-06-13T16:40:00.000Z"
}
}
}

Webhook Response Requirements​

Your webhook endpoint should:

  • Return HTTP status code 200 for successful processing
  • Respond within 30 seconds
  • Handle duplicate/out-of-order events (implement idempotency and reconcile by latest updatedAt)
  • Process events asynchronously when possible

Event Sequences​

Typical flows:

  • Pickup order:

    1. order.created (status: new or future)
    2. order.status.updated (to new if it was future)
    3. order.status.updated (to ready)
    4. order.status.updated (to finished)
  • Delivery order (third‑party courier): Typical sequence (order may vary):

    1. order.created (status: new or future)
    2. order.delivery.updated (deliveryStatus: ASSIGNED)
    3. order.delivery.updated (deliveryStatus: EN_ROUTE_TO_STORE_LOCATION)
    4. order.status.updated (status: ready) — may occur before or after courier arrival
    5. order.delivery.updated (deliveryStatus: EN_ROUTE_TO_CUSTOMER)
    6. order.delivery.updated (deliveryStatus: COMPLETED)
    7. order.status.updated (status: finished)
  • Cancellation:

    1. order.created
    2. order.canceled (cancellation includes by, reason, at)

Error Handling​

Retry Policy​

If your endpoint returns a non-200 status code or times out, we retry deliveries up to 3 times after the initial attempt using exponential backoff.

Testing Webhooks​

Local Development​

For local development, you can use tools like ngrok to expose your local server:

# Install ngrok
npm install -g ngrok

# Expose your local server
ngrok http 3000

# Use the generated URL in your webhook configuration
https://abc123.ngrok.io/webhooks/orders

Webhook Testing Tool​

Use our webhook testing tool in the dashboard to send test events to your endpoint and verify it's working correctly.