Authenticated API
This endpoint requires a valid JWT Bearer token. Accessible via the API gateway at /v1/commerce/*.
Orders API
Create, manage, and track restaurant orders across all channels.
Authentication Required
All endpoints require a valid Bearer token. See Authentication for details.
Overview
The Orders API supports all order types:
| Order Type | Description | Channel |
|---|---|---|
| Dine-in | Table service orders | Staff Shell, Voice AI |
| Takeout | Customer pickup | Staff Shell, Kiosk, Mobile |
| Delivery | Third-party or in-house | Mobile App, Delivery Platforms |
| Catering | Large event orders | Platform Portal |
| Bar Tab | Open tabs | Staff Shell |
Order Lifecycle
DRAFT → OPEN → SENT → PREPARING → READY → SERVED → CLOSED
↓ ↓
MODIFIED PAID
| Status | Description |
|---|---|
draft | Order being built, not submitted |
open | Order created, items can be added |
sent | Sent to kitchen, tickets created |
preparing | Kitchen actively working |
ready | Food ready for pickup/service |
served | Delivered to customer |
closed | Order complete and paid |
Create Order
Request
POST /api/v1/orders
Authorization: Bearer {access_token}
Content-Type: application/json
{
"location_id": "loc-xyz789",
"order_type": "dine_in",
"table_id": "table-7",
"customer_id": "cust-123",
"guests": 4,
"notes": "Birthday celebration"
}
Parameters
| Field | Type | Required | Description |
|---|---|---|---|
location_id | string | Yes | Restaurant location |
order_type | string | Yes | dine_in, takeout, delivery, catering |
table_id | string | Dine-in | Table for dine-in orders |
customer_id | string | No | Link to customer profile |
guests | number | No | Party size |
notes | string | No | Order-level notes |
Response
{
"id": "order-12345",
"order_number": "1234",
"location_id": "loc-xyz789",
"order_type": "dine_in",
"status": "open",
"table": {
"id": "table-7",
"name": "Table 7"
},
"customer": {
"id": "cust-123",
"name": "John Smith"
},
"guests": 4,
"items": [],
"subtotal": 0,
"tax": 0,
"total": 0,
"created_at": "2026-01-18T12:00:00Z",
"created_by": "user-456"
}
Add Items to Order
Request
POST /api/v1/orders/{order_id}/items
Authorization: Bearer {access_token}
Content-Type: application/json
{
"items": [
{
"menu_item_id": "item-burger-01",
"quantity": 2,
"modifiers": [
{
"modifier_id": "mod-cheese",
"option_id": "opt-cheddar"
},
{
"modifier_id": "mod-temp",
"option_id": "opt-medium"
}
],
"special_instructions": "No onions",
"seat_number": 1
},
{
"menu_item_id": "item-fries-01",
"quantity": 2,
"seat_number": 1
}
]
}
Response
{
"order_id": "order-12345",
"items_added": [
{
"id": "line-001",
"menu_item": {
"id": "item-burger-01",
"name": "Classic Burger"
},
"quantity": 2,
"unit_price": 14.99,
"modifiers": [
{
"name": "Cheese",
"option": "Cheddar",
"price": 1.50
}
],
"special_instructions": "No onions",
"line_total": 32.98,
"status": "pending"
}
],
"subtotal": 42.96,
"tax": 3.65,
"total": 46.61
}
Send to Kitchen
Submit order items to the kitchen display system.
Request
POST /api/v1/orders/{order_id}/send
Authorization: Bearer {access_token}
Content-Type: application/json
{
"items": ["line-001", "line-002"],
"rush": false,
"fire_immediately": false
}
Parameters
| Field | Type | Required | Description |
|---|---|---|---|
items | array | No | Specific items to send (default: all pending) |
rush | boolean | No | Mark as rush order |
fire_immediately | boolean | No | Skip hold for courses |
Response
{
"order_id": "order-12345",
"tickets_created": [
{
"ticket_id": "ticket-001",
"station": "Grill",
"items": ["line-001"]
},
{
"ticket_id": "ticket-002",
"station": "Fry",
"items": ["line-002"]
}
],
"status": "sent"
}
Get Order
Request
GET /api/v1/orders/{order_id}
Authorization: Bearer {access_token}
Response
{
"id": "order-12345",
"order_number": "1234",
"status": "preparing",
"order_type": "dine_in",
"table": {
"id": "table-7",
"name": "Table 7"
},
"items": [
{
"id": "line-001",
"name": "Classic Burger",
"quantity": 2,
"unit_price": 14.99,
"modifiers": ["Cheddar"],
"status": "preparing",
"line_total": 32.98
}
],
"subtotal": 42.96,
"tax": 3.65,
"discounts": [],
"total": 46.61,
"payments": [],
"balance_due": 46.61,
"created_at": "2026-01-18T12:00:00Z",
"updated_at": "2026-01-18T12:05:00Z"
}
List Orders
Request
GET /api/v1/orders?
location_id=loc-xyz789&
status=open,sent,preparing&
order_type=dine_in&
start_date=2026-01-18&
limit=50
Authorization: Bearer {access_token}
Query Parameters
| Parameter | Type | Description |
|---|---|---|
location_id | string | Filter by location |
status | string | Comma-separated statuses |
order_type | string | Filter by order type |
table_id | string | Filter by table |
server_id | string | Filter by server |
start_date | date | Orders from this date |
end_date | date | Orders until this date |
limit | number | Results per page (default: 50) |
offset | number | Pagination offset |
Response
{
"orders": [
{
"id": "order-12345",
"order_number": "1234",
"status": "preparing",
"table": "Table 7",
"total": 46.61,
"created_at": "2026-01-18T12:00:00Z"
}
],
"total": 1,
"limit": 50,
"offset": 0
}
Modify Order Item
Request
PATCH /api/v1/orders/{order_id}/items/{item_id}
Authorization: Bearer {access_token}
Content-Type: application/json
{
"quantity": 1,
"special_instructions": "No onions, extra pickles",
"reason": "Customer request"
}
Void Order Item
Manager Approval Required
Voiding an order item requires a manager PIN. This action is audit-logged and cannot be undone. The voided item will be removed from the kitchen ticket if it has not yet been prepared.
Request
POST /api/v1/orders/{order_id}/items/{item_id}/void
Authorization: Bearer {access_token}
Content-Type: application/json
{
"reason": "Customer changed mind",
"manager_pin": "1234"
}
Apply Discount
Request
POST /api/v1/orders/{order_id}/discounts
Authorization: Bearer {access_token}
Content-Type: application/json
{
"discount_type": "percentage",
"value": 10,
"reason": "Birthday discount",
"item_ids": ["line-001"]
}
Discount Types
| Type | Value | Description |
|---|---|---|
percentage | 0-100 | Percentage off |
fixed | Amount | Fixed dollar amount |
promo_code | Code | Promotional code |
comp | - | Full comp (requires approval) |
Close Order
Request
POST /api/v1/orders/{order_id}/close
Authorization: Bearer {access_token}
Response
{
"id": "order-12345",
"status": "closed",
"closed_at": "2026-01-18T13:30:00Z",
"total": 46.61,
"payments": [
{
"id": "payment-001",
"method": "card",
"amount": 50.00,
"tip": 8.00
}
],
"balance_due": 0
}
Order Events (WebSocket)
Subscribe to real-time order updates:
ws.subscribe('orders', {
location_id: 'loc-xyz789',
events: ['created', 'updated', 'item_ready', 'closed']
});
| Event | Description |
|---|---|
order.created | New order created |
order.updated | Order modified |
order.item_ready | Item ready from kitchen |
order.closed | Order completed |
Error Responses
Order Not Found (404)
{
"error": {
"code": "ORDER_NOT_FOUND",
"message": "Order does not exist"
}
}
Item Unavailable (400)
{
"error": {
"code": "ITEM_UNAVAILABLE",
"message": "Classic Burger is currently unavailable",
"item_id": "item-burger-01"
}
}
Related Documentation
- Payments API - Process payments
- Menu API - Menu management
- KDS API - Kitchen display