Public API
Orders
Create orders and (with a secret key) read order details.
Create an order
/orderspublishable or secretcurl -X POST https://www.kitchensflow.com/api/public/v1/orders \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d '{
"items": [
{
"productId": "bbq-bacon",
"quantity": 1,
"selectedOptions": [
{ "groupId": "taille", "optionId": "double", "quantity": 1 }
]
}
],
"customer": { "name": "Yasmine B.", "phone": "+212600112233" },
"fulfillment": "pickup",
"paymentMethod": "pay_at_pickup",
"locationId": "casa-maarif",
"idempotencyKey": "3d3917e0-1fd2-46b3-a85d-aef83a9734a4"
}'Body fields
Dine-in: set fulfillment to table and pass customer.tableNumber. The kitchen board shows Table N with a Web badge. Payment stays pending (pay at counter) unless you integrate card payments later.
Every order receives a per-location dailyNumber (shared with POS) and a ticketLabel for kitchen tickets.
Printing is configured by the restaurant, not by the API. Orders you create land in the kitchen queue and print when staff accept them, for each printer the restaurant subscribed to the accepted event. You cannot choose a printer, ticket format, or trigger a print from the API.
| Field | Required | Notes |
|---|---|---|
| items[].productId | yes | Must exist and be available |
| items[].quantity | yes | 1–50 per line |
| items[].selectedOptions | no | { groupId, optionId, quantity? }[] — prices ignored |
| items[].notes | no | Max 200 chars |
| customer.name | yes | |
| customer.phone | yes | |
| customer.email | no | |
| customer.tableNumber | conditional | Required when fulfillment is table (dine-in / QR). Max 20 chars. |
| fulfillment | no | pickup (default), delivery, table |
| paymentMethod | yes | pay_at_pickup or cash_on_delivery |
| locationId | conditional | Required when the restaurant has more than one location; optional (auto) for single-location tenants |
| idempotencyKey | recommended | UUID v4 — see below |
Response
{
"order": {
"id": "3d3917e0-1fd2-46b3-a85d-aef83a9734a4",
"dailyNumber": 42,
"ticketLabel": "Table 7",
"totalCentimes": 20300,
"currency": "MAD",
"status": "created",
"paymentStatus": "pending",
"paymentMethod": "pay_at_pickup",
"fulfillment": "table",
"locationId": "casa-maarif",
"createdAt": "2026-07-30T14:46:05.115Z"
}
}Idempotency
Generate one UUID v4 per checkout attempt. Retries with the same key return the same order instead of creating a duplicate.
Reuse the key for retries of the same cart. Generate a fresh one when the customer starts a new order.
const idempotencyKey = crypto.randomUUID();Retrieve an order
/orders/:idsecret onlyReturns the full order including customer details. Rejected for publishable keys so PII is never reachable from the browser.
Line merging
Lines with the same productId but different selectedOptions stay separate.
Identical lines (same product, options, and notes) are merged by quantity.