Flavours Partner API
Branch

Update Branch

POST
/api/v2/branches/{branchId}

Update an existing branch.

Authorization

API-TOKEN
API-TOKEN<token>

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

In: header

Path Parameters

branchId*string

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*array<>
name_en?|

English name. Must not be greater than 191 characters.

name_ar?|

Arabic name. Must not be greater than 191 characters.

address?|

Branch address. Must not be greater than 500 characters.

latitude?|

Geographic latitude. Must be between -90 and 90.

longitude?|

Geographic longitude. Must be between -180 and 180.

is_active?|

Active status.

is_kitchen_active?|

Kitchen active status.

is_pay_later?|

Enable pay later feature.

timezone?|

IANA timezone of the branch (e.g. Asia/Riyadh), the clock used for its schedule and workday. Omitted or null keeps the current value (Asia/Riyadh for a new branch). Returned as setting.timezone. Must be a valid time zone, such as Africa/Accra.

seating?|

Rule that frees a table to AVAILABLE when its order matches these order statuses and (optionally) transaction status.

kitchen?|

Kitchen display settings for this branch, merged over the stored values. Omitted keys keep their current value; an unknown key is dropped. print_owner (TILL | KITCHEN_SERVICE) says who prints the kitchen ticket — the terminal skips its own print when the kitchen service owns it. customer_notification.channel (OFF | SMS | WHATSAPP | BOTH) sends the guest a message on the last bump, written in customer_notification.language (AR | EN, default AR) from message_ar / message_en, which accept the {order_number} and {branch_name} placeholders. customer_screen styles the guest waiting screen: ready_display_seconds (5..900), number_size (SMALL | MEDIUM | LARGE), preparing_tone / ready_tone (WARNING | SUCCESS | INFO | PRIMARY | ACCENT | DANGER | DARK | MUTED), layout (SPLIT | FOCUS) and the hide_sidebar / hide_back / hide_branch / hide_toolbar chrome flags. Both nested objects merge key by key. legacy_board (ON | READ_ONLY | OFF, default ON) is the cutover switch for the old terminal and web kitchen boards: ON keeps today's behaviour, READ_ONLY renders the board from the ticket mirror with every action disabled, and OFF hides it entirely. READ_ONLY and OFF also make the legacy tick POST /v2/orders/{order}/products/{orderProduct} answer 409 (kitchen.legacy_board_read_only / kitchen.legacy_board_off), and the first move away from ON stamps the branch's switched_at on the cutover console.

waiter?|

Waiter (table-service) settings for this branch, merged over the stored values. Omitted keys keep their current value; an unknown key is dropped and an unknown enum value is a 422. ownership_rule (OWNER | SECTION | BRANCH) says who may act on a table another waiter owns. require_guest_count makes the cover count mandatory when a table is opened. table_warn_minutes / table_late_minutes colour the table time_state from the moment it was opened. allow_merge and allow_transfer switch the move-lines actions off for a branch that does not want them. seats (OFF | OPTIONAL | REQUIRED) and override_policy (MANAGER_PIN | NOT_ALLOWED) are the seat-numbering and manager-approval switches. tips, service_charge_display (SEPARATE | INCLUDED), partial_settlement and pay_at_table_provider (null | NEARPAY) shape settlement at the table. qr is the guest self-ordering block. table_service (FULL | SETTLE_ONLY | OFF) is the terminal cutover switch. pin_lockout caps wrong PIN tries. Changing any of them bumps the waiter config_version of the branch, which reaches paired devices as a config.changed floor event.

Response Body

application/json

application/json

application/json

application/json

application/json

application/json

