Restaurant Order Integration

Official specifications for connecting menu and kitchen systems with Sela.

Sela automatically builds orders from customer conversations and dispatches them instantly to your menu system via webhooks. Update decisions, approve, or reject orders in real-time.

Quick Integration Setup

  1. Generate API Access Key: Create an API access key with orders:read and orders:write scopes from your Sela Dashboard.
  2. Configure Webhook Endpoint: Register your public HTTPS webhook URL and subscribe to the order.created event.
  3. Secure Signature Check: Implement the X-Sela-Signature check algorithm using your webhook secret to ensure payload integrity and protect your server.

1. Receive Order Event (Webhook)

Sela dispatches the webhook payload along with an X-Sela-Delivery header, which acts as an idempotency key during delivery retries.

json
{
  "event": "order.created",
  "data": {
    "id": "toolExecutions:...",
    "status": "pending",
    "orderSummary": "2 burgers, fries, delivery fee included",
    "customer": { "name": "Ali", "phone": "+964..." },
    "fulfillment": { "type": "delivery", "address": "Al Mansour" },
    "externalOrderId": null
  }
}

Webhook Signature Verification

To prevent replay attacks, Sela includes X-Sela-Timestamp (epoch milliseconds) and X-Sela-Signature (hex-encoded HMAC-SHA256). The signature is computed on the string concatenation of: timestamp.body.

verify-webhook.js
const crypto = require("crypto");

function verifySelaWebhook(rawBody, signature, timestamp, secret) {
    // 5-minute tolerance window for replay attacks
    const fiveMinutes = 5 * 60 * 1000;
    if (Math.abs(Date.now() - Number(timestamp)) > fiveMinutes) {
        throw new Error("Replay attack suspected: timestamp window exceeded.");
    }

    // Concatenate timestamp and raw body using a dot
    const signedPayload = `${timestamp}.${rawBody}`;
    
    // Compute HMAC-SHA256 in hex format
    const computed = crypto
        .createHmac("sha256", secret)
        .update(signedPayload)
        .digest("hex");

    // Perform timing-safe comparison to prevent side-channel leaks
    return crypto.timingSafeEqual(
        Buffer.from(signature, "hex"),
        Buffer.from(computed, "hex")
    );
}

2. Update Order State (REST API)

Send restaurant actions (approve, reject, or mark_arrived) to update the customer thread and close the assistant's active order block.

bash
curl "https://jovial-bison-730.convex.site/api/v1/orders/action" \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "order_id": "toolExecutions:...",
    "action": "approve",
    "external_order_id": "menu-123"
  }'
Supported Actions:
  • approve: Accept order and initiate cooking. Sela sends a confirmation message to the customer.
  • reject: Decline order. Sela alerts the customer and restarts conversation context.
  • mark_arrived: Confirm delivery/handover success and close conversation tracking entirely.

3. Query Active Orders (REST API)

Directly query list of pending orders for reference, tracking, or local synchronization tasks.

bash
curl "https://jovial-bison-730.convex.site/api/v1/orders?status=pending&limit=25" \
  -H "Authorization: Bearer sk_live_..."