Flavours Partner API
Endpoints

Order Create

POST
/api/v2/orders

Creates an order. On a branch whose waiter.qr.enabled is on, in a table section whose qr_enabled is on, a body from a customer carrying a table_id is a QR self-order (waiter contract §15.2, W13): the table's open order is reused when it has one and created WAITING / DINING with no owner when it has not, and the lines become a round on that order with status = PENDING — priced at once, so the guest sees a total, but held back from the kitchen until a waiter sends ROUND_ACCEPT (or at once when waiter.qr.auto_accept is on). The response is the order with rounds[], which on a reused table is the table's existing order and not a second one. A pending round the waiter never answers is auto-rejected after waiter.qr.pending_minutes with reject_reason = EXPIRED. A QR round on a table whose open order ZATCA has already reported (order_zatcas.is_synced 1 or 2) answers 423 order.money_locked (data.error.code, data.money_lock) and adds no round. A branch or section with QR off, and every caller that is not a customer, keep today's behaviour exactly: a new order per submission and no round. Gated by the branch cutover switch (branch_settings.waiter.table_service, contract §15.7): a staff body with type = DINING and a table_id answers 409 waiter.table_service_off — data.error.code, with the branch's current value at data.table_service — on a branch set to SETTLE_ONLY or OFF, because opening a table belongs to the waiter app there. A DINING body without a table_id is allowed at every value, and a guest's QR submission is never refused by the switch. Off-hours (FP-1083): on a branch that uses its schedule as the workday, a caller with no open attendance (guest QR — a first order or another round on the table's order —, online, admin/merchant) is refused outside the trading window, i.e. before the opening (the early check-in window is for cashier prep only) or once closing plus overtime has passed: 409 branch.closed at data.error.code, with data.next_opening_at (epoch ms) and data.timezone (the branch's IANA zone) for the client's "closed, opens at" note. A branch with no open day at all is never refused. An order by a cashier with an open attendance, POST /v2/sync/orders and /v2/orders/calc are never refused.

Authorization

API-TOKEN
API-TOKEN<token>

Your partner API key. Send it in the API-TOKEN header on every request.

In: header

Header Parameters

X-API-Version*string

API contract version to target. See the Changelog for what changed in each version.

Default"2.0.0"
Value in"2.3.0" | "2.2.0" | "2.1.0" | "2.0.0"

Request Body

application/json

includes?|
event_type?|
Value in"MODEL" | "ID"
market_id*string

Must match an existing stored value.

branch_id*string

Must match an existing stored value.

source*string
Value in"ADMIN_APP" | "ADMIN_WEB" | "LANDING_APP" | "LANDING_WEB" | "GRUBTECH" | "ODOO"
notes?|
type*string
Value in"TAKE_AWAY" | "DINING" | "DRIVE_THROUGH" | "DELIVERY" | "PICKUP"
table_id?|

This field is required when type is DINING.

discount_id?|
external_reference?|

Must be at least 1 character. Must not be greater than 64 characters.

products*array<>

Must have at least 1 items.

payment?

Response Body

application/json

application/json

application/json

application/json

application/json

curl -X POST "https://api.flavours.sa/dev/api/v2/orders" \  -H "X-API-Version: 2.3.0" \  -H "Content-Type: application/json" \  -d '{    "market_id": "ut",    "branch_id": "vel",    "source": "ODOO",    "type": "PICKUP",    "products": [      []    ]  }'
{
  "meta": {
    "code": 401,
    "status": "error",
    "message": "Unauthenticated."
  },
  "data": null
}
{
  "meta": {
    "code": 403,
    "status": "error",
    "message": "Unauthorized."
  },
  "data": null
}
{
  "meta": {
    "code": 404,
    "status": "error",
    "message": "Resource not found."
  },
  "data": null
}
{
  "meta": {
    "code": 409,
    "status": "error",
    "message": "This branch is closed. It opens at Tue 09:00."
  },
  "data": {
    "next_opening_at": 1791266400000,
    "timezone": "Asia/Riyadh",
    "error": {
      "code": "branch.closed",
      "message": "This branch is closed. It opens at Tue 09:00."
    }
  }
}
{
  "meta": {
    "code": 500,
    "status": "error",
    "message": "Internal server error."
  },
  "data": null
}