REST API reference
Use OrderRestro as the backend for your restaurant's own website: show the live menu, quote delivery, take orders and bookings, and follow them through the kitchen.
Overview
The Integration API is a plain JSON REST API. It is meant for server-to-server calls — your website’s own backend calls OrderRestro — not for putting a key in browser JavaScript. Orders and bookings arrive live on the dashboard and the kitchen display, and (if you turn the setting on) wait for a staff member to accept them first.
Looking to connect an AI assistant instead? See the MCP server docs. To be told when things happen, see webhooks.
Base URL (replace with your own domain):
https://<your-orderrestro-domain>/api/v1/integrationsAuthentication & scopes
Create a key in Settings > API Keys > Integration API keys > New key. Give it a name, optionally limit it to one location, and tick only the scopes it needs. The key (it starts with ordr_ext_) is shown in full once; only a masked last four characters are kept afterwards. Revoking a key takes effect immediately.
Authorization: Bearer ordr_ext_xxxxxxxxxxxxxxxx| Scope | Allows |
|---|---|
locations:read | List locations |
menu:read | Read the menu and get delivery quotes |
orders:write | Place orders |
orders:read | Look up an order’s status |
reservations:write | Book tables |
reservations:read | Look up a booking’s status |
A leaked key can only ever do what its scopes and location allow — nothing else.
Endpoints
| Method | Path | Scope | What it does |
|---|---|---|---|
GET | /locations | locations:read | List active locations (or just the key's own). |
GET | /locations/:branchId/menu | menu:read | Categories and active items, with prices. |
GET | /locations/:branchId/delivery-quote?pincode=… | menu:read | Delivery fee, minimum order and ETA for a pincode. |
POST | /locations/:branchId/orders | orders:write | Place a takeaway or delivery order (optionally scheduled). |
GET | /locations/:branchId/orders/:orderId | orders:read | Order detail and kitchen progress — poll for status. |
POST | /locations/:branchId/reservations | reservations:write | Book a table. |
GET | /locations/:branchId/reservations/:reservationId | reservations:read | Current reservation status. |
Quote delivery
curl -H "Authorization: Bearer ordr_ext_..." \
"https://your-domain/api/v1/integrations/locations/<branchId>/delivery-quote?pincode=700001"{ "deliverable": true, "zoneName": "Central", "fee": 40, "minOrderAmount": 150, "etaMinutes": 30 }{ "deliverable": false } means the pincode is outside every delivery zone. Zones are set up by the restaurant under Delivery > Zones.
Place an order
curl -X POST https://your-domain/api/v1/integrations/locations/<branchId>/orders \
-H "Authorization: Bearer ordr_ext_..." \
-H "Content-Type: application/json" \
-d '{
"type": "DELIVERY",
"customerName": "Jane Doe",
"customerPhone": "+919800000000",
"delivery": { "address": "12 Park Street", "pincode": "700001", "phone": "+919800000000" },
"scheduledFor": "2026-10-10T13:30:00.000Z",
"notes": "No onions",
"items": [{ "menuItemId": "…", "quantity": 2, "modifierIds": ["…"], "kitchenNote": "extra spicy" }]
}'| Field | Notes |
|---|---|
type | TAKEAWAY (default) or DELIVERY. |
customerName, customerPhone | Required. Repeat orders from one phone number join one customer profile. |
delivery | address, pincode, phone. Required for DELIVERY once the location has delivery zones: the pincode must be inside a zone and the order must reach its minimum. The zone fee is added at payment. A location with no zones keeps the older behaviour (no fee, no zone check). |
scheduledFor | Optional ISO time at least 10 minutes ahead (click & collect / pre-order). The kitchen ticket is released about 25 minutes before it. |
items[].modifierIds | Options must belong to that item, and each option group’s minimum/maximum is enforced for online orders. |
notes | Optional free text shown to staff. |
The response is the created order, including its kitchen ticket. Online orders may wait for a staff member to accept them (a setting under Settings > Online orders); the kitchen doesn’t see them until then.
Track an order
curl -H "Authorization: Bearer ordr_ext_..." \
https://your-domain/api/v1/integrations/locations/<branchId>/orders/<orderId>Returns items, kitchen-ticket progress, payments, and (for deliveries) the delivery status. Prefer webhooks over polling if you need to react to changes.
Book a table
curl -X POST https://your-domain/api/v1/integrations/locations/<branchId>/reservations \
-H "Authorization: Bearer ordr_ext_..." \
-H "Content-Type: application/json" \
-d '{ "customerName": "Jane Doe", "phone": "+919800000000",
"guestCount": 4, "reservedAt": "2026-10-12T19:00:00Z", "durationMinutes": 90 }'Online bookings are capped at what the location’s two largest tables can seat; a bigger party gets a 400 asking the guest to phone the restaurant. Statuses are RESERVED, CONFIRMED, ARRIVED, COMPLETED, CANCELLED and NO_SHOW.
Errors & rate limits
| Status | Meaning |
|---|---|
400 | Invalid body, an option that isn’t available, a pincode with no delivery, a time too soon. |
401 | Missing, invalid or revoked key. |
403 | Missing scope, or a location outside the key’s scope. |
404 | Location, order or booking not found. |
429 | Too many requests. |
{ "message": "Sorry, we do not deliver to that pincode", "error": "Bad Request", "statusCode": 400 }Creating orders or bookings is limited to 60 requests per minute per caller, on top of a 300 per minute app-wide default.