Skip to main content

Webhooks

This document describes the webhook endpoints your platform must implement. OneTablet calls these endpoints to notify you of order confirmations, menu updates, availability changes, and more.

Overview

Your platform acts as a webhook receiver. You expose HTTP endpoints that OneTablet calls when events occur.

Endpoint Configuration

During integration setup, you provide OneTablet with your webhook base URL and authentication requirements.


Webhook Endpoints Summary

EndpointMethodPurpose
/orders/{order_id}PATCHOrder confirmation or rejection
/orders/{order_id}/events/order_ready_for_pickupPATCHOrder ready notification
/orders/{order_id}/cancellationPATCHOrder cancelled by restaurant
/menus/{menu_id}PATCHMenu push
/stores/{store_id}/items/statusPUTItem availability (86ing)
/stores/{store_id}/item_options/statusPUTModifier availability
/stores/{store_id}/statusPUTStore status update

Order Confirmation

Receive order acceptance or rejection from the restaurant.

Your Endpoint: PATCH /orders/{order_id}

Path Parameters

ParameterTypeDescription
order_idstringThe order ID you provided when submitting the order

Request Body (Accept)

{
"merchant_supplied_id": "restaurant-internal-order-id",
"order_status": "success",
"prep_time": "2024-01-15T18:30:00Z"
}

Request Body (Reject)

{
"merchant_supplied_id": "restaurant-internal-order-id",
"order_status": "fail",
"failure_reason": "Store is currently closed"
}

Fields

FieldTypeRequiredDescription
merchant_supplied_idstringYesRestaurant's internal order ID
order_statusstringYes"success" for accepted, "fail" for rejected
prep_timestringNoEstimated ready time (ISO 8601)
failure_reasonstringNoReason for rejection (when status is "fail")

Expected Response

Return 200 OK to acknowledge receipt.


Order Ready

Receive notification when the order is ready for pickup or delivery.

Your Endpoint: PATCH /orders/{order_id}/events/order_ready_for_pickup

Path Parameters

ParameterTypeDescription
order_idstringThe order ID

Request Body

{
"merchant_supplied_id": "restaurant-internal-order-id"
}

Expected Response

Return 200 OK to acknowledge receipt.


Order Cancellation

Receive notification when an order is cancelled by the restaurant.

Your Endpoint: PATCH /orders/{order_id}/cancellation

Path Parameters

ParameterTypeDescription
order_idstringThe order ID

Request Body

{
"cancel_reason": "ITEM_OUT_OF_STOCK",
"cancel_details": "The requested item is no longer available"
}

Cancellation Reason Codes

CodeDescription
ITEM_OUT_OF_STOCKOne or more items are unavailable
STORE_CLOSEDThe store is not accepting orders
KITCHEN_BUSYKitchen capacity exceeded
OTHEROther reason (see cancel_details)

Expected Response

Return 200 OK to acknowledge receipt.


Receive menu updates from OneTablet. This is called when menus are created or updated.

Your Endpoint: PATCH /menus/{menu_id} or POST /menus

Request Body

{
"reference": "menu-reference-id",
"store": {
"merchant_supplied_id": "store-123",
"provider_type": "your_platform"
},
"open_hours": [
{
"day_index": "MON",
"start_time": "09:00:00",
"end_time": "21:00:00"
}
],
"special_hours": [],
"menu": {
"name": "Main Menu",
"subtitle": "Available all day",
"merchant_supplied_id": "main-menu-001",
"active": true,
"categories": [...]
}
}

See Menu Schema for the complete menu structure.

Expected Response

Return 200 OK on success. Optionally return the menu ID you assigned:

{
"menu_id": "your-menu-uuid"
}

Item Availability Update (86ing)

Receive updates when items become unavailable or available again.

Your Endpoint: PUT /stores/{store_id}/items/status

Path Parameters

ParameterTypeDescription
store_idstringYour store ID

Request Body

[
{
"merchant_supplied_id": "item-wings-001",
"is_active": false
},
{
"merchant_supplied_id": "item-burger-001",
"is_active": true
}
]

