Flavoso APIAPI referenceOrders
Orders
Read, accept, reject, cancel and advance orders, and take them over with your own id. The lifecycle of an order is described under Order flow, taking orders into a till under POS integration.
Endpoints
List orders
get/orders
- Scope:
orders:read- Plan:
- every plan
Without updated_since, the most recently changed orders come first. With updated_since, orders come in ascending updated_at order, which is the way to poll: remember the updated_at of the last order you processed and pass it as the next updated_since, minus a minute of overlap, deduplicating by id + updated_at. Without the overlap, a change committed at the same moment as your previous poll can be missed.
A system that takes over orders can instead ask for acknowledged=false (the orders your app has not acknowledged yet with POST /orders/{id}/acknowledge) and acknowledge each one after booking it.
Unpaid online orders are never listed: they do not exist until the payment is confirmed.
Parameters
| Name | In | Description |
|---|---|---|
statusstring | query | Comma-separated statuses: pending, confirmed, preparing, ready, completed, cancelled. |
typestring | query | Comma-separated order types: pickup, delivery, dine_in. |
updated_sincestring (date-time) | query | Only orders changed after this instant (exclusive; ISO 8601 with time zone, write + as %2B in a URL). Switches the order to ascending updated_at. Poll with an overlap (the last updated_at you processed minus a minute) and deduplicate by id + updated_at: a change committed at the same moment as your poll can otherwise be missed. |
created_sincestring (date-time) | query | Only orders placed at or after this instant (ISO 8601 with time zone; write + as %2B in a URL). |
created_untilstring (date-time) | query | Only orders placed before this instant (exclusive, ISO 8601 with time zone). |
paidboolean | query | true: only orders paid online. false: only orders paid on site, whose payment status stays open (Flavoso does not record payments on site). |
acknowledgedboolean | query | true/false: only orders your app has / has not acknowledged (POST /orders/{id}/acknowledge). Other apps' acknowledgements do not count. |
external_idstring | query | Only the order your app acknowledged with this external_id.max 100 chars |
limitinteger | query | Page size, 1 to 100. Default 25.1 to 100 · default 25 |
cursorstring | query | next_cursor of the previous page. Opaque; send the same filters again with it. |
Response200
OK
objectstringrequiredAlways
list.Values:
"list"dataOrder[]requiredThe items of this page.
Child fields (20)
objectstringrequiredAlways
order.Values:
"order"idstring (uuid)requiredThe order.
codestringrequiredShort code the guest sees and says at the counter, e.g. K7Q2M9.
external_idstringrequirednullableYour app's reference set with
POST /orders/{id}/acknowledge; null when none. Always null in webhook events and inGET /events: the envelope is built once and sent the same to every receiver, but this value belongs to a single app. Retrieve the object to see yours.typestringrequiredHow the guest gets the order.
Values:
"pickup""delivery""dine_in"sourcestringrequiredWhere it was placed:
tablevia a table's QR code,appin the Flavoso app by a signed-in guest,storefronteverything else (the restaurant's ordering page, the app without sign-in).Values:
"storefront""table""app"statusstringrequiredWhere the order is now. Restaurants may skip statuses, see
GET /store.Values:
"pending""confirmed""preparing""ready""completed""cancelled"created_atstring (date-time)requiredWhen the order was placed. ISO 8601 in UTC (
Z).updated_atstring (date-time)requiredLast change. ISO 8601 in UTC (
Z).acknowledged_atstring (date-time)requirednullableWhen your app first acknowledged the order (
POST /orders/{id}/acknowledge); null when not yet. Always null in webhook events and inGET /events: the envelope is built once and sent the same to every receiver, but this value belongs to a single app. Retrieve the object to see yours.requested_forstring (date-time)requirednullablePickup or delivery time chosen by the guest (pre-order); null means as soon as possible.
currencystringrequiredISO 4217, e.g. EUR.
amountsobjectrequiredThe amounts of the order, in cents.
Child fields (6)
subtotalintegerrequiredSum of the items. Integer amount in the smallest currency unit (cents).
delivery_feeintegerrequiredDelivery fee. Integer amount in the smallest currency unit (cents).
service_feeintegerrequiredService fee. Integer amount in the smallest currency unit (cents).
discountintegerrequiredDiscount (stamp card), already subtracted. Integer amount in the smallest currency unit (cents).
tipintegerrequiredTip. Pass-through, not revenue. Integer amount in the smallest currency unit (cents).
totalintegerrequiredsubtotal + delivery_fee + service_fee − discount + tip. Integer amount in the smallest currency unit (cents).
taxobjectrequiredVAT per rate of
total − tip(items, fees, minus discount), computed like the restaurant's accounting export: discounts and delivery fees spread over the rates as the restaurant set it.Child fields (2)
includedbooleanrequiredAlways true: prices include VAT.
Values:
truelinesTaxLine[]requiredOne line per rate, ascending, lines without rate last. The gross amounts add up to total − tip.
Child fields (4)
rate_bpsintegerrequirednullableThe rate in basis points (700 = 7 %). null: no rate was stored for this part (not the same as 0 %); then net and tax are null.
grossintegerrequiredGross amount at this rate. Integer amount in the smallest currency unit (cents).
netintegerrequirednullablegross − tax, in cents. null when rate_bps is null.
taxintegerrequirednullableVAT contained in gross: round(gross × rate / (10000 + rate)), in cents. null when rate_bps is null.
paymentobjectrequiredHow and whether it is paid.
Child fields (3)
methodstringrequiredonline: paid at checkout.on_site: paid at pickup, delivery or the table.Values:
"online""on_site"statusstringrequiredpaidonce the online payment is confirmed.open: to be paid on site; it staysopen, because Flavoso does not record payments on site.Values:
"paid""open"paid_atstring (date-time)requirednullableWhen it was paid; null while open.
customerobjectrequirednullableOnly what is needed to hand the order over (data minimisation): no e-mail, and no phone for dine-in. null when neither is known.
Child fields (2)
namestringrequirednullableThe guest's name.
phonestringrequirednullablePhone for questions; null for dine-in.
deliveryobjectrequirednullableThe delivery address; null unless type is delivery.
Child fields (3)
addressstringrequirednullableStreet and number.
postal_codestringrequirednullablePostal code.
citystringrequirednullableCity.
tableobjectrequirednullableThe table of a dine-in order; null otherwise.
Child fields (2)
idstring (uuid)requiredThe table (
GET /tables).labelstringrequirednullableThe table's name, e.g. 4.
notestringrequirednullableGuest's note for the kitchen (allergies!).
itemsOrderItem[]requiredThe lines.
Child fields (8)
idstring (uuid)requiredThe line.
product_idstring (uuid)requirednullableThe dish (
GET /menu/products/{id}); null when it was deleted since.namestringrequiredName at the time of ordering.
quantityintegerrequiredHow many.
min 1
unit_priceintegerrequiredPrice of one unit including options. Integer amount in the smallest currency unit (cents).
line_totalintegerrequiredunit_price × quantity. Integer amount in the smallest currency unit (cents).
tax_rate_bpsintegerrequirednullableVAT rate frozen at order time, in basis points (700 = 7 %). null when the restaurant has not set rates.
optionsobject[]requiredThe chosen options (extras, sizes), as ordered. Name, surcharge and group name are frozen at order time; the ids point to the menu (
GET /menu/options/{id}) as long as the option exists.Child fields (5)
idstring (uuid)requirednullableThe option (
GET /menu/options/{id}); with it you find your own modifier through itsexternal_id. null for orders placed before 8 October 2026.namestringrequiredName of the option.
price_deltaintegerrequiredSurcharge of this option, per unit. Integer amount in the smallest currency unit (cents).
group_idstring (uuid)requirednullableThe option group the option was chosen in (
GET /menu/option-groups/{id}). null for orders placed before 8 October 2026.group_namestringrequirednullableName of that group at order time, e.g. Extras or Size. null for orders placed before 8 October 2026.
has_morebooleanrequiredWhether another page follows.
next_cursorstringrequirednullablePass as
cursor(with the same filters) to get the next page; null on the last page.
Errors
400invalid_request: a parameter or the body is wrong, or it contains a query parameter or field the operation does not know.paramnames the field.401unauthorized: missing, malformed, expired or revoked access token, or the app was disconnected or suspended.403insufficient_scope,plan_required(withparamwhen an order type is not in the plan) oraccount_inactive.429rate_limited: more than 120 requests per minute on this connection. WaitRetry-Afterseconds.500server_error. Safe to retry with the same Idempotency-Key.
curl "https://api.flavoso.com/v1/orders" \
-H "Authorization: Bearer $ACCESS_TOKEN"{
"object": "list",
"data": [
{
"object": "order",
"id": "5f1c9b2e-8d4a-4c1e-9f3a-2b7d6e8c1a40",
"code": "K7Q2M9",
"external_id": null,
"type": "pickup",
"source": "storefront",
"status": "pending",
"created_at": "2026-10-09T17:42:11.214Z",
"updated_at": "2026-10-09T17:42:11.214Z",
"acknowledged_at": null,
"requested_for": null,
"currency": "EUR",
"amounts": {
"subtotal": 2350,
"delivery_fee": 0,
"service_fee": 0,
"discount": 0,
"tip": 100,
"total": 2450
},
"tax": {
"included": true,
"lines": [
{
"rate_bps": 700,
"gross": 1650,
"net": 1542,
"tax": 108
},
{
"rate_bps": 1900,
"gross": 700,
"net": 588,
"tax": 112
}
]
},
"payment": {
"method": "on_site",
"status": "open",
"paid_at": null
},
"customer": {
"name": "Alex",
"phone": "+49 151 23456789"
},
"delivery": null,
"table": null,
"note": "No onions, please",
"items": [
{
"id": "e9c0ce66-7f7f-42cf-a4bf-7d66f87768c1",
"product_id": "2d6f8a1c-3e5b-4d7f-9a2c-4e6b8d0f2a46",
"name": "Pizza Margherita",
"quantity": 2,
"unit_price": 825,
"line_total": 1650,
"tax_rate_bps": 700,
"options": [
{
"id": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
"name": "Extra cheese",
"price_delta": 100,
"group_id": "5e4d3c2b-1a09-4f8e-b7d6-c5b4a3928170",
"group_name": "Extras"
}
]
},
{
"id": "f1a2b3c4-d5e6-4f70-8a9b-0c1d2e3f4a5b",
"product_id": "7b9d1f3a-5c7e-4a9b-8d1f-3a5c7e9b1d2f",
"name": "Cola 0.5 l",
"quantity": 2,
"unit_price": 350,
"line_total": 700,
"tax_rate_bps": 1900,
"options": []
}
]
}
],
"has_more": false,
"next_cursor": null
}Retrieve an order
get/orders/{id}
- Scope:
orders:read- Plan:
- every plan
The order with everything a POS needs for the receipt: items with options, amounts, VAT per rate, payment, the guest's name (and phone for pickup and delivery) and, for delivery, the address. external_id and acknowledged_at are your app's own values.
Parameters
| Name | In | Description |
|---|---|---|
idstring (uuid)required | path | The order id (UUID). |
Response200
OK
objectstringrequiredAlways
order.Values:
"order"idstring (uuid)requiredThe order.
codestringrequiredShort code the guest sees and says at the counter, e.g. K7Q2M9.
external_idstringrequirednullableYour app's reference set with
POST /orders/{id}/acknowledge; null when none. Always null in webhook events and inGET /events: the envelope is built once and sent the same to every receiver, but this value belongs to a single app. Retrieve the object to see yours.typestringrequiredHow the guest gets the order.
Values:
"pickup""delivery""dine_in"sourcestringrequiredWhere it was placed:
tablevia a table's QR code,appin the Flavoso app by a signed-in guest,storefronteverything else (the restaurant's ordering page, the app without sign-in).Values:
"storefront""table""app"statusstringrequiredWhere the order is now. Restaurants may skip statuses, see
GET /store.Values:
"pending""confirmed""preparing""ready""completed""cancelled"created_atstring (date-time)requiredWhen the order was placed. ISO 8601 in UTC (
Z).updated_atstring (date-time)requiredLast change. ISO 8601 in UTC (
Z).acknowledged_atstring (date-time)requirednullableWhen your app first acknowledged the order (
POST /orders/{id}/acknowledge); null when not yet. Always null in webhook events and inGET /events: the envelope is built once and sent the same to every receiver, but this value belongs to a single app. Retrieve the object to see yours.requested_forstring (date-time)requirednullablePickup or delivery time chosen by the guest (pre-order); null means as soon as possible.
currencystringrequiredISO 4217, e.g. EUR.
amountsobjectrequiredThe amounts of the order, in cents.
Child fields (6)
subtotalintegerrequiredSum of the items. Integer amount in the smallest currency unit (cents).
delivery_feeintegerrequiredDelivery fee. Integer amount in the smallest currency unit (cents).
service_feeintegerrequiredService fee. Integer amount in the smallest currency unit (cents).
discountintegerrequiredDiscount (stamp card), already subtracted. Integer amount in the smallest currency unit (cents).
tipintegerrequiredTip. Pass-through, not revenue. Integer amount in the smallest currency unit (cents).
totalintegerrequiredsubtotal + delivery_fee + service_fee − discount + tip. Integer amount in the smallest currency unit (cents).
taxobjectrequiredVAT per rate of
total − tip(items, fees, minus discount), computed like the restaurant's accounting export: discounts and delivery fees spread over the rates as the restaurant set it.Child fields (2)
includedbooleanrequiredAlways true: prices include VAT.
Values:
truelinesTaxLine[]requiredOne line per rate, ascending, lines without rate last. The gross amounts add up to total − tip.
Child fields (4)
rate_bpsintegerrequirednullableThe rate in basis points (700 = 7 %). null: no rate was stored for this part (not the same as 0 %); then net and tax are null.
grossintegerrequiredGross amount at this rate. Integer amount in the smallest currency unit (cents).
netintegerrequirednullablegross − tax, in cents. null when rate_bps is null.
taxintegerrequirednullableVAT contained in gross: round(gross × rate / (10000 + rate)), in cents. null when rate_bps is null.
paymentobjectrequiredHow and whether it is paid.
Child fields (3)
methodstringrequiredonline: paid at checkout.on_site: paid at pickup, delivery or the table.Values:
"online""on_site"statusstringrequiredpaidonce the online payment is confirmed.open: to be paid on site; it staysopen, because Flavoso does not record payments on site.Values:
"paid""open"paid_atstring (date-time)requirednullableWhen it was paid; null while open.
customerobjectrequirednullableOnly what is needed to hand the order over (data minimisation): no e-mail, and no phone for dine-in. null when neither is known.
Child fields (2)
namestringrequirednullableThe guest's name.
phonestringrequirednullablePhone for questions; null for dine-in.
deliveryobjectrequirednullableThe delivery address; null unless type is delivery.
Child fields (3)
addressstringrequirednullableStreet and number.
postal_codestringrequirednullablePostal code.
citystringrequirednullableCity.
tableobjectrequirednullableThe table of a dine-in order; null otherwise.
Child fields (2)
idstring (uuid)requiredThe table (
GET /tables).labelstringrequirednullableThe table's name, e.g. 4.
notestringrequirednullableGuest's note for the kitchen (allergies!).
itemsOrderItem[]requiredThe lines.
Child fields (8)
idstring (uuid)requiredThe line.
product_idstring (uuid)requirednullableThe dish (
GET /menu/products/{id}); null when it was deleted since.namestringrequiredName at the time of ordering.
quantityintegerrequiredHow many.
min 1
unit_priceintegerrequiredPrice of one unit including options. Integer amount in the smallest currency unit (cents).
line_totalintegerrequiredunit_price × quantity. Integer amount in the smallest currency unit (cents).
tax_rate_bpsintegerrequirednullableVAT rate frozen at order time, in basis points (700 = 7 %). null when the restaurant has not set rates.
optionsobject[]requiredThe chosen options (extras, sizes), as ordered. Name, surcharge and group name are frozen at order time; the ids point to the menu (
GET /menu/options/{id}) as long as the option exists.Child fields (5)
idstring (uuid)requirednullableThe option (
GET /menu/options/{id}); with it you find your own modifier through itsexternal_id. null for orders placed before 8 October 2026.namestringrequiredName of the option.
price_deltaintegerrequiredSurcharge of this option, per unit. Integer amount in the smallest currency unit (cents).
group_idstring (uuid)requirednullableThe option group the option was chosen in (
GET /menu/option-groups/{id}). null for orders placed before 8 October 2026.group_namestringrequirednullableName of that group at order time, e.g. Extras or Size. null for orders placed before 8 October 2026.
Errors
400invalid_request: a parameter or the body is wrong, or it contains a query parameter or field the operation does not know.paramnames the field.401unauthorized: missing, malformed, expired or revoked access token, or the app was disconnected or suspended.403insufficient_scope,plan_required(withparamwhen an order type is not in the plan) oraccount_inactive.404not_found: no such object in this restaurant (objects of other restaurants are never found).429rate_limited: more than 120 requests per minute on this connection. WaitRetry-Afterseconds.500server_error. Safe to retry with the same Idempotency-Key.
curl "https://api.flavoso.com/v1/orders/ORDER_ID" \
-H "Authorization: Bearer $ACCESS_TOKEN"{
"object": "order",
"id": "5f1c9b2e-8d4a-4c1e-9f3a-2b7d6e8c1a40",
"code": "K7Q2M9",
"external_id": null,
"type": "pickup",
"source": "storefront",
"status": "pending",
"created_at": "2026-10-09T17:42:11.214Z",
"updated_at": "2026-10-09T17:42:11.214Z",
"acknowledged_at": null,
"requested_for": null,
"currency": "EUR",
"amounts": {
"subtotal": 2350,
"delivery_fee": 0,
"service_fee": 0,
"discount": 0,
"tip": 100,
"total": 2450
},
"tax": {
"included": true,
"lines": [
{
"rate_bps": 700,
"gross": 1650,
"net": 1542,
"tax": 108
},
{
"rate_bps": 1900,
"gross": 700,
"net": 588,
"tax": 112
}
]
},
"payment": {
"method": "on_site",
"status": "open",
"paid_at": null
},
"customer": {
"name": "Alex",
"phone": "+49 151 23456789"
},
"delivery": null,
"table": null,
"note": "No onions, please",
"items": [
{
"id": "e9c0ce66-7f7f-42cf-a4bf-7d66f87768c1",
"product_id": "2d6f8a1c-3e5b-4d7f-9a2c-4e6b8d0f2a46",
"name": "Pizza Margherita",
"quantity": 2,
"unit_price": 825,
"line_total": 1650,
"tax_rate_bps": 700,
"options": [
{
"id": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
"name": "Extra cheese",
"price_delta": 100,
"group_id": "5e4d3c2b-1a09-4f8e-b7d6-c5b4a3928170",
"group_name": "Extras"
}
]
},
{
"id": "f1a2b3c4-d5e6-4f70-8a9b-0c1d2e3f4a5b",
"product_id": "7b9d1f3a-5c7e-4a9b-8d1f-3a5c7e9b1d2f",
"name": "Cola 0.5 l",
"quantity": 2,
"unit_price": 350,
"line_total": 700,
"tax_rate_bps": 1900,
"options": []
}
]
}Accept an order
post/orders/{id}/accept
- Scope:
orders:write- Plan:
- every plan
Moves a pending order to the first status this restaurant uses after pending: usually confirmed, preparing or ready when the restaurant switched confirmed off (GET /store lists order_statuses). The guest is notified exactly as if the restaurant had accepted in the dashboard.
An order that is already past pending (accepted elsewhere, or advanced) comes back unchanged with 200, so accepting twice is safe. A completed or cancelled order answers 409 invalid_transition.
Parameters
| Name | In | Description |
|---|---|---|
idstring (uuid)required | path | The order id (UUID). |
Idempotency-Keystring | header | Any unique string up to 255 printable characters. Retrying a POST with the same key returns the first response (header Idempotent-Replayed: true) instead of acting twice; the same key with a different body is 422 idempotency_key_reused. Kept for 24 hours. Answers that ask for a retry (5xx, 409 conflict) are not kept. While the first request runs, a retry gets 409 idempotency_in_progress; a first request that never finished frees the key after 2 minutes.max 255 chars |
Response200
The order after the change.
objectstringrequiredAlways
order.Values:
"order"idstring (uuid)requiredThe order.
codestringrequiredShort code the guest sees and says at the counter, e.g. K7Q2M9.
external_idstringrequirednullableYour app's reference set with
POST /orders/{id}/acknowledge; null when none. Always null in webhook events and inGET /events: the envelope is built once and sent the same to every receiver, but this value belongs to a single app. Retrieve the object to see yours.typestringrequiredHow the guest gets the order.
Values:
"pickup""delivery""dine_in"sourcestringrequiredWhere it was placed:
tablevia a table's QR code,appin the Flavoso app by a signed-in guest,storefronteverything else (the restaurant's ordering page, the app without sign-in).Values:
"storefront""table""app"statusstringrequiredWhere the order is now. Restaurants may skip statuses, see
GET /store.Values:
"pending""confirmed""preparing""ready""completed""cancelled"created_atstring (date-time)requiredWhen the order was placed. ISO 8601 in UTC (
Z).updated_atstring (date-time)requiredLast change. ISO 8601 in UTC (
Z).acknowledged_atstring (date-time)requirednullableWhen your app first acknowledged the order (
POST /orders/{id}/acknowledge); null when not yet. Always null in webhook events and inGET /events: the envelope is built once and sent the same to every receiver, but this value belongs to a single app. Retrieve the object to see yours.requested_forstring (date-time)requirednullablePickup or delivery time chosen by the guest (pre-order); null means as soon as possible.
currencystringrequiredISO 4217, e.g. EUR.
amountsobjectrequiredThe amounts of the order, in cents.
Child fields (6)
subtotalintegerrequiredSum of the items. Integer amount in the smallest currency unit (cents).
delivery_feeintegerrequiredDelivery fee. Integer amount in the smallest currency unit (cents).
service_feeintegerrequiredService fee. Integer amount in the smallest currency unit (cents).
discountintegerrequiredDiscount (stamp card), already subtracted. Integer amount in the smallest currency unit (cents).
tipintegerrequiredTip. Pass-through, not revenue. Integer amount in the smallest currency unit (cents).
totalintegerrequiredsubtotal + delivery_fee + service_fee − discount + tip. Integer amount in the smallest currency unit (cents).
taxobjectrequiredVAT per rate of
total − tip(items, fees, minus discount), computed like the restaurant's accounting export: discounts and delivery fees spread over the rates as the restaurant set it.Child fields (2)
includedbooleanrequiredAlways true: prices include VAT.
Values:
truelinesTaxLine[]requiredOne line per rate, ascending, lines without rate last. The gross amounts add up to total − tip.
Child fields (4)
rate_bpsintegerrequirednullableThe rate in basis points (700 = 7 %). null: no rate was stored for this part (not the same as 0 %); then net and tax are null.
grossintegerrequiredGross amount at this rate. Integer amount in the smallest currency unit (cents).
netintegerrequirednullablegross − tax, in cents. null when rate_bps is null.
taxintegerrequirednullableVAT contained in gross: round(gross × rate / (10000 + rate)), in cents. null when rate_bps is null.
paymentobjectrequiredHow and whether it is paid.
Child fields (3)
methodstringrequiredonline: paid at checkout.on_site: paid at pickup, delivery or the table.Values:
"online""on_site"statusstringrequiredpaidonce the online payment is confirmed.open: to be paid on site; it staysopen, because Flavoso does not record payments on site.Values:
"paid""open"paid_atstring (date-time)requirednullableWhen it was paid; null while open.
customerobjectrequirednullableOnly what is needed to hand the order over (data minimisation): no e-mail, and no phone for dine-in. null when neither is known.
Child fields (2)
namestringrequirednullableThe guest's name.
phonestringrequirednullablePhone for questions; null for dine-in.
deliveryobjectrequirednullableThe delivery address; null unless type is delivery.
Child fields (3)
addressstringrequirednullableStreet and number.
postal_codestringrequirednullablePostal code.
citystringrequirednullableCity.
tableobjectrequirednullableThe table of a dine-in order; null otherwise.
Child fields (2)
idstring (uuid)requiredThe table (
GET /tables).labelstringrequirednullableThe table's name, e.g. 4.
notestringrequirednullableGuest's note for the kitchen (allergies!).
itemsOrderItem[]requiredThe lines.
Child fields (8)
idstring (uuid)requiredThe line.
product_idstring (uuid)requirednullableThe dish (
GET /menu/products/{id}); null when it was deleted since.namestringrequiredName at the time of ordering.
quantityintegerrequiredHow many.
min 1
unit_priceintegerrequiredPrice of one unit including options. Integer amount in the smallest currency unit (cents).
line_totalintegerrequiredunit_price × quantity. Integer amount in the smallest currency unit (cents).
tax_rate_bpsintegerrequirednullableVAT rate frozen at order time, in basis points (700 = 7 %). null when the restaurant has not set rates.
optionsobject[]requiredThe chosen options (extras, sizes), as ordered. Name, surcharge and group name are frozen at order time; the ids point to the menu (
GET /menu/options/{id}) as long as the option exists.Child fields (5)
idstring (uuid)requirednullableThe option (
GET /menu/options/{id}); with it you find your own modifier through itsexternal_id. null for orders placed before 8 October 2026.namestringrequiredName of the option.
price_deltaintegerrequiredSurcharge of this option, per unit. Integer amount in the smallest currency unit (cents).
group_idstring (uuid)requirednullableThe option group the option was chosen in (
GET /menu/option-groups/{id}). null for orders placed before 8 October 2026.group_namestringrequirednullableName of that group at order time, e.g. Extras or Size. null for orders placed before 8 October 2026.
Errors
400invalid_request: a parameter or the body is wrong, or it contains a query parameter or field the operation does not know.paramnames the field.401unauthorized: missing, malformed, expired or revoked access token, or the app was disconnected or suspended.403insufficient_scope,plan_required(withparamwhen an order type is not in the plan) oraccount_inactive.404not_found: no such object in this restaurant (objects of other restaurants are never found).409invalid_transition(the status of the object does not allow this),stage_not_used(the restaurant does not use this status),external_id_taken(your app already uses thisexternal_idfor another object of the same kind in this restaurant),slot_unavailable(the time or the table is taken),idempotency_in_progress(a request with this Idempotency-Key is still running) orconflict(the same data was changed elsewhere at the same moment, three times in a row; retry unchanged afterRetry-Afterseconds).413payload_too_large: the body is larger than the operation takes, counted in bytes: 64 KB, 2 MB forPUT /menu. Split the request.422idempotency_key_reused(the key was used with a different request) orlimit_exceeded(too many entries in one request, such as products inPUT /menu, or a limit of the restaurant is reached, such as 60 special days).429rate_limited: more than 120 requests per minute on this connection. WaitRetry-Afterseconds.500server_error. Safe to retry with the same Idempotency-Key.
curl -X POST "https://api.flavoso.com/v1/orders/ORDER_ID/accept" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Idempotency-Key: $(uuidgen)"{
"object": "order",
"id": "5f1c9b2e-8d4a-4c1e-9f3a-2b7d6e8c1a40",
"code": "K7Q2M9",
"external_id": null,
"type": "pickup",
"source": "storefront",
"status": "confirmed",
"created_at": "2026-10-09T17:42:11.214Z",
"updated_at": "2026-10-09T17:42:11.214Z",
"acknowledged_at": null,
"requested_for": null,
"currency": "EUR",
"amounts": {
"subtotal": 2350,
"delivery_fee": 0,
"service_fee": 0,
"discount": 0,
"tip": 100,
"total": 2450
},
"tax": {
"included": true,
"lines": [
{
"rate_bps": 700,
"gross": 1650,
"net": 1542,
"tax": 108
},
{
"rate_bps": 1900,
"gross": 700,
"net": 588,
"tax": 112
}
]
},
"payment": {
"method": "on_site",
"status": "open",
"paid_at": null
},
"customer": {
"name": "Alex",
"phone": "+49 151 23456789"
},
"delivery": null,
"table": null,
"note": "No onions, please",
"items": [
{
"id": "e9c0ce66-7f7f-42cf-a4bf-7d66f87768c1",
"product_id": "2d6f8a1c-3e5b-4d7f-9a2c-4e6b8d0f2a46",
"name": "Pizza Margherita",
"quantity": 2,
"unit_price": 825,
"line_total": 1650,
"tax_rate_bps": 700,
"options": [
{
"id": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
"name": "Extra cheese",
"price_delta": 100,
"group_id": "5e4d3c2b-1a09-4f8e-b7d6-c5b4a3928170",
"group_name": "Extras"
}
]
},
{
"id": "f1a2b3c4-d5e6-4f70-8a9b-0c1d2e3f4a5b",
"product_id": "7b9d1f3a-5c7e-4a9b-8d1f-3a5c7e9b1d2f",
"name": "Cola 0.5 l",
"quantity": 2,
"unit_price": 350,
"line_total": 700,
"tax_rate_bps": 1900,
"options": []
}
]
}Reject an order
post/orders/{id}/reject
- Scope:
orders:write- Plan:
- every plan
Cancels an order that has not been accepted yet (pending only). The guest receives the cancellation notice; reason goes into the restaurant's audit log.
Parameters
| Name | In | Description |
|---|---|---|
idstring (uuid)required | path | The order id (UUID). |
Idempotency-Keystring | header | Any unique string up to 255 printable characters. Retrying a POST with the same key returns the first response (header Idempotent-Replayed: true) instead of acting twice; the same key with a different body is 422 idempotency_key_reused. Kept for 24 hours. Answers that ask for a retry (5xx, 409 conflict) are not kept. While the first request runs, a retry gets 409 idempotency_in_progress; a first request that never finished frees the key after 2 minutes.max 255 chars |
Bodyapplication/json
reasonstringFree text for the restaurant's audit log, e.g. 'out of dough', at most 200 characters (longer answers 400 with
param). Not shown to the guest.max 200 chars
Response200
The order after the change.
objectstringrequiredAlways
order.Values:
"order"idstring (uuid)requiredThe order.
codestringrequiredShort code the guest sees and says at the counter, e.g. K7Q2M9.
external_idstringrequirednullableYour app's reference set with
POST /orders/{id}/acknowledge; null when none. Always null in webhook events and inGET /events: the envelope is built once and sent the same to every receiver, but this value belongs to a single app. Retrieve the object to see yours.typestringrequiredHow the guest gets the order.
Values:
"pickup""delivery""dine_in"sourcestringrequiredWhere it was placed:
tablevia a table's QR code,appin the Flavoso app by a signed-in guest,storefronteverything else (the restaurant's ordering page, the app without sign-in).Values:
"storefront""table""app"statusstringrequiredWhere the order is now. Restaurants may skip statuses, see
GET /store.Values:
"pending""confirmed""preparing""ready""completed""cancelled"created_atstring (date-time)requiredWhen the order was placed. ISO 8601 in UTC (
Z).updated_atstring (date-time)requiredLast change. ISO 8601 in UTC (
Z).acknowledged_atstring (date-time)requirednullableWhen your app first acknowledged the order (
POST /orders/{id}/acknowledge); null when not yet. Always null in webhook events and inGET /events: the envelope is built once and sent the same to every receiver, but this value belongs to a single app. Retrieve the object to see yours.requested_forstring (date-time)requirednullablePickup or delivery time chosen by the guest (pre-order); null means as soon as possible.
currencystringrequiredISO 4217, e.g. EUR.
amountsobjectrequiredThe amounts of the order, in cents.
Child fields (6)
subtotalintegerrequiredSum of the items. Integer amount in the smallest currency unit (cents).
delivery_feeintegerrequiredDelivery fee. Integer amount in the smallest currency unit (cents).
service_feeintegerrequiredService fee. Integer amount in the smallest currency unit (cents).
discountintegerrequiredDiscount (stamp card), already subtracted. Integer amount in the smallest currency unit (cents).
tipintegerrequiredTip. Pass-through, not revenue. Integer amount in the smallest currency unit (cents).
totalintegerrequiredsubtotal + delivery_fee + service_fee − discount + tip. Integer amount in the smallest currency unit (cents).
taxobjectrequiredVAT per rate of
total − tip(items, fees, minus discount), computed like the restaurant's accounting export: discounts and delivery fees spread over the rates as the restaurant set it.Child fields (2)
includedbooleanrequiredAlways true: prices include VAT.
Values:
truelinesTaxLine[]requiredOne line per rate, ascending, lines without rate last. The gross amounts add up to total − tip.
Child fields (4)
rate_bpsintegerrequirednullableThe rate in basis points (700 = 7 %). null: no rate was stored for this part (not the same as 0 %); then net and tax are null.
grossintegerrequiredGross amount at this rate. Integer amount in the smallest currency unit (cents).
netintegerrequirednullablegross − tax, in cents. null when rate_bps is null.
taxintegerrequirednullableVAT contained in gross: round(gross × rate / (10000 + rate)), in cents. null when rate_bps is null.
paymentobjectrequiredHow and whether it is paid.
Child fields (3)
methodstringrequiredonline: paid at checkout.on_site: paid at pickup, delivery or the table.Values:
"online""on_site"statusstringrequiredpaidonce the online payment is confirmed.open: to be paid on site; it staysopen, because Flavoso does not record payments on site.Values:
"paid""open"paid_atstring (date-time)requirednullableWhen it was paid; null while open.
customerobjectrequirednullableOnly what is needed to hand the order over (data minimisation): no e-mail, and no phone for dine-in. null when neither is known.
Child fields (2)
namestringrequirednullableThe guest's name.
phonestringrequirednullablePhone for questions; null for dine-in.
deliveryobjectrequirednullableThe delivery address; null unless type is delivery.
Child fields (3)
addressstringrequirednullableStreet and number.
postal_codestringrequirednullablePostal code.
citystringrequirednullableCity.
tableobjectrequirednullableThe table of a dine-in order; null otherwise.
Child fields (2)
idstring (uuid)requiredThe table (
GET /tables).labelstringrequirednullableThe table's name, e.g. 4.
notestringrequirednullableGuest's note for the kitchen (allergies!).
itemsOrderItem[]requiredThe lines.
Child fields (8)
idstring (uuid)requiredThe line.
product_idstring (uuid)requirednullableThe dish (
GET /menu/products/{id}); null when it was deleted since.namestringrequiredName at the time of ordering.
quantityintegerrequiredHow many.
min 1
unit_priceintegerrequiredPrice of one unit including options. Integer amount in the smallest currency unit (cents).
line_totalintegerrequiredunit_price × quantity. Integer amount in the smallest currency unit (cents).
tax_rate_bpsintegerrequirednullableVAT rate frozen at order time, in basis points (700 = 7 %). null when the restaurant has not set rates.
optionsobject[]requiredThe chosen options (extras, sizes), as ordered. Name, surcharge and group name are frozen at order time; the ids point to the menu (
GET /menu/options/{id}) as long as the option exists.Child fields (5)
idstring (uuid)requirednullableThe option (
GET /menu/options/{id}); with it you find your own modifier through itsexternal_id. null for orders placed before 8 October 2026.namestringrequiredName of the option.
price_deltaintegerrequiredSurcharge of this option, per unit. Integer amount in the smallest currency unit (cents).
group_idstring (uuid)requirednullableThe option group the option was chosen in (
GET /menu/option-groups/{id}). null for orders placed before 8 October 2026.group_namestringrequirednullableName of that group at order time, e.g. Extras or Size. null for orders placed before 8 October 2026.
Errors
400invalid_request: a parameter or the body is wrong, or it contains a query parameter or field the operation does not know.paramnames the field.401unauthorized: missing, malformed, expired or revoked access token, or the app was disconnected or suspended.403insufficient_scope,plan_required(withparamwhen an order type is not in the plan) oraccount_inactive.404not_found: no such object in this restaurant (objects of other restaurants are never found).409invalid_transition(the status of the object does not allow this),stage_not_used(the restaurant does not use this status),external_id_taken(your app already uses thisexternal_idfor another object of the same kind in this restaurant),slot_unavailable(the time or the table is taken),idempotency_in_progress(a request with this Idempotency-Key is still running) orconflict(the same data was changed elsewhere at the same moment, three times in a row; retry unchanged afterRetry-Afterseconds).413payload_too_large: the body is larger than the operation takes, counted in bytes: 64 KB, 2 MB forPUT /menu. Split the request.422idempotency_key_reused(the key was used with a different request) orlimit_exceeded(too many entries in one request, such as products inPUT /menu, or a limit of the restaurant is reached, such as 60 special days).429rate_limited: more than 120 requests per minute on this connection. WaitRetry-Afterseconds.500server_error. Safe to retry with the same Idempotency-Key.
curl -X POST "https://api.flavoso.com/v1/orders/ORDER_ID/reject" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"reason": "Out of dough"
}'{
"reason": "Out of dough"
}{
"object": "order",
"id": "5f1c9b2e-8d4a-4c1e-9f3a-2b7d6e8c1a40",
"code": "K7Q2M9",
"external_id": null,
"type": "pickup",
"source": "storefront",
"status": "confirmed",
"created_at": "2026-10-09T17:42:11.214Z",
"updated_at": "2026-10-09T17:42:11.214Z",
"acknowledged_at": null,
"requested_for": null,
"currency": "EUR",
"amounts": {
"subtotal": 2350,
"delivery_fee": 0,
"service_fee": 0,
"discount": 0,
"tip": 100,
"total": 2450
},
"tax": {
"included": true,
"lines": [
{
"rate_bps": 700,
"gross": 1650,
"net": 1542,
"tax": 108
},
{
"rate_bps": 1900,
"gross": 700,
"net": 588,
"tax": 112
}
]
},
"payment": {
"method": "on_site",
"status": "open",
"paid_at": null
},
"customer": {
"name": "Alex",
"phone": "+49 151 23456789"
},
"delivery": null,
"table": null,
"note": "No onions, please",
"items": [
{
"id": "e9c0ce66-7f7f-42cf-a4bf-7d66f87768c1",
"product_id": "2d6f8a1c-3e5b-4d7f-9a2c-4e6b8d0f2a46",
"name": "Pizza Margherita",
"quantity": 2,
"unit_price": 825,
"line_total": 1650,
"tax_rate_bps": 700,
"options": [
{
"id": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
"name": "Extra cheese",
"price_delta": 100,
"group_id": "5e4d3c2b-1a09-4f8e-b7d6-c5b4a3928170",
"group_name": "Extras"
}
]
},
{
"id": "f1a2b3c4-d5e6-4f70-8a9b-0c1d2e3f4a5b",
"product_id": "7b9d1f3a-5c7e-4a9b-8d1f-3a5c7e9b1d2f",
"name": "Cola 0.5 l",
"quantity": 2,
"unit_price": 350,
"line_total": 700,
"tax_rate_bps": 1900,
"options": []
}
]
}Cancel an order
post/orders/{id}/cancel
- Scope:
orders:write- Plan:
- every plan
Cancels an order from any open status. Guest and staff are notified, the order leaves the kitchen display.
Parameters
| Name | In | Description |
|---|---|---|
idstring (uuid)required | path | The order id (UUID). |
Idempotency-Keystring | header | Any unique string up to 255 printable characters. Retrying a POST with the same key returns the first response (header Idempotent-Replayed: true) instead of acting twice; the same key with a different body is 422 idempotency_key_reused. Kept for 24 hours. Answers that ask for a retry (5xx, 409 conflict) are not kept. While the first request runs, a retry gets 409 idempotency_in_progress; a first request that never finished frees the key after 2 minutes.max 255 chars |
Bodyapplication/json
reasonstringFree text for the restaurant's audit log, e.g. 'out of dough', at most 200 characters (longer answers 400 with
param). Not shown to the guest.max 200 chars
Response200
The order after the change.
objectstringrequiredAlways
order.Values:
"order"idstring (uuid)requiredThe order.
codestringrequiredShort code the guest sees and says at the counter, e.g. K7Q2M9.
external_idstringrequirednullableYour app's reference set with
POST /orders/{id}/acknowledge; null when none. Always null in webhook events and inGET /events: the envelope is built once and sent the same to every receiver, but this value belongs to a single app. Retrieve the object to see yours.typestringrequiredHow the guest gets the order.
Values:
"pickup""delivery""dine_in"sourcestringrequiredWhere it was placed:
tablevia a table's QR code,appin the Flavoso app by a signed-in guest,storefronteverything else (the restaurant's ordering page, the app without sign-in).Values:
"storefront""table""app"statusstringrequiredWhere the order is now. Restaurants may skip statuses, see
GET /store.Values:
"pending""confirmed""preparing""ready""completed""cancelled"created_atstring (date-time)requiredWhen the order was placed. ISO 8601 in UTC (
Z).updated_atstring (date-time)requiredLast change. ISO 8601 in UTC (
Z).acknowledged_atstring (date-time)requirednullableWhen your app first acknowledged the order (
POST /orders/{id}/acknowledge); null when not yet. Always null in webhook events and inGET /events: the envelope is built once and sent the same to every receiver, but this value belongs to a single app. Retrieve the object to see yours.requested_forstring (date-time)requirednullablePickup or delivery time chosen by the guest (pre-order); null means as soon as possible.
currencystringrequiredISO 4217, e.g. EUR.
amountsobjectrequiredThe amounts of the order, in cents.
Child fields (6)
subtotalintegerrequiredSum of the items. Integer amount in the smallest currency unit (cents).
delivery_feeintegerrequiredDelivery fee. Integer amount in the smallest currency unit (cents).
service_feeintegerrequiredService fee. Integer amount in the smallest currency unit (cents).
discountintegerrequiredDiscount (stamp card), already subtracted. Integer amount in the smallest currency unit (cents).
tipintegerrequiredTip. Pass-through, not revenue. Integer amount in the smallest currency unit (cents).
totalintegerrequiredsubtotal + delivery_fee + service_fee − discount + tip. Integer amount in the smallest currency unit (cents).
taxobjectrequiredVAT per rate of
total − tip(items, fees, minus discount), computed like the restaurant's accounting export: discounts and delivery fees spread over the rates as the restaurant set it.Child fields (2)
includedbooleanrequiredAlways true: prices include VAT.
Values:
truelinesTaxLine[]requiredOne line per rate, ascending, lines without rate last. The gross amounts add up to total − tip.
Child fields (4)
rate_bpsintegerrequirednullableThe rate in basis points (700 = 7 %). null: no rate was stored for this part (not the same as 0 %); then net and tax are null.
grossintegerrequiredGross amount at this rate. Integer amount in the smallest currency unit (cents).
netintegerrequirednullablegross − tax, in cents. null when rate_bps is null.
taxintegerrequirednullableVAT contained in gross: round(gross × rate / (10000 + rate)), in cents. null when rate_bps is null.
paymentobjectrequiredHow and whether it is paid.
Child fields (3)
methodstringrequiredonline: paid at checkout.on_site: paid at pickup, delivery or the table.Values:
"online""on_site"statusstringrequiredpaidonce the online payment is confirmed.open: to be paid on site; it staysopen, because Flavoso does not record payments on site.Values:
"paid""open"paid_atstring (date-time)requirednullableWhen it was paid; null while open.
customerobjectrequirednullableOnly what is needed to hand the order over (data minimisation): no e-mail, and no phone for dine-in. null when neither is known.
Child fields (2)
namestringrequirednullableThe guest's name.
phonestringrequirednullablePhone for questions; null for dine-in.
deliveryobjectrequirednullableThe delivery address; null unless type is delivery.
Child fields (3)
addressstringrequirednullableStreet and number.
postal_codestringrequirednullablePostal code.
citystringrequirednullableCity.
tableobjectrequirednullableThe table of a dine-in order; null otherwise.
Child fields (2)
idstring (uuid)requiredThe table (
GET /tables).labelstringrequirednullableThe table's name, e.g. 4.
notestringrequirednullableGuest's note for the kitchen (allergies!).
itemsOrderItem[]requiredThe lines.
Child fields (8)
idstring (uuid)requiredThe line.
product_idstring (uuid)requirednullableThe dish (
GET /menu/products/{id}); null when it was deleted since.namestringrequiredName at the time of ordering.
quantityintegerrequiredHow many.
min 1
unit_priceintegerrequiredPrice of one unit including options. Integer amount in the smallest currency unit (cents).
line_totalintegerrequiredunit_price × quantity. Integer amount in the smallest currency unit (cents).
tax_rate_bpsintegerrequirednullableVAT rate frozen at order time, in basis points (700 = 7 %). null when the restaurant has not set rates.
optionsobject[]requiredThe chosen options (extras, sizes), as ordered. Name, surcharge and group name are frozen at order time; the ids point to the menu (
GET /menu/options/{id}) as long as the option exists.Child fields (5)
idstring (uuid)requirednullableThe option (
GET /menu/options/{id}); with it you find your own modifier through itsexternal_id. null for orders placed before 8 October 2026.namestringrequiredName of the option.
price_deltaintegerrequiredSurcharge of this option, per unit. Integer amount in the smallest currency unit (cents).
group_idstring (uuid)requirednullableThe option group the option was chosen in (
GET /menu/option-groups/{id}). null for orders placed before 8 October 2026.group_namestringrequirednullableName of that group at order time, e.g. Extras or Size. null for orders placed before 8 October 2026.
Errors
400invalid_request: a parameter or the body is wrong, or it contains a query parameter or field the operation does not know.paramnames the field.401unauthorized: missing, malformed, expired or revoked access token, or the app was disconnected or suspended.403insufficient_scope,plan_required(withparamwhen an order type is not in the plan) oraccount_inactive.404not_found: no such object in this restaurant (objects of other restaurants are never found).409invalid_transition(the status of the object does not allow this),stage_not_used(the restaurant does not use this status),external_id_taken(your app already uses thisexternal_idfor another object of the same kind in this restaurant),slot_unavailable(the time or the table is taken),idempotency_in_progress(a request with this Idempotency-Key is still running) orconflict(the same data was changed elsewhere at the same moment, three times in a row; retry unchanged afterRetry-Afterseconds).413payload_too_large: the body is larger than the operation takes, counted in bytes: 64 KB, 2 MB forPUT /menu. Split the request.422idempotency_key_reused(the key was used with a different request) orlimit_exceeded(too many entries in one request, such as products inPUT /menu, or a limit of the restaurant is reached, such as 60 special days).429rate_limited: more than 120 requests per minute on this connection. WaitRetry-Afterseconds.500server_error. Safe to retry with the same Idempotency-Key.
curl -X POST "https://api.flavoso.com/v1/orders/ORDER_ID/cancel" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"reason": "Out of dough"
}'{
"reason": "Out of dough"
}{
"object": "order",
"id": "5f1c9b2e-8d4a-4c1e-9f3a-2b7d6e8c1a40",
"code": "K7Q2M9",
"external_id": null,
"type": "pickup",
"source": "storefront",
"status": "confirmed",
"created_at": "2026-10-09T17:42:11.214Z",
"updated_at": "2026-10-09T17:42:11.214Z",
"acknowledged_at": null,
"requested_for": null,
"currency": "EUR",
"amounts": {
"subtotal": 2350,
"delivery_fee": 0,
"service_fee": 0,
"discount": 0,
"tip": 100,
"total": 2450
},
"tax": {
"included": true,
"lines": [
{
"rate_bps": 700,
"gross": 1650,
"net": 1542,
"tax": 108
},
{
"rate_bps": 1900,
"gross": 700,
"net": 588,
"tax": 112
}
]
},
"payment": {
"method": "on_site",
"status": "open",
"paid_at": null
},
"customer": {
"name": "Alex",
"phone": "+49 151 23456789"
},
"delivery": null,
"table": null,
"note": "No onions, please",
"items": [
{
"id": "e9c0ce66-7f7f-42cf-a4bf-7d66f87768c1",
"product_id": "2d6f8a1c-3e5b-4d7f-9a2c-4e6b8d0f2a46",
"name": "Pizza Margherita",
"quantity": 2,
"unit_price": 825,
"line_total": 1650,
"tax_rate_bps": 700,
"options": [
{
"id": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
"name": "Extra cheese",
"price_delta": 100,
"group_id": "5e4d3c2b-1a09-4f8e-b7d6-c5b4a3928170",
"group_name": "Extras"
}
]
},
{
"id": "f1a2b3c4-d5e6-4f70-8a9b-0c1d2e3f4a5b",
"product_id": "7b9d1f3a-5c7e-4a9b-8d1f-3a5c7e9b1d2f",
"name": "Cola 0.5 l",
"quantity": 2,
"unit_price": 350,
"line_total": 700,
"tax_rate_bps": 1900,
"options": []
}
]
}Advance an order
post/orders/{id}/status
- Scope:
orders:write- Plan:
- every plan
Moves an order forward to confirmed, preparing, ready or completed. Skipping ahead is allowed (confirmed → ready), moving back is not (invalid_transition). Setting the current status again returns the order unchanged.
Restaurants can switch statuses off. A status this restaurant does not use returns stage_not_used; GET /store lists order_statuses.
For delivery orders, ready means ready for the driver and completed means delivered.
Parameters
| Name | In | Description |
|---|---|---|
idstring (uuid)required | path | The order id (UUID). |
Idempotency-Keystring | header | Any unique string up to 255 printable characters. Retrying a POST with the same key returns the first response (header Idempotent-Replayed: true) instead of acting twice; the same key with a different body is 422 idempotency_key_reused. Kept for 24 hours. Answers that ask for a retry (5xx, 409 conflict) are not kept. While the first request runs, a retry gets 409 idempotency_in_progress; a first request that never finished frees the key after 2 minutes.max 255 chars |
Bodyapplication/json
statusstringrequiredThe status to move to. Use /cancel to cancel.
Values:
"confirmed""preparing""ready""completed"
Response200
The order after the change.
objectstringrequiredAlways
order.Values:
"order"idstring (uuid)requiredThe order.
codestringrequiredShort code the guest sees and says at the counter, e.g. K7Q2M9.
external_idstringrequirednullableYour app's reference set with
POST /orders/{id}/acknowledge; null when none. Always null in webhook events and inGET /events: the envelope is built once and sent the same to every receiver, but this value belongs to a single app. Retrieve the object to see yours.typestringrequiredHow the guest gets the order.
Values:
"pickup""delivery""dine_in"sourcestringrequiredWhere it was placed:
tablevia a table's QR code,appin the Flavoso app by a signed-in guest,storefronteverything else (the restaurant's ordering page, the app without sign-in).Values:
"storefront""table""app"statusstringrequiredWhere the order is now. Restaurants may skip statuses, see
GET /store.Values:
"pending""confirmed""preparing""ready""completed""cancelled"created_atstring (date-time)requiredWhen the order was placed. ISO 8601 in UTC (
Z).updated_atstring (date-time)requiredLast change. ISO 8601 in UTC (
Z).acknowledged_atstring (date-time)requirednullableWhen your app first acknowledged the order (
POST /orders/{id}/acknowledge); null when not yet. Always null in webhook events and inGET /events: the envelope is built once and sent the same to every receiver, but this value belongs to a single app. Retrieve the object to see yours.requested_forstring (date-time)requirednullablePickup or delivery time chosen by the guest (pre-order); null means as soon as possible.
currencystringrequiredISO 4217, e.g. EUR.
amountsobjectrequiredThe amounts of the order, in cents.
Child fields (6)
subtotalintegerrequiredSum of the items. Integer amount in the smallest currency unit (cents).
delivery_feeintegerrequiredDelivery fee. Integer amount in the smallest currency unit (cents).
service_feeintegerrequiredService fee. Integer amount in the smallest currency unit (cents).
discountintegerrequiredDiscount (stamp card), already subtracted. Integer amount in the smallest currency unit (cents).
tipintegerrequiredTip. Pass-through, not revenue. Integer amount in the smallest currency unit (cents).
totalintegerrequiredsubtotal + delivery_fee + service_fee − discount + tip. Integer amount in the smallest currency unit (cents).
taxobjectrequiredVAT per rate of
total − tip(items, fees, minus discount), computed like the restaurant's accounting export: discounts and delivery fees spread over the rates as the restaurant set it.Child fields (2)
includedbooleanrequiredAlways true: prices include VAT.
Values:
truelinesTaxLine[]requiredOne line per rate, ascending, lines without rate last. The gross amounts add up to total − tip.
Child fields (4)
rate_bpsintegerrequirednullableThe rate in basis points (700 = 7 %). null: no rate was stored for this part (not the same as 0 %); then net and tax are null.
grossintegerrequiredGross amount at this rate. Integer amount in the smallest currency unit (cents).
netintegerrequirednullablegross − tax, in cents. null when rate_bps is null.
taxintegerrequirednullableVAT contained in gross: round(gross × rate / (10000 + rate)), in cents. null when rate_bps is null.
paymentobjectrequiredHow and whether it is paid.
Child fields (3)
methodstringrequiredonline: paid at checkout.on_site: paid at pickup, delivery or the table.Values:
"online""on_site"statusstringrequiredpaidonce the online payment is confirmed.open: to be paid on site; it staysopen, because Flavoso does not record payments on site.Values:
"paid""open"paid_atstring (date-time)requirednullableWhen it was paid; null while open.
customerobjectrequirednullableOnly what is needed to hand the order over (data minimisation): no e-mail, and no phone for dine-in. null when neither is known.
Child fields (2)
namestringrequirednullableThe guest's name.
phonestringrequirednullablePhone for questions; null for dine-in.
deliveryobjectrequirednullableThe delivery address; null unless type is delivery.
Child fields (3)
addressstringrequirednullableStreet and number.
postal_codestringrequirednullablePostal code.
citystringrequirednullableCity.
tableobjectrequirednullableThe table of a dine-in order; null otherwise.
Child fields (2)
idstring (uuid)requiredThe table (
GET /tables).labelstringrequirednullableThe table's name, e.g. 4.
notestringrequirednullableGuest's note for the kitchen (allergies!).
itemsOrderItem[]requiredThe lines.
Child fields (8)
idstring (uuid)requiredThe line.
product_idstring (uuid)requirednullableThe dish (
GET /menu/products/{id}); null when it was deleted since.namestringrequiredName at the time of ordering.
quantityintegerrequiredHow many.
min 1
unit_priceintegerrequiredPrice of one unit including options. Integer amount in the smallest currency unit (cents).
line_totalintegerrequiredunit_price × quantity. Integer amount in the smallest currency unit (cents).
tax_rate_bpsintegerrequirednullableVAT rate frozen at order time, in basis points (700 = 7 %). null when the restaurant has not set rates.
optionsobject[]requiredThe chosen options (extras, sizes), as ordered. Name, surcharge and group name are frozen at order time; the ids point to the menu (
GET /menu/options/{id}) as long as the option exists.Child fields (5)
idstring (uuid)requirednullableThe option (
GET /menu/options/{id}); with it you find your own modifier through itsexternal_id. null for orders placed before 8 October 2026.namestringrequiredName of the option.
price_deltaintegerrequiredSurcharge of this option, per unit. Integer amount in the smallest currency unit (cents).
group_idstring (uuid)requirednullableThe option group the option was chosen in (
GET /menu/option-groups/{id}). null for orders placed before 8 October 2026.group_namestringrequirednullableName of that group at order time, e.g. Extras or Size. null for orders placed before 8 October 2026.
Errors
400invalid_request: a parameter or the body is wrong, or it contains a query parameter or field the operation does not know.paramnames the field.401unauthorized: missing, malformed, expired or revoked access token, or the app was disconnected or suspended.403insufficient_scope,plan_required(withparamwhen an order type is not in the plan) oraccount_inactive.404not_found: no such object in this restaurant (objects of other restaurants are never found).409invalid_transition(the status of the object does not allow this),stage_not_used(the restaurant does not use this status),external_id_taken(your app already uses thisexternal_idfor another object of the same kind in this restaurant),slot_unavailable(the time or the table is taken),idempotency_in_progress(a request with this Idempotency-Key is still running) orconflict(the same data was changed elsewhere at the same moment, three times in a row; retry unchanged afterRetry-Afterseconds).413payload_too_large: the body is larger than the operation takes, counted in bytes: 64 KB, 2 MB forPUT /menu. Split the request.422idempotency_key_reused(the key was used with a different request) orlimit_exceeded(too many entries in one request, such as products inPUT /menu, or a limit of the restaurant is reached, such as 60 special days).429rate_limited: more than 120 requests per minute on this connection. WaitRetry-Afterseconds.500server_error. Safe to retry with the same Idempotency-Key.
curl -X POST "https://api.flavoso.com/v1/orders/ORDER_ID/status" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"status": "preparing"
}'{
"status": "preparing"
}{
"object": "order",
"id": "5f1c9b2e-8d4a-4c1e-9f3a-2b7d6e8c1a40",
"code": "K7Q2M9",
"external_id": null,
"type": "pickup",
"source": "storefront",
"status": "confirmed",
"created_at": "2026-10-09T17:42:11.214Z",
"updated_at": "2026-10-09T17:42:11.214Z",
"acknowledged_at": null,
"requested_for": null,
"currency": "EUR",
"amounts": {
"subtotal": 2350,
"delivery_fee": 0,
"service_fee": 0,
"discount": 0,
"tip": 100,
"total": 2450
},
"tax": {
"included": true,
"lines": [
{
"rate_bps": 700,
"gross": 1650,
"net": 1542,
"tax": 108
},
{
"rate_bps": 1900,
"gross": 700,
"net": 588,
"tax": 112
}
]
},
"payment": {
"method": "on_site",
"status": "open",
"paid_at": null
},
"customer": {
"name": "Alex",
"phone": "+49 151 23456789"
},
"delivery": null,
"table": null,
"note": "No onions, please",
"items": [
{
"id": "e9c0ce66-7f7f-42cf-a4bf-7d66f87768c1",
"product_id": "2d6f8a1c-3e5b-4d7f-9a2c-4e6b8d0f2a46",
"name": "Pizza Margherita",
"quantity": 2,
"unit_price": 825,
"line_total": 1650,
"tax_rate_bps": 700,
"options": [
{
"id": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
"name": "Extra cheese",
"price_delta": 100,
"group_id": "5e4d3c2b-1a09-4f8e-b7d6-c5b4a3928170",
"group_name": "Extras"
}
]
},
{
"id": "f1a2b3c4-d5e6-4f70-8a9b-0c1d2e3f4a5b",
"product_id": "7b9d1f3a-5c7e-4a9b-8d1f-3a5c7e9b1d2f",
"name": "Cola 0.5 l",
"quantity": 2,
"unit_price": 350,
"line_total": 700,
"tax_rate_bps": 1900,
"options": []
}
]
}Acknowledge an order
post/orders/{id}/acknowledge
- Scope:
orders:write- Plan:
- every plan
Tells Flavoso your app has taken over the order (booked it into the POS, printed it), optionally with your own reference (external_id, e.g. the receipt number). The first call sets acknowledged_at; later calls keep it and only change external_id (send null to remove it). Safe to repeat.
Both values belong to your app: another app connected to the same restaurant sees its own. Find orders you have not taken over yet with GET /orders?acknowledged=false.
Does not change the order's status; use /accept for that. An external_id your app already uses for another order of this restaurant answers 409 external_id_taken.
Parameters
| Name | In | Description |
|---|---|---|
idstring (uuid)required | path | The order id (UUID). |
Idempotency-Keystring | header | Any unique string up to 255 printable characters. Retrying a POST with the same key returns the first response (header Idempotent-Replayed: true) instead of acting twice; the same key with a different body is 422 idempotency_key_reused. Kept for 24 hours. Answers that ask for a retry (5xx, 409 conflict) are not kept. While the first request runs, a retry gets 409 idempotency_in_progress; a first request that never finished frees the key after 2 minutes.max 255 chars |
Bodyapplication/json
external_idstringnullableYour reference for this order, 1 to 100 printable characters, unique per app and restaurant. null removes it; omit it to keep the current one.
1 to 100 chars
Response200
The order with your external_id and acknowledged_at.
objectstringrequiredAlways
order.Values:
"order"idstring (uuid)requiredThe order.
codestringrequiredShort code the guest sees and says at the counter, e.g. K7Q2M9.
external_idstringrequirednullableYour app's reference set with
POST /orders/{id}/acknowledge; null when none. Always null in webhook events and inGET /events: the envelope is built once and sent the same to every receiver, but this value belongs to a single app. Retrieve the object to see yours.typestringrequiredHow the guest gets the order.
Values:
"pickup""delivery""dine_in"sourcestringrequiredWhere it was placed:
tablevia a table's QR code,appin the Flavoso app by a signed-in guest,storefronteverything else (the restaurant's ordering page, the app without sign-in).Values:
"storefront""table""app"statusstringrequiredWhere the order is now. Restaurants may skip statuses, see
GET /store.Values:
"pending""confirmed""preparing""ready""completed""cancelled"created_atstring (date-time)requiredWhen the order was placed. ISO 8601 in UTC (
Z).updated_atstring (date-time)requiredLast change. ISO 8601 in UTC (
Z).acknowledged_atstring (date-time)requirednullableWhen your app first acknowledged the order (
POST /orders/{id}/acknowledge); null when not yet. Always null in webhook events and inGET /events: the envelope is built once and sent the same to every receiver, but this value belongs to a single app. Retrieve the object to see yours.requested_forstring (date-time)requirednullablePickup or delivery time chosen by the guest (pre-order); null means as soon as possible.
currencystringrequiredISO 4217, e.g. EUR.
amountsobjectrequiredThe amounts of the order, in cents.
Child fields (6)
subtotalintegerrequiredSum of the items. Integer amount in the smallest currency unit (cents).
delivery_feeintegerrequiredDelivery fee. Integer amount in the smallest currency unit (cents).
service_feeintegerrequiredService fee. Integer amount in the smallest currency unit (cents).
discountintegerrequiredDiscount (stamp card), already subtracted. Integer amount in the smallest currency unit (cents).
tipintegerrequiredTip. Pass-through, not revenue. Integer amount in the smallest currency unit (cents).
totalintegerrequiredsubtotal + delivery_fee + service_fee − discount + tip. Integer amount in the smallest currency unit (cents).
taxobjectrequiredVAT per rate of
total − tip(items, fees, minus discount), computed like the restaurant's accounting export: discounts and delivery fees spread over the rates as the restaurant set it.Child fields (2)
includedbooleanrequiredAlways true: prices include VAT.
Values:
truelinesTaxLine[]requiredOne line per rate, ascending, lines without rate last. The gross amounts add up to total − tip.
Child fields (4)
rate_bpsintegerrequirednullableThe rate in basis points (700 = 7 %). null: no rate was stored for this part (not the same as 0 %); then net and tax are null.
grossintegerrequiredGross amount at this rate. Integer amount in the smallest currency unit (cents).
netintegerrequirednullablegross − tax, in cents. null when rate_bps is null.
taxintegerrequirednullableVAT contained in gross: round(gross × rate / (10000 + rate)), in cents. null when rate_bps is null.
paymentobjectrequiredHow and whether it is paid.
Child fields (3)
methodstringrequiredonline: paid at checkout.on_site: paid at pickup, delivery or the table.Values:
"online""on_site"statusstringrequiredpaidonce the online payment is confirmed.open: to be paid on site; it staysopen, because Flavoso does not record payments on site.Values:
"paid""open"paid_atstring (date-time)requirednullableWhen it was paid; null while open.
customerobjectrequirednullableOnly what is needed to hand the order over (data minimisation): no e-mail, and no phone for dine-in. null when neither is known.
Child fields (2)
namestringrequirednullableThe guest's name.
phonestringrequirednullablePhone for questions; null for dine-in.
deliveryobjectrequirednullableThe delivery address; null unless type is delivery.
Child fields (3)
addressstringrequirednullableStreet and number.
postal_codestringrequirednullablePostal code.
citystringrequirednullableCity.
tableobjectrequirednullableThe table of a dine-in order; null otherwise.
Child fields (2)
idstring (uuid)requiredThe table (
GET /tables).labelstringrequirednullableThe table's name, e.g. 4.
notestringrequirednullableGuest's note for the kitchen (allergies!).
itemsOrderItem[]requiredThe lines.
Child fields (8)
idstring (uuid)requiredThe line.
product_idstring (uuid)requirednullableThe dish (
GET /menu/products/{id}); null when it was deleted since.namestringrequiredName at the time of ordering.
quantityintegerrequiredHow many.
min 1
unit_priceintegerrequiredPrice of one unit including options. Integer amount in the smallest currency unit (cents).
line_totalintegerrequiredunit_price × quantity. Integer amount in the smallest currency unit (cents).
tax_rate_bpsintegerrequirednullableVAT rate frozen at order time, in basis points (700 = 7 %). null when the restaurant has not set rates.
optionsobject[]requiredThe chosen options (extras, sizes), as ordered. Name, surcharge and group name are frozen at order time; the ids point to the menu (
GET /menu/options/{id}) as long as the option exists.Child fields (5)
idstring (uuid)requirednullableThe option (
GET /menu/options/{id}); with it you find your own modifier through itsexternal_id. null for orders placed before 8 October 2026.namestringrequiredName of the option.
price_deltaintegerrequiredSurcharge of this option, per unit. Integer amount in the smallest currency unit (cents).
group_idstring (uuid)requirednullableThe option group the option was chosen in (
GET /menu/option-groups/{id}). null for orders placed before 8 October 2026.group_namestringrequirednullableName of that group at order time, e.g. Extras or Size. null for orders placed before 8 October 2026.
Errors
400invalid_request: a parameter or the body is wrong, or it contains a query parameter or field the operation does not know.paramnames the field.401unauthorized: missing, malformed, expired or revoked access token, or the app was disconnected or suspended.403insufficient_scope,plan_required(withparamwhen an order type is not in the plan) oraccount_inactive.404not_found: no such object in this restaurant (objects of other restaurants are never found).409invalid_transition(the status of the object does not allow this),stage_not_used(the restaurant does not use this status),external_id_taken(your app already uses thisexternal_idfor another object of the same kind in this restaurant),slot_unavailable(the time or the table is taken),idempotency_in_progress(a request with this Idempotency-Key is still running) orconflict(the same data was changed elsewhere at the same moment, three times in a row; retry unchanged afterRetry-Afterseconds).413payload_too_large: the body is larger than the operation takes, counted in bytes: 64 KB, 2 MB forPUT /menu. Split the request.422idempotency_key_reused(the key was used with a different request) orlimit_exceeded(too many entries in one request, such as products inPUT /menu, or a limit of the restaurant is reached, such as 60 special days).429rate_limited: more than 120 requests per minute on this connection. WaitRetry-Afterseconds.500server_error. Safe to retry with the same Idempotency-Key.
curl -X POST "https://api.flavoso.com/v1/orders/ORDER_ID/acknowledge" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"external_id": "BON-2026-004711"
}'{
"external_id": "BON-2026-004711"
}{
"object": "order",
"id": "5f1c9b2e-8d4a-4c1e-9f3a-2b7d6e8c1a40",
"code": "K7Q2M9",
"external_id": "BON-2026-004711",
"type": "pickup",
"source": "storefront",
"status": "pending",
"created_at": "2026-10-09T17:42:11.214Z",
"updated_at": "2026-10-09T17:42:11.214Z",
"acknowledged_at": "2026-10-09T17:42:15.902Z",
"requested_for": null,
"currency": "EUR",
"amounts": {
"subtotal": 2350,
"delivery_fee": 0,
"service_fee": 0,
"discount": 0,
"tip": 100,
"total": 2450
},
"tax": {
"included": true,
"lines": [
{
"rate_bps": 700,
"gross": 1650,
"net": 1542,
"tax": 108
},
{
"rate_bps": 1900,
"gross": 700,
"net": 588,
"tax": 112
}
]
},
"payment": {
"method": "on_site",
"status": "open",
"paid_at": null
},
"customer": {
"name": "Alex",
"phone": "+49 151 23456789"
},
"delivery": null,
"table": null,
"note": "No onions, please",
"items": [
{
"id": "e9c0ce66-7f7f-42cf-a4bf-7d66f87768c1",
"product_id": "2d6f8a1c-3e5b-4d7f-9a2c-4e6b8d0f2a46",
"name": "Pizza Margherita",
"quantity": 2,
"unit_price": 825,
"line_total": 1650,
"tax_rate_bps": 700,
"options": [
{
"id": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
"name": "Extra cheese",
"price_delta": 100,
"group_id": "5e4d3c2b-1a09-4f8e-b7d6-c5b4a3928170",
"group_name": "Extras"
}
]
},
{
"id": "f1a2b3c4-d5e6-4f70-8a9b-0c1d2e3f4a5b",
"product_id": "7b9d1f3a-5c7e-4a9b-8d1f-3a5c7e9b1d2f",
"name": "Cola 0.5 l",
"quantity": 2,
"unit_price": 350,
"line_total": 700,
"tax_rate_bps": 1900,
"options": []
}
]
}Still unclear? Write to support@flavoso.com and include the id from X-Request-Id. It lets us find your request in the log.