Appearance
Catering (Event Menus)
Event menus are time-boxed catering menus tied to a specific event date (e.g. holiday catering, game-day platters). Customers browse the available event menus for a location, check capacity, and place a pre-order for a pickup slot. Event-menu orders are created unpaid (pay_later); the balance is collected later via an Invoice.
Discovery is public; placing an order requires the kitchenclick:orders.create scope.
List Available Event Menus
GET /v1/ecommerce/locations/{location}/concepts/{concept}/event-menusAuthentication: None (Public)
Rate Limit: 100/min per IP
Path Parameters
| Parameter | Type | Description |
|---|---|---|
location | string | Location ID (e.g. loc_00000k1L2m3N4o5) |
concept | string | Concept ID (e.g. con_00000a1B2c3D4e5) |
Only event menus that are open and whose order deadline has not passed are returned, ordered by event date. An empty array is returned when none are available.
Response
json
{
"status": "success",
"data": [
{
"event_menu_id": "evm_00000a1B2c3D4e5",
"name": "Holiday Catering 2026",
"slug": "holiday-catering-2026",
"event_type": "holiday",
"event_date": "2026-12-25",
"order_open_date": "2026-11-01",
"order_deadline": "2026-12-20T23:59:59Z",
"fulfillment_date_start": "2026-12-24",
"fulfillment_date_end": "2026-12-25",
"is_ordering_open": true,
"menu_id": "mnu_00000z9Y8x7W6v5",
"capacity": {
"max_orders": 50,
"total_orders": 12,
"remaining": 38,
"max_per_slot": 10,
"slots": { "10:00": 3, "12:00": 4, "14:00": 5 }
},
"available_pickup_slots": ["10:00", "11:00", "12:00", "14:00"]
}
]
}| Field | Type | Description |
|---|---|---|
event_menu_id | string | Event menu ID (prefix evm_) |
event_type | string | holiday, seasonal, special_event, or custom |
event_date | string | YYYY-MM-DD event date |
order_deadline | string | ISO 8601 cutoff for placing orders |
is_ordering_open | boolean | Whether orders are currently accepted |
menu_id | string | The linked menu — fetch its items via the Menus API |
capacity | object | Order/slot capacity summary (null if uncapped) |
available_pickup_slots | array | Pickup time slots with remaining capacity |
Get Event Menu Availability
Re-check capacity and pickup slots for a single event menu (call before submitting an order to avoid a rejected slot).
GET /v1/ecommerce/event-menus/{eventMenu}/availabilityAuthentication: None (Public)
Rate Limit: 100/min per IP
Path Parameters
| Parameter | Type | Description |
|---|---|---|
eventMenu | string | Event menu ID (e.g. evm_00000a1B2c3D4e5) |
Response
json
{
"status": "success",
"data": {
"event_menu": {
"event_menu_id": "evm_00000a1B2c3D4e5",
"name": "Holiday Catering 2026",
"event_type": "holiday",
"event_date": "2026-12-25",
"order_deadline": "2026-12-20T23:59:59Z",
"menu_id": "mnu_00000z9Y8x7W6v5"
},
"is_ordering_open": true,
"order_deadline": "2026-12-20T23:59:59Z",
"capacity": {
"max_orders": 50,
"total_orders": 12,
"remaining": 38,
"max_per_slot": 10,
"slots": { "10:00": 3, "12:00": 4 }
},
"available_pickup_slots": ["10:00", "11:00", "12:00", "14:00"]
}
}Errors
| Status | Condition |
|---|---|
404 | Event menu not found |
Create Event Menu Order
Place a catering pre-order. The order is created unpaid; collect the balance later via the Invoices API.
POST /v1/ecommerce/event-menus/{eventMenu}/ordersAuthentication: OAuth Token
Scope: kitchenclick:orders.create
Rate Limit: 30/min per client
Path Parameters
| Parameter | Type | Description |
|---|---|---|
eventMenu | string | Event menu ID (e.g. evm_00000a1B2c3D4e5) |
Request Body
json
{
"location_id": "loc_00000k1L2m3N4o5",
"items": [
{
"item_id": "itm_00000a1B2c3D4e5",
"quantity": 2,
"customizations": [
{ "modifier_id": "mod_no_nuts", "options": ["no_nuts"] }
],
"special_instructions": "Extra crispy"
}
],
"pickup_slot": "10:00",
"customer_name": "Jane Doe",
"customer_email": "jane@example.com",
"customer_phone": "(555) 123-4567",
"special_instructions": "No nuts please"
}| Field | Type | Required | Description |
|---|---|---|---|
location_id | string | Yes | Pickup location ID; must be associated with the event menu's concept |
items | array | Yes | At least one line item |
items[].item_id | string | Yes | Menu item ID |
items[].quantity | integer | Yes | Quantity (≥ 1) |
items[].customizations | array | No | Selected modifiers: [{ modifier_id, options: [] }] |
items[].special_instructions | string | No | Per-item note (≤ 255 chars) |
pickup_slot | string | No | Pickup time slot, e.g. "10:00" (≤ 20 chars); must be an available slot |
customer_name | string | Yes | Customer name (≤ 255 chars) |
customer_email | string | No | Customer email |
customer_phone | string | Yes | Customer phone (≤ 50 chars) |
special_instructions | string | No | Order-level note (≤ 1000 chars) |
Response — 201 Created
json
{
"status": "success",
"data": {
"order_id": "ord_00000x1Y2z3A4b5",
"order_number": 1047,
"friendly_number": "#1047",
"event_menu_id": "evm_00000a1B2c3D4e5",
"pickup_slot": "10:00",
"scheduled_at": "2026-12-25T10:00:00Z",
"total_amount": 156.75,
"status": "open"
}
}| Field | Type | Description |
|---|---|---|
order_id | string | Created order ID (prefix ord_) — track via GET /orders/{order}/track |
order_number | integer | Sequential order number |
friendly_number | string | Display order number, e.g. #1047 |
scheduled_at | string | Pickup datetime (UTC) derived from event_date + pickup_slot |
total_amount | number | Order total |
status | string | Order status (open for new pre-orders) |
Errors
| Status | Message | Condition |
|---|---|---|
404 | Event menu not found. | Unknown event menu |
404 | This event menu is not available at the selected location. | location_id not tied to the concept |
422 | Ordering is not currently open for this event menu. | Before open date or after deadline |
422 | This event menu has reached maximum capacity. | Total order cap reached |
422 | Pickup slot '{slot}' is full. | Selected slot at capacity |
422 | Some items are no longer available. | One or more items 86'd / not live (see unavailable array) |
422 | (validation) | Missing/invalid fields — errors map per field |
Changelog
| Date | Change |
|---|---|
| 2026-06-17 | Initial publication. |