Fields (per item)

FieldTypeDescription
merchant_supplied_idstringItem ID from menu
is_activebooleantrue = available, false = unavailable (86'd)

Expected Response

Return 200 OK to acknowledge receipt.


Modifier Availability Update

Receive updates when modifier options become unavailable or available.

Your Endpoint: PUT /stores/{store_id}/item_options/status

Path Parameters

ParameterTypeDescription
store_idstringYour store ID

Request Body

[
{
"merchant_supplied_id": "opt-bacon",
"is_active": false
},
{
"merchant_supplied_id": "opt-cheese",
"is_active": true
}
]

Expected Response

Return 200 OK to acknowledge receipt.


Store Status Update

Receive updates when a store goes online, offline, or is paused.

Your Endpoint: PUT /stores/{store_id}/status

Path Parameters

ParameterTypeDescription
store_idstringYour store ID

Request Body (Online)

{
"is_active": true
}

Request Body (Offline/Paused)

{
"is_active": false,
"end_time": "2024-01-15T23:59:59Z",
"reason": "operational_issues",
"notes": "Temporarily closed for equipment maintenance"
}

Deactivation Reason Codes

CodeDescription
out_of_businessStore is permanently closed
operational_issuesTemporary operational problems
store_self_disabled_in_their_POS_portalStore disabled via POS
store_pos_connectivity_issuesPOS connection problems

Expected Response

Return 200 OK to acknowledge receipt.


Webhook Security

Verifying Requests

Verify that webhook requests are genuinely from OneTablet:

  1. IP Allowlist - Check source IP against the OneTablet IP allowlist (provided during integration)
  2. Signature Verification - Validate request signatures if configured
  3. Store Validation - Confirm the store ID matches your account

Example Verification

app.use('/webhooks/onetablet', (req, res, next) => {
// Check IP allowlist
const clientIp = req.ip;
if (!ONETABLET_IP_ALLOWLIST.includes(clientIp)) {
return res.status(403).send('Forbidden');
}

// Verify signature (if configured)
const signature = req.headers['x-onetablet-signature'];
if (!verifySignature(req.body, signature)) {
return res.status(401).send('Invalid signature');
}

next();
});

Response Requirements

Your webhook endpoints must:

  1. Return HTTP 200 for successful processing
  2. Respond within 30 seconds
  3. Handle duplicate events (implement idempotency)
  4. Process asynchronously when possible

Success Response

HTTP/1.1 200 OK

Failure Response

Any non-200 response triggers retry logic.


Retry Policy

If your endpoint fails to respond with HTTP 200, OneTablet retries:

AttemptDelay
1st retry1 second
2nd retry5 seconds
3rd retry30 seconds

After 3 failed retries, the webhook is logged for investigation.


Error Responses

If your endpoint encounters an error, return an appropriate HTTP status code:

StatusWhen to Use
200 OKRequest processed successfully
400 Bad RequestInvalid request data
401 UnauthorizedAuthentication failed
404 Not FoundResource not found
500 Internal Server ErrorServer error (OneTablet will retry)

Error Response Body

{
"error": "Error Type",
"message": "Human-readable error description"
}

Idempotency

Webhooks may be delivered more than once. Implement idempotency using:

  • order_id for order events
  • menu_id or reference for menu events
  • store_id + timestamp for status events
async function handleOrderConfirmation(orderId, payload) {
// Check if already processed
const existing = await getOrderConfirmation(orderId);
if (existing) {
return { status: 200, message: 'Already processed' };
}

// Process the confirmation
await processOrderConfirmation(orderId, payload);

// Mark as processed
await markConfirmationProcessed(orderId);

return { status: 200, message: 'Success' };
}

Endpoint Configuration

During integration setup, you provide:

  1. Base URL - Your webhook base URL (e.g., https://api.yourplatform.com/webhooks/onetablet)
  2. Authentication - How OneTablet should authenticate requests to your endpoints
  3. Endpoint paths - If your paths differ from the defaults above

Contact OneTablet technical support to configure your endpoints.