Beta: the Biskèt Partner API may still change before v1 is final. Sandbox access is by request:partners@bisket.ai.
Order lifecycle
stateDiagram-v2 direction TB [*] --> awaiting_payment: POST /orders (collected_by=restaurant) [*] --> pending: POST /orders (collected_by=partner) awaiting_payment --> pending: payment.succeeded awaiting_payment --> cancelled: you cancel, or unpaid 60 min pending --> accepted: restaurant accepts (full or partial) pending --> refused: restaurant refuses pending --> cancelled: you cancel accepted --> preparing: kitchen starts accepted --> ready: order ready preparing --> ready: order ready accepted --> cancelled: restaurant approves your cancel request accepted --> picked_up: driver scans the QR preparing --> picked_up: driver scans the QR ready --> picked_up: driver scans the QR accepted --> not_picked_up: business day closes preparing --> not_picked_up: business day closes ready --> not_picked_up: business day closes picked_up --> delivered: POST /delivery delivered picked_up --> delivery_failed: POST /delivery failed
| Transition | Who | Event |
|---|---|---|
| create | you | 201 (synchronous) |
| order reaches the restaurant | Biskèt | order.received |
| still pending after your acceptance timeout | Biskèt | order.acceptance_overdue (the order stays pending) |
| accept / partially accept / refuse | restaurant | order.accepted / order.partially_accepted / order.refused |
| cancel before acceptance | you | order.cancelled |
| cancel after acceptance | you request, restaurant decides | order.cancel_requested, then order.cancel_approved + order.cancelled, or order.cancel_rejected |
| kitchen starts / ready | restaurant | order.preparing / order.ready |
| pickup | the driver’s scan | order.picked_up |
| close (after pickup, or not picked up at day close) | restaurant’s system | order.closed with reason |
| delivered / failed | you | none (visible on GET /v1/orders/{id}) |
Timing
Section titled “Timing”order.receivednormally follows201within seconds. Some restaurants run Biskèt on a local server at the restaurant: if its internet drops, orders queue and arrive when it reconnects. Watch the location’sstatus(open,closed,unreachable) andlocation.status_changed;POST /ordersrefuses withlocation_not_accepting_orderswhile it cannot take them.- Your acceptance timeout (in
GET /v1/mesettings) starts when the order is paid. Past it you getorder.acceptance_overdue; the restaurant can still answer, and you can cancel. - An order nobody picked up closes at the restaurant’s day close with
reason: not_picked_up. The restaurant prepared it, so it is settled like a pickup.
Partial acceptance
Section titled “Partial acceptance”The restaurant can remove lines it cannot serve (with a reason per line). You get order.partially_accepted with
accepted_subtotal and each removed line’s removal. Refund the customer the removed lines; settlement takes only the
accepted subtotal.
Concurrency
Section titled “Concurrency”Orders carry version and an ETag. Send If-Match on driver, cancel and delivery to act only on the version you
saw; a stale one answers 412 precondition_failed. The SDK’s ifMatch(order) builds the header.