curl -X POST "https://api.flavours.sa/dev/api/v2/branches/excepturi" \  -H "X-API-Version: 2.3.0" \  -H "Content-Type: application/json" \  -d '{    "includes": [      "dolores"    ]  }'
{
  "meta": {
    "code": 200,
    "status": "success",
    "message": "Branch updated successfully."
  },
  "data": {
    "id": "716ba96a-6dc2-4fe9-93a4-fbba01d9f1fc",
    "market_id": "eef0da10-dd19-4a4c-ab3d-23dd1b548801",
    "name_en": "Harvey Group",
    "name_ar": "Harvey Group",
    "address": "29636 Ladarius Corners\nJaynestad, CT 69312",
    "latitude": 39.18634,
    "longitude": 34.979283,
    "is_active": false,
    "created_at": 1792593332209,
    "updated_at": 1792593332393,
    "deleted_at": null,
    "expired_at": null,
    "is_online": false,
    "code": "BR-808909",
    "level": null,
    "shift": null,
    "days": {
      "SUN": 0,
      "MON": 0,
      "TUE": 0,
      "WED": 0,
      "THU": 0,
      "FRI": 0,
      "SAT": 0
    },
    "location": null,
    "plans": [],
    "schedules": [],
    "out_of_stock_products": [],
    "market": {
      "id": "eef0da10-dd19-4a4c-ab3d-23dd1b548801",
      "sector_id": 15,
      "name_en": "Wisoky-Feest",
      "name_ar": "Wisoky-Feest",
      "description_en": null,
      "description_ar": null,
      "logo_img": "https://via.placeholder.com/200x200.png/009955?text=business+logo+facilis",
      "cover_img": "https://via.placeholder.com/200x200.png/009999?text=business+cover+amet",
      "email": "[email protected]",
      "phone_prefix": "967",
      "phone_number": "7856586642",
      "crn": "033-466-2828",
      "tax_number": "66596607090",
      "created_by": null,
      "email_verified_at": 1792593329562,
      "phone_verified_at": 1792593329562,
      "created_at": 1792593329465,
      "updated_at": 1792593329465,
      "deleted_at": null,
      "is_active": true,
      "merchant_id": null,
      "reseller_id": null,
      "slug": "wisoky-feest",
      "code": "ENT-0000000001",
      "links": {
        "website": null,
        "instagram": null,
        "youtube": null,
        "x": null,
        "call_center": null
      },
      "phone": "7856586642",
      "setting": null
    },
    "setting": {
      "id": 11,
      "market_id": "eef0da10-dd19-4a4c-ab3d-23dd1b548801",
      "branch_id": "716ba96a-6dc2-4fe9-93a4-fbba01d9f1fc",
      "is_kitchen_active": false,
      "is_pay_later": true,
      "invoice_prefix": null,
      "zatca_otp": null,
      "seating": {
        "order": {
          "statuses": [
            "COMPLETED"
          ],
          "transaction": {
            "status": "PAID"
          }
        }
      },
      "kitchen": {
        "complete_on_last_bump": true,
        "courses_enabled": false,
        "courses": [],
        "kitchen_can_fire": false,
        "fire_by_prep_time": false,
        "fallback_print_delay_seconds": 60,
        "ack_warning_seconds": 15,
        "warn_ratio": 0.75,
        "late_ratio": 1,
        "recall_window_seconds": 900,
        "completed_tab_window_seconds": 1800,
        "print_owner": "TILL",
        "legacy_board": "ON",
        "customer_notification": {
          "channel": "OFF",
          "language": "AR",
          "message_en": "Order {order_number} is ready at {branch_name}.",
          "message_ar": "طلبك رقم {order_number} جاهز في {branch_name}."
        },
        "customer_screen": {
          "ready_display_seconds": 90,
          "number_size": "MEDIUM",
          "preparing_tone": "WARNING",
          "ready_tone": "SUCCESS",
          "layout": "SPLIT",
          "hide_sidebar": false,
          "hide_back": false,
          "hide_branch": false,
          "hide_toolbar": false
        }
      },
      "config_version": 0,
      "waiter": {
        "require_guest_count": false,
        "ownership_rule": "SECTION",
        "table_warn_minutes": 45,
        "table_late_minutes": 90,
        "allow_merge": true,
        "allow_transfer": true,
        "seats": "OPTIONAL",
        "override_policy": "MANAGER_PIN",
        "tips": {
          "enabled": false,
          "presets": [
            5,
            10,
            15
          ],
          "allow_custom": true
        },
        "service_charge_display": "SEPARATE",
        "partial_settlement": false,
        "pay_at_table_provider": null,
        "qr": {
          "enabled": false,
          "auto_accept": false,
          "reject_reasons": [],
          "pending_minutes": 15
        },
        "table_service": "FULL",
        "pin_lockout": {
          "attempts": 5,
          "seconds": 60
        }
      },
      "waiter_config_version": 0,
      "waiter_catalog_version": 1,
      "timezone": "Asia/Riyadh",
      "extension": {
        "has_cleartax": false,
        "has_zatca": false,
        "has_qoyod": false
      },
      "payment": {
        "has_apple": false,
        "has_card": false,
        "has_cash": false,
        "has_postpay": true
      },
      "service": {
        "has_dining": false,
        "has_take_away": false
      },
      "qflavours": {
        "configured": false,
        "api_key": null
      },
      "active_plan": null,
      "active_subscription": null
    },
    "waiting_orders": [],
    "process_orders": [],
    "canceled_orders": [],
    "completed_orders": []
  }
}
{
  "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": 422,
    "status": "error",
    "message": "The Name (English) must be a string. (and 3 more errors)"
  },
  "data": [
    {
      "code": 0,
      "message": "The Name (English) must be a string.",
      "field": "name_en"
    },
    {
      "code": 0,
      "message": "The latitude must be a number.",
      "field": "latitude"
    },
    {
      "code": 0,
      "message": "The longitude must be a number.",
      "field": "longitude"
    },
    {
      "code": 0,
      "message": "The Active field must be true or false.",
      "field": "is_active"
    }
  ]
}
{
  "meta": {
    "code": 500,
    "status": "error",
    "message": "Internal server error."
  },
  "data": null
}

List Branches GET

List all branches with pagination and filtering options.

Order Create POST

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.