This endpoint requires a valid JWT Bearer token. Accessible via the API gateway at /v1/commerce/*.
Online Ordering API
Manage online ordering experiences for web and mobile applications, including menu display, cart management, and checkout.
Menu display endpoints are publicly accessible without authentication. Cart management and checkout endpoints require a Bearer Token. See Authentication for details.
Overview
| Attribute | Value |
|---|---|
| Base Path | /api/v1/online-ordering |
| Authentication | Public (menu), Bearer Token (cart/checkout) |
| Required Roles | pos_staff, server, bartender, cashier, manager, restaurant_staff, restaurant_manager, kitchen, host, tenant_admin, platform_admin, system_admin, super_admin |
Menu Display
Get Online Menu
Retrieve the menu configured for online ordering.
GET /api/v1/online-ordering/menu
Query Parameters
| Parameter | Type | Description |
|---|---|---|
location_id | uuid | Restaurant location |
order_type | string | pickup, delivery, dine_in |
time | datetime | For scheduled orders |
Response
{
"location": {
"id": "loc_123",
"name": "Downtown Location",
"accepts_orders": true,
"order_types": ["pickup", "delivery"],
"current_wait_time_minutes": 25
},
"menu": {
"version": "2026-01-24-1",
"categories": [
{
"id": "cat_appetizers",
"name": "Appetizers",
"description": "Start your meal right",
"image_url": "https://...",
"items": [
{
"id": "item_001",
"name": "Loaded Nachos",
"description": "Tortilla chips with cheese, jalapeños, and salsa",
"price": 12.99,
"image_url": "https://...",
"available": true,
"popular": true,
"dietary_flags": ["vegetarian", "gluten-free-available"],
"modifier_groups": [
{
"id": "mod_proteins",
"name": "Add Protein",
"required": false,
"min_selections": 0,
"max_selections": 1,
"modifiers": [
{"id": "mod_chicken", "name": "Chicken", "price": 3.00},
{"id": "mod_beef", "name": "Ground Beef", "price": 3.50}
]
}
]
}
]
}
]
},
"promotions": [
{
"id": "promo_001",
"title": "Free Delivery Today",
"description": "Orders over $25 get free delivery",
"banner_image": "https://..."
}
]
}
Check Item Availability
Check real-time availability of specific items.
POST /api/v1/online-ordering/availability
Request Body
{
"location_id": "loc_123",
"item_ids": ["item_001", "item_002", "item_003"]
}
Response
{
"items": [
{"item_id": "item_001", "available": true},
{"item_id": "item_002", "available": false, "reason": "sold_out"},
{"item_id": "item_003", "available": true}
]
}
Cart Management
Create Cart
Initialize a new shopping cart.
POST /api/v1/online-ordering/carts
Request Body
{
"location_id": "loc_123",
"order_type": "pickup",
"customer_id": "cust_abc"
}
Response
{
"cart_id": "cart_xyz",
"location_id": "loc_123",
"order_type": "pickup",
"items": [],
"subtotal": 0,
"tax": 0,
"total": 0,
"expires_at": "2026-01-24T20:30:00Z"
}
Get Cart
Retrieve current cart state.
GET /api/v1/online-ordering/carts/{cart_id}
Response
{
"cart_id": "cart_xyz",
"location_id": "loc_123",
"order_type": "pickup",
"items": [
{
"id": "cart_item_001",
"menu_item_id": "item_001",
"name": "Loaded Nachos",
"quantity": 1,
"modifiers": [
{"id": "mod_chicken", "name": "Chicken", "price": 3.00}
],
"special_instructions": "Extra salsa",
"unit_price": 15.99,
"total": 15.99
}
],
"subtotal": 15.99,
"discounts": [],
"fees": [
{"type": "service_fee", "amount": 1.50}
],
"tax": 1.44,
"total": 18.93,
"promo_code": null,
"estimated_ready_time": "2026-01-24T19:25:00Z"
}
Add Item to Cart
Add an item to the cart.
POST /api/v1/online-ordering/carts/{cart_id}/items
Request Body
{
"menu_item_id": "item_001",
"quantity": 1,
"modifiers": [
{"modifier_id": "mod_chicken", "quantity": 1}
],
"special_instructions": "Extra salsa please"
}
Update Cart Item
Modify quantity or modifiers.
PUT /api/v1/online-ordering/carts/{cart_id}/items/{item_id}
Request Body
{
"quantity": 2,
"modifiers": [
{"modifier_id": "mod_beef", "quantity": 1}
]
}
Remove Item from Cart
DELETE /api/v1/online-ordering/carts/{cart_id}/items/{item_id}
Apply Promo Code
POST /api/v1/online-ordering/carts/{cart_id}/promo
Request Body
{
"promo_code": "SAVE20"
}
Response
{
"applied": true,
"promo_code": "SAVE20",
"discount_type": "percentage",
"discount_value": 20,
"discount_amount": 3.20,
"new_total": 15.73
}
Remove Promo Code
DELETE /api/v1/online-ordering/carts/{cart_id}/promo
Checkout
Get Checkout Options
Retrieve available checkout options.
GET /api/v1/online-ordering/carts/{cart_id}/checkout
Response
{
"cart_id": "cart_xyz",
"total": 18.93,
"order_types": {
"pickup": {
"available": true,
"estimated_time_minutes": 25,
"instructions": "Pick up at the front counter"
},
"delivery": {
"available": true,
"fee": 4.99,
"minimum_order": 15.00,
"estimated_time_minutes": 45
}
},
"payment_methods": ["card", "apple_pay", "google_pay"],
"tip_options": {
"enabled": true,
"presets": [15, 18, 20, 25],
"custom_allowed": true
},
"schedule_options": {
"asap_available": true,
"scheduled_available": true,
"time_slots": [
{"time": "2026-01-24T19:30:00Z", "available": true},
{"time": "2026-01-24T20:00:00Z", "available": true}
]
}
}
Submit Order
Complete the checkout and submit the order.
POST /api/v1/online-ordering/carts/{cart_id}/submit
Request Body
{
"customer": {
"name": "John Doe",
"email": "john@example.com",
"phone": "+1234567890"
},
"order_type": "pickup",
"scheduled_time": null,
"payment": {
"method": "card",
"payment_method_id": "pm_abc123"
},
"tip_amount": 3.00,
"delivery_address": null,
"special_instructions": "Please include extra napkins"
}
Response
{
"order_id": "ord_abc123",
"order_number": "OL-042",
"status": "confirmed",
"total_charged": 21.93,
"estimated_ready_time": "2026-01-24T19:25:00Z",
"pickup_instructions": "Pick up at the front counter. Show order number.",
"receipt_url": "https://..."
}
Order Tracking
Get Order Status
Track order status after submission.
GET /api/v1/online-ordering/orders/{order_id}
Response
{
"order_id": "ord_abc123",
"order_number": "OL-042",
"status": "preparing",
"status_display": "Your order is being prepared",
"items": [...],
"total": 21.93,
"order_type": "pickup",
"estimated_ready_time": "2026-01-24T19:25:00Z",
"timeline": [
{"status": "confirmed", "timestamp": "2026-01-24T19:00:00Z"},
{"status": "preparing", "timestamp": "2026-01-24T19:05:00Z"}
],
"location": {
"name": "Downtown Location",
"address": "123 Main St",
"phone": "+1234567890"
}
}
Order Status Values
| Status | Description |
|---|---|
confirmed | Order received |
preparing | Kitchen is making the order |
ready | Ready for pickup/delivery |
out_for_delivery | Driver en route |
completed | Order fulfilled |
cancelled | Order cancelled |
Delivery Integration
Calculate Delivery Fee
Get delivery fee and availability.
POST /api/v1/online-ordering/delivery/quote
Request Body
{
"location_id": "loc_123",
"address": {
"street": "456 Oak Ave",
"city": "Anytown",
"state": "CA",
"zip": "12345"
},
"order_total": 25.00
}
Response
{
"available": true,
"fee": 4.99,
"estimated_time_minutes": 45,
"distance_miles": 3.2,
"free_delivery_threshold": 35.00
}
Track Delivery
Track delivery driver location.
GET /api/v1/online-ordering/orders/{order_id}/delivery
Response
{
"status": "out_for_delivery",
"driver": {
"name": "Mike",
"phone": "+1234567890",
"vehicle": "Silver Honda Civic"
},
"location": {
"latitude": 37.7749,
"longitude": -122.4194,
"updated_at": "2026-01-24T19:35:00Z"
},
"eta_minutes": 12
}
Webhooks
| Event | Description |
|---|---|
online_order.placed | New order submitted |
online_order.confirmed | Order confirmed |
online_order.preparing | Preparation started |
online_order.ready | Order ready |
online_order.completed | Order completed |
online_order.cancelled | Order cancelled |
Error Responses
| Status | Code | Description |
|---|---|---|
| 400 | cart_expired | Cart session expired |
| 400 | item_unavailable | Item no longer available |
| 400 | below_minimum | Order below delivery minimum |
| 400 | promo_invalid | Promo code invalid or expired |
| 404 | cart_not_found | Cart ID not found |
| 422 | payment_failed | Payment processing failed |
Related Documentation
- Online Ordering Guide - Setup guide
- Orders API - Order management
- Menus API - Menu management