Developer documentation
Build customer, driver, and merchant apps on one API. Read and write restaurants, menus, orders, and drivers; receive real-time events over signed webhooks. Everything is scoped to the token owner.
🛍️ customer app 🛵 Driver App 🧑🍳 Merchant app
Building for the marketplace? App developer docs → · Theme developer docs →
learn_platform primes it, get_liquid_reference gives it the authoritative whitelist, and
validate_theme runs the marketplace's own checks on its output — the full learn → build → validate loop without leaving your editor. Connect in one command →
Getting started
Create an API token from your dashboard under API tokens & webhooks. Choose the read and/or write abilities and copy the token — it is shown only once.
https://www.menubarcode.com/api/v1A quick check that your token works:
curl https://www.menubarcode.com/api/v1/restaurants \
-H "Authorization: Bearer YOUR_TOKEN"
GET https://www.menubarcode.com/api/v1 returns a machine-readable index of available endpoints (no auth required). Machine-readable OpenAPI 3.1 spec (JSON) — generated from the live router, so it always matches the deployed API.Authentication
Send your token as a Bearer header on every request:
Authorization: Bearer YOUR_TOKEN
For quick tests you may instead pass ?api_token=YOUR_TOKEN as a query parameter, but the header is strongly preferred so tokens never leak into logs.
| Ability | Grants |
|---|---|
read | All GET endpoints (every resource). |
write | All mutating endpoints (and, being a superset, all reads). |
Scoped tokens
Beyond coarse read/write, a token can be limited to specific resources with resource:action abilities. Resources: restaurants, menu, orders, customers, analytics, drivers, webhooks; Actions read, write. Pick them when creating the token in the dashboard.
| Example token | Can do |
|---|---|
["orders:write"] | Read + write orders only (a POS integration). |
["menu:read"] | Read the menu; nothing else. |
["orders:read","analytics:read"] | A reporting dashboard. |
Coverage rules: * grants everything; a :write scope also grants its :read; coarse read/write behave like *:read / *:write. A request lacking the required scope returns 403. Legacy read/write tokens are unaffected.
Tokens are hashed at rest (SHA-256) and may carry an optional expiry. Revoke any token instantly from the dashboard.
Rate Limits
The API allows 120 requests per minute per token. Exceeding it returns 429 Too Many Requests with a Retry-After header. Standard rate-limit headers are included on every response:
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 118
Errors
Every error on an /api/v1 route returns conventional HTTP status codes and a single JSON envelope — a human message, a stable machine code, and (on validation) a per-field errors Map
{ "message": "Invalid or expired token.", "code": "unauthenticated" }
{ "message": "The given data was invalid.",
"code": "validation_failed",
"errors": { "title": ["The title field is required."] } }
| Status | code | Meaning |
|---|---|---|
401 | unauthenticated | Missing, invalid, or expired token. |
403 | forbidden | Token lacks the required ability/scope. |
404 | not_found | Resource not found or not owned by the token. |
422 | validation_failed | Validation failed (see errors). |
429 | rate_limited | Rate limit exceeded. |
code, not the human message — messages may be reworded or localized; codes are stable.404, not 403 — the API never confirms the existence of another owner's data.Pagination
List endpoints return Laravel-style paginated envelopes. Use the ?page= query parameter to walk pages.
{
"data": [ ... ],
"current_page": 1,
"last_page": 3,
"per_page": 20,
"total": 47
}
Read restaurants & menu
List the restaurants owned by the token, paginated (20 per page).
{
"data": [
{ "id": 12, "title": "Nova Bistro", "slug": "nova-bistro",
"url": "https://.../nova-bistro", "template": "linen",
"created_at": "2026-06-01T10:22:00+00:00" }
],
"current_page": 1, "last_page": 1, "total": 1
}
A single restaurant with its menu categories and item count.
The full active menu grouped by category.
[
{ "id": 3, "name": "Starters",
"items": [
{ "id": 88, "name": "Bruschetta", "price": 6.50,
"is_sold_out": false, "is_popular": true, "is_vegan": true,
"is_halal": true, "calories": 210 }
]
}
]
Orders
Orders newest first, paginated (30/page). Filter with ?status=.
Full order detail with line items, extras, driver, and delivery timeline.
Create an order — this is how a customer app submits a cart (the merchant's backend holds the token). Every item is validated against the restaurant's live menu; sold-out or foreign items reject the whole order (422). Fires order.created and returns the full order including its track_token.
curl -X POST https://www.menubarcode.com/api/v1/restaurants/12/orders \
-H "Authorization: Bearer YOUR_TOKEN" -H "Content-Type: application/json" \
-d '{
"type": "delivery",
"customer_name": "A. Idriss",
"phone": "+15551234567",
"address": "9 Cedar Road",
"tip_amount": 3.00,
"note": "Ring the bell",
"source": "customer_app",
"items": [
{ "item_id": 88, "quantity": 2, "variation": 5, "extras": [12], "note": "no onion" },
{ "item_id": 91, "quantity": 1 }
]
}'
Order type is one of on-table, takeaway, delivery. for on-table pass table_number; for delivery pass address.
Idempotency. Send an Idempotency-Key header (or a body client_uuid) on any order-create call. Retrying with the same key returns the original order and never creates a duplicate — safe for dropped responses and offline replay. Keys are scoped per restaurant.
Update the kitchen status (new|preparing|ready|delivered|completed|cancelled). Fires order.status_changed.
Storefront API (per-restaurant token)
A separate, public-facing API authenticated by a per-restaurant storefront token sent as X-Storefront-Token (not the owner Bearer token). Issue these from your dashboard; each token can only ever reach its own restaurant. Read scope is menu:read; placing orders needs the order:write Scope
Full menu for the token's restaurant (variants, extras, groups, gallery).
Basic restaurant info for the token's restaurant.
Submit a cart on behalf of a diner. Server-priced and unpaid (the diner pays on arrival); takeaway or on-table only. Every item is validated against the live menu — sold-out or foreign items reject the whole order (422). Caps: 40 items/order, 30 qty/line. Optional coupon_code applies an owner discount server-side. Fires order.created and returns track_token + continue_url.
curl -X POST https://www.menubarcode.com/api/v1/storefront/orders \
-H "X-Storefront-Token: YOUR_STOREFRONT_TOKEN" -H "Content-Type: application/json" \
-d '{
"type": "takeaway",
"customer_name": "A. Idriss",
"phone": "+15551234567",
"coupon_code": "WELCOME10",
"items": [
{ "item_id": 88, "quantity": 2, "variation": 5, "extras": [12] },
{ "item_id": 91, "quantity": 1 }
]
}'
Analytics & customers
Sales summary over a date range (?from=YYYY-MM-DD&to=YYYY-MM-DD, default last 30 days): order counts by status/type, gross & paid revenue, average order value, and top items.
{
"range": { "from": "2026-06-02", "to": "2026-07-02" },
"orders": { "total": 214, "paid": 198, "by_status": {...}, "by_type": {...} },
"revenue": { "gross": 8420.50, "paid": 7990.00, "avg_order_value": 39.35 },
"top_items": [ { "item_id": 88, "name": "Margherita", "quantity": 143 } ]
}
The restaurant's customer list (CRM), paginated. Filter with ?search=.
Manage drivers Write
Drivers belong to you and (optionally) to one restaurant. Creating or rotating a driver returns a raw driver token exactly once — hand it to the driver's app; they authenticate with it (see below).
curl -X POST https://www.menubarcode.com/api/v1/drivers \
-H "Authorization: Bearer YOUR_TOKEN" -H "Content-Type: application/json" \
-d '{"name":"Alex","phone":"+15550001111","restaurant_id":12}'
# → { "id": 7, "name": "Alex", ..., "token": "RAW_DRIVER_TOKEN_SHOWN_ONCE" }
Invalidates the old token and returns a fresh one.
Assign & track a delivery
Delivery orders, filterable by ?delivery_status= and ?driver_id=.
Assign a driver {"driver_id": 7}. Sets delivery_status=assigned and fires order.driver_assigned.
Override the delivery stage: pending | assigned | picked_up | out_for_delivery | delivered | failed.
Driver app API
The driver app authenticates with a Driver token (not an owner token) issued above. Base path https://www.menubarcode.com/api/v1/driver. Every response is scoped to that one driver.
Authorization: Bearer RAW_DRIVER_TOKEN
The authenticated driver's profile.
Orders assigned to this driver. Add ?active=1 to hide delivered/failed.
Advance the delivery: {"delivery_status":"out_for_delivery"} then "delivered" or "picked_up" / "failed", optional note). Fires the same webhooks as the owner endpoint.
Push live position: {"lat":25.2048,"lng":55.2708}. Surfaced to the customer's tracking view while out for delivery.
Customer accounts
A standalone customer app authenticates its own users with a per-customer token (Sanctum-style: multiple devices, individually revocable). No owner token is involved. Customers are scoped per restaurant, so auth is under /restaurants/{id}/customer/…. Browse the menu first with the public endpoint:
Active menu grouped by category (sold-out items omitted). No auth.
Register / login
curl -X POST https://www.menubarcode.com/api/v1/restaurants/12/customer/login \
-H "Content-Type: application/json" \
-d '{"email":"sam@example.com","password":"secret123","device":"iPhone 15"}'
# → { "token": "RAW_CUSTOMER_TOKEN", "customer": { "id": 42, "name": "Sam", ... } }
Passwordless (SMS OTP)
Request a code for a phone number, then verify it. Verify finds-or-creates the customer and returns a token. Auth endpoints are rate-limited (login/register 10/min, OTP request 6/min).
Customer app API
Authenticate with the customer token. Base path https://www.menubarcode.com/api/v1/customer. Everything is scoped to the authenticated customer — the order body can never spoof another customer's id.
Authorization: Bearer RAW_CUSTOMER_TOKEN
Profile read / update (name, email, phone, birthday, consents).
Place an order as this customer (same item shape as the merchant create endpoint; identity is taken from the token). Returns the order with its track_token.
The customer's own order history, paginated.
Saved delivery addresses (first one becomes default; supports lat/lng).
Revokes the token used for the request (that device only).
Order tracking Public
No auth — access is gated by the order's unguessable track_token (returned when the order is created). This powers a customer app live-tracking screen.
{
"id": 5501, "status": "preparing", "delivery_status": "out_for_delivery",
"is_paid": true, "total": 42.00,
"timeline": { "preparing_at": "...", "out_for_delivery_at": "..." },
"items": [ { "name": "Margherita", "quantity": 2 } ],
"driver": { "name": "Alex", "lat": 25.2, "lng": 55.27, "location_updated_at": "..." }
}
The driver block (with live coordinates) appears only once the order is picked up / out for delivery.
Staff Login
A staff app (POS / KDS / waiter) authenticates each staff member with a per-staff token. Two paths mirror the dashboard: email + password, or a quick numeric PIN for shared kitchen tablets. Staff are scoped per restaurant.
curl -X POST https://www.menubarcode.com/api/v1/restaurants/12/staff/pin \
-H "Content-Type: application/json" -d '{"pin":"4321","device":"Kitchen iPad"}'
# → { "token": "RAW_STAFF_TOKEN",
# "staff": { "id": 3, "role": "kitchen", "permissions": ["kds"] } }
The response lists the staff member's effective Permissions — a subset of orders, menu_edit, coupons, analytics, kds, customers derived from their role (manager / cashier / kitchen / waiter) plus any per-staff overrides. Endpoints are permission-gated (403 otherwise).
Staff app API
Authenticate with the staff token. Base path https://www.menubarcode.com/api/v1/staff. All actions are scoped to the staff member's restaurant.
Authorization: Bearer RAW_STAFF_TOKEN
Profile with role and permission list.
List orders and update kitchen status. Requires the orders permission.
Live kitchen tickets grouped by order, filtered to the staff member's station (or ?station_id=). Shows only items still queued|preparing|ready.
Advance (queued → preparing → ready → served) or step back one KDS status. The parent order's status re-syncs automatically.
Edit the menu from the floor (managers). Same payloads as the merchant menu endpoints, scoped to the staff member's restaurant.
Sales summary for the staff member's restaurant (same shape as the merchant analytics endpoint; ?from=&to=).
Revokes this device's token.
Webhooks — setup
Register endpoints from the dashboard under API tokens & webhooks. Pick which events each endpoint receives. On save you get a per-endpoint Signing Secret; use the Test button to send a ping. Pause an endpoint to stop delivery without losing its secret.
Your endpoint should respond with a 2xx status quickly (within 10s). Any other status — or a timeout — is treated as a failure and retried.
Endpoints can also be managed programmatically (for Zapier/Make REST-Hooks) with a webhooks:write token:
GET /api/v1/webhook-endpoints # list your endpoints
POST /api/v1/webhook-endpoints # {"url":"https://…","events":["order.created"]} → 201 {id, secret, …}
DELETE /api/v1/webhook-endpoints/{id} # unsubscribe → 204
The secret is returned only on create — store it to verify the signature. url must be a public HTTPS endpoint (SSRF-guarded); events must be from the list below (or *).
Webhook events
| Event | Fires when |
|---|---|
order.created | A new order is placed (dashboard or API). |
order.status_changed | An order's kitchen status changes (dashboard, POS, or API). |
order.paid | An order is marked fully paid (gateway or split bill). |
order.driver_assigned | A driver is assigned to a delivery. |
order.out_for_delivery | The driver is en route to the customer. |
order.delivered | The delivery was completed. |
order.delivery_failed | The delivery could not be completed. |
refund.completed | A refund is completed for an order. |
reservation.created | A table reservation is created. |
reservation.cancelled | A table reservation is cancelled. |
customer.created | A new customer record is created. |
shift.opened | A cash-drawer / POS shift is opened. |
shift.closed | A cash-drawer / POS shift is closed. |
menu.updated | A menu item or category is created, updated, or deleted (any surface). Payload: {restaurant_id, change, entity, id}. |
entitlement.changed | A feature entitlement is granted or revoked for the workspace (plan change, add-on, app install/uninstall, admin override). Payload: {action, feature_key, source_type, source_id, user_id, occurred_at} where action is granted or revoked. |
subscription.* | Subscription lifecycle: subscription.paused, .resumed, .renewed, .expired, .plan_changed, .past_due, .expiring, .trial_ending. |
app.uninstalled | A marketplace app is uninstalled (delivered to the app's endpoint). |
* | Subscribe to every event above. |
ping | Sent by the Test button to verify wiring. |
Failed a delivery while your endpoint was down? Use Redeliver on any row in the dashboard's Recent deliveries log to re-queue it with a fresh webhook-id.
Webhook payload
Every delivery is a POST with this JSON envelope and these headers:
POST /your-endpoint HTTP/1.1
Content-Type: application/json
webhook-id: msg_a1b2c3d4e5f6g7h8i9j0k1l2
webhook-timestamp: 1751472240
webhook-signature: v1,K5f...base64...==
X-Webhook-Event: order.created (legacy)
X-Webhook-Signature: 9a3f...hex... (legacy, HMAC of body only)
{
"id": "msg_a1b2c3d4e5f6g7h8i9j0k1l2",
"event": "order.created",
"created_at": "2026-07-02T18:04:00+00:00",
"data": { "order_id": 5501, "total": "42.00" }
}
The id is unique per delivery. Because retries reuse the same id, use it to make your handler idempotent.
Verifying the signature
The webhook-signature header is an HMAC-SHA256, base64-encoded, computed over {id}.{timestamp}.{body} using your endpoint's signing secret. Binding the id and timestamp into the signature is what makes a captured request safe against replay. Reject any request whose webhook-timestamp is more than ~5 minutes old.
PHP
$secret = 'whsec_from_dashboard';
$id = $_SERVER['HTTP_WEBHOOK_ID'];
$ts = $_SERVER['HTTP_WEBHOOK_TIMESTAMP'];
$body = file_get_contents('php://input');
$sent = explode(',', $_SERVER['HTTP_WEBHOOK_SIGNATURE'])[1] ?? '';
if (abs(time() - (int) $ts) > 300) { http_response_code(400); exit; }
$expected = base64_encode(hash_hmac('sha256', "$id.$ts.$body", $secret, true));
if (!hash_equals($expected, $sent)) { http_response_code(401); exit; }
// verified — process $body
http_response_code(200);
Node.js
const crypto = require('crypto');
function verify(req, secret) {
const id = req.headers['webhook-id'];
const ts = req.headers['webhook-timestamp'];
const sig = (req.headers['webhook-signature'] || '').split(',')[1];
if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false;
const expected = crypto
.createHmac('sha256', secret)
.update(`${id}.${ts}.${req.rawBody}`)
.digest('base64');
return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(sig || ''));
}
X-Webhook-Signature header (plain HMAC-SHA256 of the body, hex) is also sent for backward compatibility. New integrations should use webhook-signature.Retries & delivery log
Delivery is asynchronous and retried on failure with exponential backoff plus jitter: roughly 1m → 5m → 15m → 1h (up to 5 attempts total). Every attempt — success or failure — is recorded in the delivery log on your dashboard with its HTTP status, attempt number, and response snippet.
webhook-id to handle occasional repeats.MCP servers
Five Model Context Protocol servers connect AI agents (ChatGPT, Claude, Cursor) to the platform — pick the one that matches your audience. All speak JSON-RPC 2.0 over HTTP and negotiate protocol versions 2024-11-05 / 2025-03-26 / 2025-06-18.
| Server | Endpoint | Audience | Auth | Tools |
|---|---|---|---|---|
| Admin | https://www.menubarcode.com/mcp | Store owners — manage the store | API token (Bearer) | 23 |
| Storefront | https://www.menubarcode.com/mcp/storefront | A diner's agent — shop & order one store | Storefront token (agent scope) | 12 |
| Customer | https://www.menubarcode.com/mcp/customer | A signed-in diner — their own orders | Customer token (OTP login) | 5 |
| Catalog | https://www.menubarcode.com/mcp/catalog | Anyone — discover stores platform-wide | Public | 3 |
| Dev | https://www.menubarcode.com/mcp/dev | AI coding tools — build themes/integrations | Public | 7 |
Quickstart: jump to Admin, Catalog, Customer, or Dev. The Storefront server shares the Admin connect pattern with an X-Storefront-Token header instead of a Bearer token.
MCP server (Admin)
An MCP-compatible AI client (Claude, ChatGPT, Cursor) can operate your restaurant in natural language using the same API tokens. Point it at:
https://www.menubarcode.com/mcp JSON-RPC 2.0Authenticate with Authorization: Bearer YOUR_TOKEN. Every tool declares the granular ability it needs (resource:action); a legacy read token covers every :read tool and write covers everything. All calls are scoped to your restaurants and rate-limited. Tools you lack the ability for are hidden from tools/list.
Connect (Claude Code)
claude mcp add --transport http platform-admin https://www.menubarcode.com/mcp \
--header "Authorization: Bearer YOUR_TOKEN"
List tools
curl -X POST https://www.menubarcode.com/mcp \
-H "Authorization: Bearer YOUR_TOKEN" -H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
Call a tool (e.g. add a menu item)
curl -X POST https://www.menubarcode.com/mcp \
-H "Authorization: Bearer YOUR_TOKEN" -H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call",
"params":{"name":"add_menu_item",
"arguments":{"restaurant_id":12,"name":"Latte","price":4.5}}}'
Tools
| Tool | Ability | What it does |
|---|---|---|
list_restaurants | read | Restaurants you own. |
get_menu | read | A restaurant's categories & items. |
list_categories | menu:read | Categories with item counts. |
add_category | menu:write | Create a category. |
update_category | menu:write | Rename / reorder a category. |
delete_category | menu:write | Delete a category (refuses if it has items). |
add_menu_item | write | Create a menu item (plan-limit checked). |
update_menu_item | write | Edit an item's name/price/description. |
delete_menu_item | menu:write | Permanently delete an item. |
set_item_availability | menu:write | Mark an item in/out of stock (86 toggle). |
list_orders | orders:read | Orders newest first; status/date/search filters. |
get_order | orders:read | Full order detail incl. line items. |
update_order_status | write | Advance an order's kitchen status. |
list_customers | customers:read + crm_suite | CRM list; search name/phone/email. Hidden from tools/list without the entitlement. |
get_customer | customers:read + crm_suite | One customer's full record. Hidden from tools/list without the entitlement. |
sales_report | analytics:read | Revenue + order counts + top items for a range. |
get_restaurant_settings | restaurants:read | Profile + ordering settings snapshot. |
update_business_hours | restaurants:write | Set the business-hours text. |
list_coupons | orders:read | Your discount coupons. |
create_coupon | orders:write | Create a percentage/fixed coupon. |
update_coupon | orders:write | Edit a coupon. |
delete_coupon | orders:write | Delete a coupon. |
Catalog MCP (discover restaurants)
A public, read-only MCP server that lets AI agents discover restaurants and dishes across the whole platform, then deep-link into a specific store to order. No auth, rate-limited.
https://www.menubarcode.com/mcp/catalog JSON-RPC 2.0 · publicConnect (Claude Code)
claude mcp add --transport http platform-catalog https://www.menubarcode.com/mcp/catalog
| Tool | What it does |
|---|---|
search_stores | Find restaurants by keyword/city (name, address, menu_url, storefront_mcp hint). |
search_items | Find dishes across all stores (query/dietary/max_price/city), grouped by store. |
get_store | Full public detail for one store by slug or id. |
list_starter_menus | The bundled starter-menu presets a new store can seed from (cafe, pizzeria, burger, bakery, lounge). |
Only active, publicly listed stores appear; owners can opt out in their store settings. No owner contact details are ever returned. To place an order, use the store's storefront MCP with a per-store agent token.
Customer Account MCP
Lets a diner's AI assistant read, track, and reorder their own orders. Authenticated by a per-customer token from the existing OTP login; customer identity comes only from the token — a phone or customer id is never accepted as an argument.
https://www.menubarcode.com/mcp/customer JSON-RPC 2.0 · customer tokenGet a token (OTP flow)
# 1) request a one-time code (sent to the customer's phone)
curl -X POST https://www.menubarcode.com/api/v1/restaurants/12/customer/otp/request \
-H "Content-Type: application/json" -d '{"phone":"+15551234567"}'
# 2) verify the code → returns a customer bearer token
curl -X POST https://www.menubarcode.com/api/v1/restaurants/12/customer/otp/verify \
-H "Content-Type: application/json" -d '{"phone":"+15551234567","code":"123456"}'
Connect (Claude Code)
claude mcp add --transport http my-orders https://www.menubarcode.com/mcp/customer \
--header "Authorization: Bearer CUSTOMER_TOKEN"
| Tool | What it does |
|---|---|
my_orders | Your recent orders (most recent first). |
order_detail | Full detail + line items for one of your orders. |
track_order | Live status by order id or track token. |
reorder | Rebuild a past order as a cart draft (skips sold-out items). |
my_profile | Your name, phone, and order count. |
my_bookings | Your own hotel room bookings at this venue (code, status, dates, room type, total). |
curl -X POST https://www.menubarcode.com/mcp/customer \
-H "Authorization: Bearer CUSTOMER_TOKEN" -H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call",
"params":{"name":"my_orders","arguments":{"limit":5}}}'
Connect your AI editor
Building a theme or an integration with Claude Code, Cursor, or VS Code? Point it at the public Dev MCP server — your AI tool gets live platform docs, the generated Liquid whitelist, and server-side theme validation. No token needed.
https://www.menubarcode.com/mcp/dev JSON-RPC 2.0 · publicClaude Code
claude mcp add --transport http platform-dev https://www.menubarcode.com/mcp/dev
Cursor — .cursor/mcp.json
{ "mcpServers": { "platform-dev": { "url": "https://www.menubarcode.com/mcp/dev" } } }
VS Code — .vscode/mcp.json
{ "servers": { "platform-dev": { "type": "http", "url": "https://www.menubarcode.com/mcp/dev" } } }
Tools learn_platform (start here), search_docs / fetch_full_doc, get_liquid_reference, get_section_schema, validate_theme, list_webhook_events. Recommended agent workflow: learn → build → validate → deliver.
https://www.menubarcode.com/mcp) operates your restaurant data; this one serves documentation and validation and is safe to share publicly.Changelog
| Date | Change |
|---|---|
| 2026-08-20 | Hotel PMS + growth release: refund.completed, reservation.created, reservation.cancelled, customer.created, shift.opened, shift.closed webhook events; staff push-device registration + 2fa endpoints; new MCP tools hotel_availability, my_bookings, list_starter_menus, list_webhook_events. |
| 2026-07-28 | Router-generated discovery index + OpenAPI 3.1 spec (always in parity with the deployed API); Idempotency-Key on order-create; per-token API rate limits; subscription.* + app.uninstalled webhook events + delivery Redeliver. |
| 2026-07-07 | Public Dev MCP server for AI coding tools: live docs search, generated Liquid reference, server-side theme validation. |
| 2026-07-02 | Granular token scopes (resource:action); staff menu editing + analytics endpoints. |
| 2026-07-02 | Staff app: per-staff token auth (password + PIN), role-permission gating, order status, KDS bump/recall. |
| 2026-07-02 | Standalone customer app: per-customer token auth (register/login/OTP), profile, order placement + history, saved addresses, public menu browse. |
| 2026-07-02 | Full management API: menu CRUD, order creation, drivers + delivery lifecycle, driver-app token API, public order tracking, sales analytics, customers. New delivery webhook events. |
| 2026-07-02 | Queued webhook delivery with retries; Standard-Webhooks signing (webhook-id/timestamp/signature); order.paid event; public docs. |
| 2026-06-26 | Initial v1 REST API, tokens, and webhook endpoints. |
https://www.menubarcode.com/api/v1