Flavoso APIAPI-ReferenzBestellungen
Bestellungen
Bestellungen lesen, annehmen, ablehnen, stornieren, weiterschalten und mit eigener Kennung übernehmen. Der Lebenslauf einer Bestellung steht unter Bestellablauf, die Übernahme in eine Kasse unter Kassenanbindung.
Endpunkte
List orders
get/orders
- Recht:
orders:read- Tarif:
- jeder Tarif
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.
Parameter
| Name | Ort | Beschreibung |
|---|---|---|
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. |
Antwort200
OK
objectstringPflichtAlways
list.Werte:
"list"dataOrder[]PflichtThe items of this page.
Felder darin (20)
objectstringPflichtAlways
order.Werte:
"order"idstring (uuid)PflichtThe order.
codestringPflichtShort code the guest sees and says at the counter, e.g. K7Q2M9.
external_idstringPflichtkann null seinYour 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.typestringPflichtHow the guest gets the order.
Werte:
"pickup""delivery""dine_in"sourcestringPflichtWhere 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).Werte:
"storefront""table""app"statusstringPflichtWhere the order is now. Restaurants may skip statuses, see
GET /store.Werte:
"pending""confirmed""preparing""ready""completed""cancelled"created_atstring (date-time)PflichtWhen the order was placed. ISO 8601 in UTC (
Z).updated_atstring (date-time)PflichtLast change. ISO 8601 in UTC (
Z).acknowledged_atstring (date-time)Pflichtkann null seinWhen 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)Pflichtkann null seinPickup or delivery time chosen by the guest (pre-order); null means as soon as possible.
currencystringPflichtISO 4217, e.g. EUR.
amountsobjectPflichtThe amounts of the order, in cents.
Felder darin (6)
subtotalintegerPflichtSum of the items. Integer amount in the smallest currency unit (cents).
delivery_feeintegerPflichtDelivery fee. Integer amount in the smallest currency unit (cents).
service_feeintegerPflichtService fee. Integer amount in the smallest currency unit (cents).
discountintegerPflichtDiscount (stamp card), already subtracted. Integer amount in the smallest currency unit (cents).
tipintegerPflichtTip. Pass-through, not revenue. Integer amount in the smallest currency unit (cents).
totalintegerPflichtsubtotal + delivery_fee + service_fee − discount + tip. Integer amount in the smallest currency unit (cents).
taxobjectPflichtVAT 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.Felder darin (2)
includedbooleanPflichtAlways true: prices include VAT.
Werte:
truelinesTaxLine[]PflichtOne line per rate, ascending, lines without rate last. The gross amounts add up to total − tip.
Felder darin (4)
rate_bpsintegerPflichtkann null seinThe 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.
grossintegerPflichtGross amount at this rate. Integer amount in the smallest currency unit (cents).
netintegerPflichtkann null seingross − tax, in cents. null when rate_bps is null.
taxintegerPflichtkann null seinVAT contained in gross: round(gross × rate / (10000 + rate)), in cents. null when rate_bps is null.
paymentobjectPflichtHow and whether it is paid.
Felder darin (3)
methodstringPflichtonline: paid at checkout.on_site: paid at pickup, delivery or the table.Werte:
"online""on_site"statusstringPflichtpaidonce the online payment is confirmed.open: to be paid on site; it staysopen, because Flavoso does not record payments on site.Werte:
"paid""open"paid_atstring (date-time)Pflichtkann null seinWhen it was paid; null while open.
customerobjectPflichtkann null seinOnly what is needed to hand the order over (data minimisation): no e-mail, and no phone for dine-in. null when neither is known.
Felder darin (2)
namestringPflichtkann null seinThe guest's name.
phonestringPflichtkann null seinPhone for questions; null for dine-in.
deliveryobjectPflichtkann null seinThe delivery address; null unless type is delivery.
Felder darin (3)
addressstringPflichtkann null seinStreet and number.
postal_codestringPflichtkann null seinPostal code.
citystringPflichtkann null seinCity.
tableobjectPflichtkann null seinThe table of a dine-in order; null otherwise.
Felder darin (2)
idstring (uuid)PflichtThe table (
GET /tables).labelstringPflichtkann null seinThe table's name, e.g. 4.
notestringPflichtkann null seinGuest's note for the kitchen (allergies!).
itemsOrderItem[]PflichtThe lines.
Felder darin (8)
idstring (uuid)PflichtThe line.
product_idstring (uuid)Pflichtkann null seinThe dish (
GET /menu/products/{id}); null when it was deleted since.namestringPflichtName at the time of ordering.
quantityintegerPflichtHow many.
min 1
unit_priceintegerPflichtPrice of one unit including options. Integer amount in the smallest currency unit (cents).
line_totalintegerPflichtunit_price × quantity. Integer amount in the smallest currency unit (cents).
tax_rate_bpsintegerPflichtkann null seinVAT rate frozen at order time, in basis points (700 = 7 %). null when the restaurant has not set rates.
optionsobject[]PflichtThe 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.Felder darin (5)
idstring (uuid)Pflichtkann null seinThe option (
GET /menu/options/{id}); with it you find your own modifier through itsexternal_id. null for orders placed before 8 October 2026.namestringPflichtName of the option.
price_deltaintegerPflichtSurcharge of this option, per unit. Integer amount in the smallest currency unit (cents).
group_idstring (uuid)Pflichtkann null seinThe option group the option was chosen in (
GET /menu/option-groups/{id}). null for orders placed before 8 October 2026.group_namestringPflichtkann null seinName of that group at order time, e.g. Extras or Size. null for orders placed before 8 October 2026.
has_morebooleanPflichtWhether another page follows.
next_cursorstringPflichtkann null seinPass as
cursor(with the same filters) to get the next page; null on the last page.
Fehler
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}
- Recht:
orders:read- Tarif:
- jeder Tarif
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.
Parameter
| Name | Ort | Beschreibung |
|---|---|---|
idstring (uuid)Pflicht | path | The order id (UUID). |
Antwort200
OK
objectstringPflichtAlways
order.Werte:
"order"idstring (uuid)PflichtThe order.
codestringPflichtShort code the guest sees and says at the counter, e.g. K7Q2M9.
external_idstringPflichtkann null seinYour 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.typestringPflichtHow the guest gets the order.
Werte:
"pickup""delivery""dine_in"sourcestringPflichtWhere 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).Werte:
"storefront""table""app"statusstringPflichtWhere the order is now. Restaurants may skip statuses, see
GET /store.Werte:
"pending""confirmed""preparing""ready""completed""cancelled"created_atstring (date-time)PflichtWhen the order was placed. ISO 8601 in UTC (
Z).updated_atstring (date-time)PflichtLast change. ISO 8601 in UTC (
Z).acknowledged_atstring (date-time)Pflichtkann null seinWhen 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)Pflichtkann null seinPickup or delivery time chosen by the guest (pre-order); null means as soon as possible.
currencystringPflichtISO 4217, e.g. EUR.
amountsobjectPflichtThe amounts of the order, in cents.
Felder darin (6)
subtotalintegerPflichtSum of the items. Integer amount in the smallest currency unit (cents).
delivery_feeintegerPflichtDelivery fee. Integer amount in the smallest currency unit (cents).
service_feeintegerPflichtService fee. Integer amount in the smallest currency unit (cents).
discountintegerPflichtDiscount (stamp card), already subtracted. Integer amount in the smallest currency unit (cents).
tipintegerPflichtTip. Pass-through, not revenue. Integer amount in the smallest currency unit (cents).
totalintegerPflichtsubtotal + delivery_fee + service_fee − discount + tip. Integer amount in the smallest currency unit (cents).
taxobjectPflichtVAT 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.Felder darin (2)
includedbooleanPflichtAlways true: prices include VAT.
Werte:
truelinesTaxLine[]PflichtOne line per rate, ascending, lines without rate last. The gross amounts add up to total − tip.
Felder darin (4)
rate_bpsintegerPflichtkann null seinThe 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.
grossintegerPflichtGross amount at this rate. Integer amount in the smallest currency unit (cents).
netintegerPflichtkann null seingross − tax, in cents. null when rate_bps is null.
taxintegerPflichtkann null seinVAT contained in gross: round(gross × rate / (10000 + rate)), in cents. null when rate_bps is null.
paymentobjectPflichtHow and whether it is paid.
Felder darin (3)
methodstringPflichtonline: paid at checkout.on_site: paid at pickup, delivery or the table.Werte:
"online""on_site"statusstringPflichtpaidonce the online payment is confirmed.open: to be paid on site; it staysopen, because Flavoso does not record payments on site.Werte:
"paid""open"paid_atstring (date-time)Pflichtkann null seinWhen it was paid; null while open.
customerobjectPflichtkann null seinOnly what is needed to hand the order over (data minimisation): no e-mail, and no phone for dine-in. null when neither is known.
Felder darin (2)
namestringPflichtkann null seinThe guest's name.
phonestringPflichtkann null seinPhone for questions; null for dine-in.
deliveryobjectPflichtkann null seinThe delivery address; null unless type is delivery.
Felder darin (3)
addressstringPflichtkann null seinStreet and number.
postal_codestringPflichtkann null seinPostal code.
citystringPflichtkann null seinCity.
tableobjectPflichtkann null seinThe table of a dine-in order; null otherwise.
Felder darin (2)
idstring (uuid)PflichtThe table (
GET /tables).labelstringPflichtkann null seinThe table's name, e.g. 4.
notestringPflichtkann null seinGuest's note for the kitchen (allergies!).
itemsOrderItem[]PflichtThe lines.
Felder darin (8)
idstring (uuid)PflichtThe line.
product_idstring (uuid)Pflichtkann null seinThe dish (
GET /menu/products/{id}); null when it was deleted since.namestringPflichtName at the time of ordering.
quantityintegerPflichtHow many.
min 1
unit_priceintegerPflichtPrice of one unit including options. Integer amount in the smallest currency unit (cents).
line_totalintegerPflichtunit_price × quantity. Integer amount in the smallest currency unit (cents).
tax_rate_bpsintegerPflichtkann null seinVAT rate frozen at order time, in basis points (700 = 7 %). null when the restaurant has not set rates.
optionsobject[]PflichtThe 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.Felder darin (5)
idstring (uuid)Pflichtkann null seinThe option (
GET /menu/options/{id}); with it you find your own modifier through itsexternal_id. null for orders placed before 8 October 2026.namestringPflichtName of the option.
price_deltaintegerPflichtSurcharge of this option, per unit. Integer amount in the smallest currency unit (cents).
group_idstring (uuid)Pflichtkann null seinThe option group the option was chosen in (
GET /menu/option-groups/{id}). null for orders placed before 8 October 2026.group_namestringPflichtkann null seinName of that group at order time, e.g. Extras or Size. null for orders placed before 8 October 2026.
Fehler
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
- Recht:
orders:write- Tarif:
- jeder Tarif
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.
Parameter
| Name | Ort | Beschreibung |
|---|---|---|
idstring (uuid)Pflicht | 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 |
Antwort200
The order after the change.
objectstringPflichtAlways
order.Werte:
"order"idstring (uuid)PflichtThe order.
codestringPflichtShort code the guest sees and says at the counter, e.g. K7Q2M9.
external_idstringPflichtkann null seinYour 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.typestringPflichtHow the guest gets the order.
Werte:
"pickup""delivery""dine_in"sourcestringPflichtWhere 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).Werte:
"storefront""table""app"statusstringPflichtWhere the order is now. Restaurants may skip statuses, see
GET /store.Werte:
"pending""confirmed""preparing""ready""completed""cancelled"created_atstring (date-time)PflichtWhen the order was placed. ISO 8601 in UTC (
Z).updated_atstring (date-time)PflichtLast change. ISO 8601 in UTC (
Z).acknowledged_atstring (date-time)Pflichtkann null seinWhen 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)Pflichtkann null seinPickup or delivery time chosen by the guest (pre-order); null means as soon as possible.
currencystringPflichtISO 4217, e.g. EUR.
amountsobjectPflichtThe amounts of the order, in cents.
Felder darin (6)
subtotalintegerPflichtSum of the items. Integer amount in the smallest currency unit (cents).
delivery_feeintegerPflichtDelivery fee. Integer amount in the smallest currency unit (cents).
service_feeintegerPflichtService fee. Integer amount in the smallest currency unit (cents).
discountintegerPflichtDiscount (stamp card), already subtracted. Integer amount in the smallest currency unit (cents).
tipintegerPflichtTip. Pass-through, not revenue. Integer amount in the smallest currency unit (cents).
totalintegerPflichtsubtotal + delivery_fee + service_fee − discount + tip. Integer amount in the smallest currency unit (cents).
taxobjectPflichtVAT 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.Felder darin (2)
includedbooleanPflichtAlways true: prices include VAT.
Werte:
truelinesTaxLine[]PflichtOne line per rate, ascending, lines without rate last. The gross amounts add up to total − tip.
Felder darin (4)
rate_bpsintegerPflichtkann null seinThe 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.
grossintegerPflichtGross amount at this rate. Integer amount in the smallest currency unit (cents).
netintegerPflichtkann null seingross − tax, in cents. null when rate_bps is null.
taxintegerPflichtkann null seinVAT contained in gross: round(gross × rate / (10000 + rate)), in cents. null when rate_bps is null.
paymentobjectPflichtHow and whether it is paid.
Felder darin (3)
methodstringPflichtonline: paid at checkout.on_site: paid at pickup, delivery or the table.Werte:
"online""on_site"statusstringPflichtpaidonce the online payment is confirmed.open: to be paid on site; it staysopen, because Flavoso does not record payments on site.Werte:
"paid""open"paid_atstring (date-time)Pflichtkann null seinWhen it was paid; null while open.
customerobjectPflichtkann null seinOnly what is needed to hand the order over (data minimisation): no e-mail, and no phone for dine-in. null when neither is known.
Felder darin (2)
namestringPflichtkann null seinThe guest's name.
phonestringPflichtkann null seinPhone for questions; null for dine-in.
deliveryobjectPflichtkann null seinThe delivery address; null unless type is delivery.
Felder darin (3)
addressstringPflichtkann null seinStreet and number.
postal_codestringPflichtkann null seinPostal code.
citystringPflichtkann null seinCity.
tableobjectPflichtkann null seinThe table of a dine-in order; null otherwise.
Felder darin (2)
idstring (uuid)PflichtThe table (
GET /tables).labelstringPflichtkann null seinThe table's name, e.g. 4.
notestringPflichtkann null seinGuest's note for the kitchen (allergies!).
itemsOrderItem[]PflichtThe lines.
Felder darin (8)
idstring (uuid)PflichtThe line.
product_idstring (uuid)Pflichtkann null seinThe dish (
GET /menu/products/{id}); null when it was deleted since.namestringPflichtName at the time of ordering.
quantityintegerPflichtHow many.
min 1
unit_priceintegerPflichtPrice of one unit including options. Integer amount in the smallest currency unit (cents).
line_totalintegerPflichtunit_price × quantity. Integer amount in the smallest currency unit (cents).
tax_rate_bpsintegerPflichtkann null seinVAT rate frozen at order time, in basis points (700 = 7 %). null when the restaurant has not set rates.
optionsobject[]PflichtThe 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.Felder darin (5)
idstring (uuid)Pflichtkann null seinThe option (
GET /menu/options/{id}); with it you find your own modifier through itsexternal_id. null for orders placed before 8 October 2026.namestringPflichtName of the option.
price_deltaintegerPflichtSurcharge of this option, per unit. Integer amount in the smallest currency unit (cents).
group_idstring (uuid)Pflichtkann null seinThe option group the option was chosen in (
GET /menu/option-groups/{id}). null for orders placed before 8 October 2026.group_namestringPflichtkann null seinName of that group at order time, e.g. Extras or Size. null for orders placed before 8 October 2026.
Fehler
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
- Recht:
orders:write- Tarif:
- jeder Tarif
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.
Parameter
| Name | Ort | Beschreibung |
|---|---|---|
idstring (uuid)Pflicht | 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 |
Rumpfapplication/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
Antwort200
The order after the change.
objectstringPflichtAlways
order.Werte:
"order"idstring (uuid)PflichtThe order.
codestringPflichtShort code the guest sees and says at the counter, e.g. K7Q2M9.
external_idstringPflichtkann null seinYour 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.typestringPflichtHow the guest gets the order.
Werte:
"pickup""delivery""dine_in"sourcestringPflichtWhere 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).Werte:
"storefront""table""app"statusstringPflichtWhere the order is now. Restaurants may skip statuses, see
GET /store.Werte:
"pending""confirmed""preparing""ready""completed""cancelled"created_atstring (date-time)PflichtWhen the order was placed. ISO 8601 in UTC (
Z).updated_atstring (date-time)PflichtLast change. ISO 8601 in UTC (
Z).acknowledged_atstring (date-time)Pflichtkann null seinWhen 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)Pflichtkann null seinPickup or delivery time chosen by the guest (pre-order); null means as soon as possible.
currencystringPflichtISO 4217, e.g. EUR.
amountsobjectPflichtThe amounts of the order, in cents.
Felder darin (6)
subtotalintegerPflichtSum of the items. Integer amount in the smallest currency unit (cents).
delivery_feeintegerPflichtDelivery fee. Integer amount in the smallest currency unit (cents).
service_feeintegerPflichtService fee. Integer amount in the smallest currency unit (cents).
discountintegerPflichtDiscount (stamp card), already subtracted. Integer amount in the smallest currency unit (cents).
tipintegerPflichtTip. Pass-through, not revenue. Integer amount in the smallest currency unit (cents).
totalintegerPflichtsubtotal + delivery_fee + service_fee − discount + tip. Integer amount in the smallest currency unit (cents).
taxobjectPflichtVAT 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.Felder darin (2)
includedbooleanPflichtAlways true: prices include VAT.
Werte:
truelinesTaxLine[]PflichtOne line per rate, ascending, lines without rate last. The gross amounts add up to total − tip.
Felder darin (4)
rate_bpsintegerPflichtkann null seinThe 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.
grossintegerPflichtGross amount at this rate. Integer amount in the smallest currency unit (cents).
netintegerPflichtkann null seingross − tax, in cents. null when rate_bps is null.
taxintegerPflichtkann null seinVAT contained in gross: round(gross × rate / (10000 + rate)), in cents. null when rate_bps is null.
paymentobjectPflichtHow and whether it is paid.
Felder darin (3)
methodstringPflichtonline: paid at checkout.on_site: paid at pickup, delivery or the table.Werte:
"online""on_site"statusstringPflichtpaidonce the online payment is confirmed.open: to be paid on site; it staysopen, because Flavoso does not record payments on site.Werte:
"paid""open"paid_atstring (date-time)Pflichtkann null seinWhen it was paid; null while open.
customerobjectPflichtkann null seinOnly what is needed to hand the order over (data minimisation): no e-mail, and no phone for dine-in. null when neither is known.
Felder darin (2)
namestringPflichtkann null seinThe guest's name.
phonestringPflichtkann null seinPhone for questions; null for dine-in.
deliveryobjectPflichtkann null seinThe delivery address; null unless type is delivery.
Felder darin (3)
addressstringPflichtkann null seinStreet and number.
postal_codestringPflichtkann null seinPostal code.
citystringPflichtkann null seinCity.
tableobjectPflichtkann null seinThe table of a dine-in order; null otherwise.
Felder darin (2)
idstring (uuid)PflichtThe table (
GET /tables).labelstringPflichtkann null seinThe table's name, e.g. 4.
notestringPflichtkann null seinGuest's note for the kitchen (allergies!).
itemsOrderItem[]PflichtThe lines.
Felder darin (8)
idstring (uuid)PflichtThe line.
product_idstring (uuid)Pflichtkann null seinThe dish (
GET /menu/products/{id}); null when it was deleted since.namestringPflichtName at the time of ordering.
quantityintegerPflichtHow many.
min 1
unit_priceintegerPflichtPrice of one unit including options. Integer amount in the smallest currency unit (cents).
line_totalintegerPflichtunit_price × quantity. Integer amount in the smallest currency unit (cents).
tax_rate_bpsintegerPflichtkann null seinVAT rate frozen at order time, in basis points (700 = 7 %). null when the restaurant has not set rates.
optionsobject[]PflichtThe 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.Felder darin (5)
idstring (uuid)Pflichtkann null seinThe option (
GET /menu/options/{id}); with it you find your own modifier through itsexternal_id. null for orders placed before 8 October 2026.namestringPflichtName of the option.
price_deltaintegerPflichtSurcharge of this option, per unit. Integer amount in the smallest currency unit (cents).
group_idstring (uuid)Pflichtkann null seinThe option group the option was chosen in (
GET /menu/option-groups/{id}). null for orders placed before 8 October 2026.group_namestringPflichtkann null seinName of that group at order time, e.g. Extras or Size. null for orders placed before 8 October 2026.
Fehler
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
- Recht:
orders:write- Tarif:
- jeder Tarif
Cancels an order from any open status. Guest and staff are notified, the order leaves the kitchen display.
Parameter
| Name | Ort | Beschreibung |
|---|---|---|
idstring (uuid)Pflicht | 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 |
Rumpfapplication/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
Antwort200
The order after the change.
objectstringPflichtAlways
order.Werte:
"order"idstring (uuid)PflichtThe order.
codestringPflichtShort code the guest sees and says at the counter, e.g. K7Q2M9.
external_idstringPflichtkann null seinYour 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.typestringPflichtHow the guest gets the order.
Werte:
"pickup""delivery""dine_in"sourcestringPflichtWhere 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).Werte:
"storefront""table""app"statusstringPflichtWhere the order is now. Restaurants may skip statuses, see
GET /store.Werte:
"pending""confirmed""preparing""ready""completed""cancelled"created_atstring (date-time)PflichtWhen the order was placed. ISO 8601 in UTC (
Z).updated_atstring (date-time)PflichtLast change. ISO 8601 in UTC (
Z).acknowledged_atstring (date-time)Pflichtkann null seinWhen 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)Pflichtkann null seinPickup or delivery time chosen by the guest (pre-order); null means as soon as possible.
currencystringPflichtISO 4217, e.g. EUR.
amountsobjectPflichtThe amounts of the order, in cents.
Felder darin (6)
subtotalintegerPflichtSum of the items. Integer amount in the smallest currency unit (cents).
delivery_feeintegerPflichtDelivery fee. Integer amount in the smallest currency unit (cents).
service_feeintegerPflichtService fee. Integer amount in the smallest currency unit (cents).
discountintegerPflichtDiscount (stamp card), already subtracted. Integer amount in the smallest currency unit (cents).
tipintegerPflichtTip. Pass-through, not revenue. Integer amount in the smallest currency unit (cents).
totalintegerPflichtsubtotal + delivery_fee + service_fee − discount + tip. Integer amount in the smallest currency unit (cents).
taxobjectPflichtVAT 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.Felder darin (2)
includedbooleanPflichtAlways true: prices include VAT.
Werte:
truelinesTaxLine[]PflichtOne line per rate, ascending, lines without rate last. The gross amounts add up to total − tip.
Felder darin (4)
rate_bpsintegerPflichtkann null seinThe 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.
grossintegerPflichtGross amount at this rate. Integer amount in the smallest currency unit (cents).
netintegerPflichtkann null seingross − tax, in cents. null when rate_bps is null.
taxintegerPflichtkann null seinVAT contained in gross: round(gross × rate / (10000 + rate)), in cents. null when rate_bps is null.
paymentobjectPflichtHow and whether it is paid.
Felder darin (3)
methodstringPflichtonline: paid at checkout.on_site: paid at pickup, delivery or the table.Werte:
"online""on_site"statusstringPflichtpaidonce the online payment is confirmed.open: to be paid on site; it staysopen, because Flavoso does not record payments on site.Werte:
"paid""open"paid_atstring (date-time)Pflichtkann null seinWhen it was paid; null while open.
customerobjectPflichtkann null seinOnly what is needed to hand the order over (data minimisation): no e-mail, and no phone for dine-in. null when neither is known.
Felder darin (2)
namestringPflichtkann null seinThe guest's name.
phonestringPflichtkann null seinPhone for questions; null for dine-in.
deliveryobjectPflichtkann null seinThe delivery address; null unless type is delivery.
Felder darin (3)
addressstringPflichtkann null seinStreet and number.
postal_codestringPflichtkann null seinPostal code.
citystringPflichtkann null seinCity.
tableobjectPflichtkann null seinThe table of a dine-in order; null otherwise.
Felder darin (2)
idstring (uuid)PflichtThe table (
GET /tables).labelstringPflichtkann null seinThe table's name, e.g. 4.
notestringPflichtkann null seinGuest's note for the kitchen (allergies!).
itemsOrderItem[]PflichtThe lines.
Felder darin (8)
idstring (uuid)PflichtThe line.
product_idstring (uuid)Pflichtkann null seinThe dish (
GET /menu/products/{id}); null when it was deleted since.namestringPflichtName at the time of ordering.
quantityintegerPflichtHow many.
min 1
unit_priceintegerPflichtPrice of one unit including options. Integer amount in the smallest currency unit (cents).
line_totalintegerPflichtunit_price × quantity. Integer amount in the smallest currency unit (cents).
tax_rate_bpsintegerPflichtkann null seinVAT rate frozen at order time, in basis points (700 = 7 %). null when the restaurant has not set rates.
optionsobject[]PflichtThe 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.Felder darin (5)
idstring (uuid)Pflichtkann null seinThe option (
GET /menu/options/{id}); with it you find your own modifier through itsexternal_id. null for orders placed before 8 October 2026.namestringPflichtName of the option.
price_deltaintegerPflichtSurcharge of this option, per unit. Integer amount in the smallest currency unit (cents).
group_idstring (uuid)Pflichtkann null seinThe option group the option was chosen in (
GET /menu/option-groups/{id}). null for orders placed before 8 October 2026.group_namestringPflichtkann null seinName of that group at order time, e.g. Extras or Size. null for orders placed before 8 October 2026.
Fehler
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
- Recht:
orders:write- Tarif:
- jeder Tarif
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.
Parameter
| Name | Ort | Beschreibung |
|---|---|---|
idstring (uuid)Pflicht | 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 |
Rumpfapplication/json
statusstringPflichtThe status to move to. Use /cancel to cancel.
Werte:
"confirmed""preparing""ready""completed"
Antwort200
The order after the change.
objectstringPflichtAlways
order.Werte:
"order"idstring (uuid)PflichtThe order.
codestringPflichtShort code the guest sees and says at the counter, e.g. K7Q2M9.
external_idstringPflichtkann null seinYour 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.typestringPflichtHow the guest gets the order.
Werte:
"pickup""delivery""dine_in"sourcestringPflichtWhere 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).Werte:
"storefront""table""app"statusstringPflichtWhere the order is now. Restaurants may skip statuses, see
GET /store.Werte:
"pending""confirmed""preparing""ready""completed""cancelled"created_atstring (date-time)PflichtWhen the order was placed. ISO 8601 in UTC (
Z).updated_atstring (date-time)PflichtLast change. ISO 8601 in UTC (
Z).acknowledged_atstring (date-time)Pflichtkann null seinWhen 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)Pflichtkann null seinPickup or delivery time chosen by the guest (pre-order); null means as soon as possible.
currencystringPflichtISO 4217, e.g. EUR.
amountsobjectPflichtThe amounts of the order, in cents.
Felder darin (6)
subtotalintegerPflichtSum of the items. Integer amount in the smallest currency unit (cents).
delivery_feeintegerPflichtDelivery fee. Integer amount in the smallest currency unit (cents).
service_feeintegerPflichtService fee. Integer amount in the smallest currency unit (cents).
discountintegerPflichtDiscount (stamp card), already subtracted. Integer amount in the smallest currency unit (cents).
tipintegerPflichtTip. Pass-through, not revenue. Integer amount in the smallest currency unit (cents).
totalintegerPflichtsubtotal + delivery_fee + service_fee − discount + tip. Integer amount in the smallest currency unit (cents).
taxobjectPflichtVAT 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.Felder darin (2)
includedbooleanPflichtAlways true: prices include VAT.
Werte:
truelinesTaxLine[]PflichtOne line per rate, ascending, lines without rate last. The gross amounts add up to total − tip.
Felder darin (4)
rate_bpsintegerPflichtkann null seinThe 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.
grossintegerPflichtGross amount at this rate. Integer amount in the smallest currency unit (cents).
netintegerPflichtkann null seingross − tax, in cents. null when rate_bps is null.
taxintegerPflichtkann null seinVAT contained in gross: round(gross × rate / (10000 + rate)), in cents. null when rate_bps is null.
paymentobjectPflichtHow and whether it is paid.
Felder darin (3)
methodstringPflichtonline: paid at checkout.on_site: paid at pickup, delivery or the table.Werte:
"online""on_site"statusstringPflichtpaidonce the online payment is confirmed.open: to be paid on site; it staysopen, because Flavoso does not record payments on site.Werte:
"paid""open"paid_atstring (date-time)Pflichtkann null seinWhen it was paid; null while open.
customerobjectPflichtkann null seinOnly what is needed to hand the order over (data minimisation): no e-mail, and no phone for dine-in. null when neither is known.
Felder darin (2)
namestringPflichtkann null seinThe guest's name.
phonestringPflichtkann null seinPhone for questions; null for dine-in.
deliveryobjectPflichtkann null seinThe delivery address; null unless type is delivery.
Felder darin (3)
addressstringPflichtkann null seinStreet and number.
postal_codestringPflichtkann null seinPostal code.
citystringPflichtkann null seinCity.
tableobjectPflichtkann null seinThe table of a dine-in order; null otherwise.
Felder darin (2)
idstring (uuid)PflichtThe table (
GET /tables).labelstringPflichtkann null seinThe table's name, e.g. 4.
notestringPflichtkann null seinGuest's note for the kitchen (allergies!).
itemsOrderItem[]PflichtThe lines.
Felder darin (8)
idstring (uuid)PflichtThe line.
product_idstring (uuid)Pflichtkann null seinThe dish (
GET /menu/products/{id}); null when it was deleted since.namestringPflichtName at the time of ordering.
quantityintegerPflichtHow many.
min 1
unit_priceintegerPflichtPrice of one unit including options. Integer amount in the smallest currency unit (cents).
line_totalintegerPflichtunit_price × quantity. Integer amount in the smallest currency unit (cents).
tax_rate_bpsintegerPflichtkann null seinVAT rate frozen at order time, in basis points (700 = 7 %). null when the restaurant has not set rates.
optionsobject[]PflichtThe 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.Felder darin (5)
idstring (uuid)Pflichtkann null seinThe option (
GET /menu/options/{id}); with it you find your own modifier through itsexternal_id. null for orders placed before 8 October 2026.namestringPflichtName of the option.
price_deltaintegerPflichtSurcharge of this option, per unit. Integer amount in the smallest currency unit (cents).
group_idstring (uuid)Pflichtkann null seinThe option group the option was chosen in (
GET /menu/option-groups/{id}). null for orders placed before 8 October 2026.group_namestringPflichtkann null seinName of that group at order time, e.g. Extras or Size. null for orders placed before 8 October 2026.
Fehler
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
- Recht:
orders:write- Tarif:
- jeder Tarif
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.
Parameter
| Name | Ort | Beschreibung |
|---|---|---|
idstring (uuid)Pflicht | 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 |
Rumpfapplication/json
external_idstringkann null seinYour 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
Antwort200
The order with your external_id and acknowledged_at.
objectstringPflichtAlways
order.Werte:
"order"idstring (uuid)PflichtThe order.
codestringPflichtShort code the guest sees and says at the counter, e.g. K7Q2M9.
external_idstringPflichtkann null seinYour 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.typestringPflichtHow the guest gets the order.
Werte:
"pickup""delivery""dine_in"sourcestringPflichtWhere 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).Werte:
"storefront""table""app"statusstringPflichtWhere the order is now. Restaurants may skip statuses, see
GET /store.Werte:
"pending""confirmed""preparing""ready""completed""cancelled"created_atstring (date-time)PflichtWhen the order was placed. ISO 8601 in UTC (
Z).updated_atstring (date-time)PflichtLast change. ISO 8601 in UTC (
Z).acknowledged_atstring (date-time)Pflichtkann null seinWhen 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)Pflichtkann null seinPickup or delivery time chosen by the guest (pre-order); null means as soon as possible.
currencystringPflichtISO 4217, e.g. EUR.
amountsobjectPflichtThe amounts of the order, in cents.
Felder darin (6)
subtotalintegerPflichtSum of the items. Integer amount in the smallest currency unit (cents).
delivery_feeintegerPflichtDelivery fee. Integer amount in the smallest currency unit (cents).
service_feeintegerPflichtService fee. Integer amount in the smallest currency unit (cents).
discountintegerPflichtDiscount (stamp card), already subtracted. Integer amount in the smallest currency unit (cents).
tipintegerPflichtTip. Pass-through, not revenue. Integer amount in the smallest currency unit (cents).
totalintegerPflichtsubtotal + delivery_fee + service_fee − discount + tip. Integer amount in the smallest currency unit (cents).
taxobjectPflichtVAT 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.Felder darin (2)
includedbooleanPflichtAlways true: prices include VAT.
Werte:
truelinesTaxLine[]PflichtOne line per rate, ascending, lines without rate last. The gross amounts add up to total − tip.
Felder darin (4)
rate_bpsintegerPflichtkann null seinThe 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.
grossintegerPflichtGross amount at this rate. Integer amount in the smallest currency unit (cents).
netintegerPflichtkann null seingross − tax, in cents. null when rate_bps is null.
taxintegerPflichtkann null seinVAT contained in gross: round(gross × rate / (10000 + rate)), in cents. null when rate_bps is null.
paymentobjectPflichtHow and whether it is paid.
Felder darin (3)
methodstringPflichtonline: paid at checkout.on_site: paid at pickup, delivery or the table.Werte:
"online""on_site"statusstringPflichtpaidonce the online payment is confirmed.open: to be paid on site; it staysopen, because Flavoso does not record payments on site.Werte:
"paid""open"paid_atstring (date-time)Pflichtkann null seinWhen it was paid; null while open.
customerobjectPflichtkann null seinOnly what is needed to hand the order over (data minimisation): no e-mail, and no phone for dine-in. null when neither is known.
Felder darin (2)
namestringPflichtkann null seinThe guest's name.
phonestringPflichtkann null seinPhone for questions; null for dine-in.
deliveryobjectPflichtkann null seinThe delivery address; null unless type is delivery.
Felder darin (3)
addressstringPflichtkann null seinStreet and number.
postal_codestringPflichtkann null seinPostal code.
citystringPflichtkann null seinCity.
tableobjectPflichtkann null seinThe table of a dine-in order; null otherwise.
Felder darin (2)
idstring (uuid)PflichtThe table (
GET /tables).labelstringPflichtkann null seinThe table's name, e.g. 4.
notestringPflichtkann null seinGuest's note for the kitchen (allergies!).
itemsOrderItem[]PflichtThe lines.
Felder darin (8)
idstring (uuid)PflichtThe line.
product_idstring (uuid)Pflichtkann null seinThe dish (
GET /menu/products/{id}); null when it was deleted since.namestringPflichtName at the time of ordering.
quantityintegerPflichtHow many.
min 1
unit_priceintegerPflichtPrice of one unit including options. Integer amount in the smallest currency unit (cents).
line_totalintegerPflichtunit_price × quantity. Integer amount in the smallest currency unit (cents).
tax_rate_bpsintegerPflichtkann null seinVAT rate frozen at order time, in basis points (700 = 7 %). null when the restaurant has not set rates.
optionsobject[]PflichtThe 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.Felder darin (5)
idstring (uuid)Pflichtkann null seinThe option (
GET /menu/options/{id}); with it you find your own modifier through itsexternal_id. null for orders placed before 8 October 2026.namestringPflichtName of the option.
price_deltaintegerPflichtSurcharge of this option, per unit. Integer amount in the smallest currency unit (cents).
group_idstring (uuid)Pflichtkann null seinThe option group the option was chosen in (
GET /menu/option-groups/{id}). null for orders placed before 8 October 2026.group_namestringPflichtkann null seinName of that group at order time, e.g. Extras or Size. null for orders placed before 8 October 2026.
Fehler
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": []
}
]
}Etwas unklar geblieben? Schreib an support@flavoso.com und nenne die Kennung aus X-Request-Id. Damit finden wir deine Anfrage im Protokoll.