Order lifecycle
Create Orders
Preview Order
Validate cart and calculate totals without persisting data.
POST/orders/previewPreview Order
Validate cart and calculate totals without persisting data.
Request Body
{
"restaurantId": 2285,
"channelId": 2,
"consumptionMode": "MODE_DELIVERY",
"menuId": 24194,
"cart": [
{
"productId": 1670891,
"quantity": 1,
"steps": []
}
],
"addressId": 12345,
"expectedAt": "2025-12-03T19:00:00.000Z"
}Request Body Properties
Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.
| Property | Type | Example | Description |
|---|---|---|---|
| restaurantId | integer | 2285 | Identifier of the restaurant. |
| channelId | integer | 2 | Identifier of the associated channel. |
| consumptionMode | string | "MODE_DELIVERY" | The consumption mode value. |
| menuId | integer | 24194 | Identifier of the menu. |
| cart | array | […] | List of cart entries. |
| cart[] | object | {…} | Object containing cart fields. |
| cart[].productId | integer | 1670891 | Identifier of the product. |
| cart[].quantity | integer | 1 | The quantity value. |
| cart[].steps | array | [] | List of steps entries. |
| addressId | integer | 12345 | Identifier of the associated address. |
| expectedAt | string | "2025-12-03T19:00:00.000Z" | Date or timestamp for expected. |
Response
{
"status": 200,
"code": "order_parameters_validated",
"message": "...",
"data": {
"totalPriceWithTaxIncluded": 1500,
"valid": true,
"deliveryArea": {
"id": 1,
"name": "Zone A"
}
}
}Response Properties
Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.
| Property | Type | Example | Description |
|---|---|---|---|
| status | integer | 200 | HTTP status code returned by the API. |
| code | string | "order_parameters_validated" | Machine-readable application code for the result. |
| message | string | "..." | Human-readable result message. Do not use this value for program logic. |
| data | object | {…} | Endpoint-specific response payload. |
| data.totalPriceWithTaxIncluded | integer | 1500 | The total price with tax included value. |
| data.valid | boolean | true | The valid value. |
| data.deliveryArea | object | {…} | Object containing delivery area fields. |
| data.deliveryArea.id | integer | 1 | The id value. |
| data.deliveryArea.name | string | "Zone A" | The name value. |
Payload Schema
| Field | Type | Required | Description |
|---|---|---|---|
| restaurantId | number | Yes | Target restaurant. |
| channelId | number | Yes | 1=KIOSK, 2=WEB. |
| consumptionMode | string | Yes | MODE_DELIVERY, MODE_TAKE_AWAY, MODE_SIT_IN, MODE_DRIVE. |
| menuId | number | Yes | Catalog context. |
| cartId | string | No | Optional. |
| cart | Product[] | Yes | Items. |
| customerId | number | No | Optional. |
| willPayLater | boolean | No | Payment is settled on site. payments must then be omitted or empty. |
| payments | Payment[] | No | Omit it (or send []) when willPayLater is true. |
| expectedAt | ISO datetime | No | Optional. |
| expectedAtEnd | ISO datetime | No | Optional, must be >= expectedAt. |
| royaltyDiscountValue | number | No | Optional. |
| promocode | string | No | Optional. |
| comment | string | No | Optional. |
| userName | string | Conditional | Min 1 if KIOSK, else min 2. |
| addressId | number | Conditional | Required for delivery. |
| applyDate | ISO datetime | No | Optional. |
| tableName | string | No | Optional. |
| formulaDetection | boolean | No | Optional. |
| loyalty | object|null | No | Optional. |
Detailed Schemas
Product Object
| Field | Type | Required | Description |
|---|---|---|---|
| productId | string|number | Yes | ID. |
| productCartId | string | No | Optional. |
| quantity | number | Yes | > 0. |
| imageUrl | string | No | Optional. |
| customPrice | number | No | Optional. |
| customLabel | string | No | Optional. |
| steps | Step[] | Yes | Options. |
| crossSelling | object | No | { stepId: number, productId: number } |
Step Object
| Field | Type | Required | Description |
|---|---|---|---|
| stepId | number | Yes | ID. |
| products | Product[] | Yes | Selected options. |
| type | number | No | Optional. |
Payment Object
| Field | Type | Required | Description |
|---|---|---|---|
| paymentMethodId | number | Yes | ID. |
| amount | number | No | >= 0. |
| quantity | number | Yes | > 0. |
| currency | string | No | Optional. |
| metadata | string | No | JSON-encoded string. Required for Stripe payments: {"stripePaymentMethodId":"pm_..."} or {"cardId":42} - see the Stripe Payments guide. |
| isExternal | boolean | No | Optional. |
| paymentMethodCode | string | No | Optional. |
Business Rules
MODE_DELIVERY
- addressId is required.
- area is NOT expected in the body. It is calculated server-side from the address.
- If no active zone covers the address:
no_area_for_address(403). - If zone minimum order amount is not reached:
price_too_low_for_delivery(403).
MODE_TAKE_AWAY / MODE_SIT_IN / MODE_DRIVE
addressId must be absent.
Payments
- Mixing payments with and without defined amounts is forbidden.
- If the sum of payments does not match the total:
wrong_payments_amount.
willPayLater
- Nothing is paid at preview time:
paymentsmust be either omitted or an empty array. Both spellings are accepted and mean the same thing. - Sending
willPayLater: truetogether with a non-emptypaymentsarray is refused withinvalid_order_payload(400); the offendingwillPayLater/paymentsvalues are echoed inextraData.
Deligo
If expectedAt is > 3 days in the past and outside the current month: expected_at_too_old (400).
Error Codes
Examples
Error: No Delivery Area
{
"status": 403,
"code": "no_area_for_address",
"message": "Aucune zone de livraison ne couvre cette adresse."
}Create Order
Once the cart has been validated via the /orders/preview endpoint, use this endpoint to finalize and persist the transaction.
Workflow: The body for Create Order is largely identical to Preview Order, but introduces mandatory fields for payment and timestamps.
Create Endpoint
Idempotency Required:You must provide a unique idempotency-key in the header to prevent duplicate orders in case of network retries.
POST/ordersCreate Order
Creates an order. Supports recursive product steps, multiple payment methods, and loyalty rewards.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| idempotency-key | string (header) | Yes | Unique UUID to prevent duplicate creations. |
| io-locale | string (header) | No | Language code (e.g. fr-FR). |
Request Body
{
"restaurantId": 2285,
"channelId": 2,
"consumptionMode": "MODE_TAKE_AWAY",
"menuId": 24194,
"cart": [
{
"productId": 1670891,
"quantity": 1,
"steps": [
{
"stepId": 501,
"products": [
{
"productId": 9901,
"quantity": 1,
"steps": []
}
]
}
]
}
],
"customerId": 1008881,
"expectedAt": "2025-12-03T15:53:44.311Z",
"payments": [
{
"paymentMethodId": 22521,
"amount": 273,
"quantity": 1,
"paymentMethodCode": "EWallet"
}
],
"comment": "No cutlery please"
}Request Body Properties
Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.
| Property | Type | Example | Description |
|---|---|---|---|
| restaurantId | integer | 2285 | Identifier of the restaurant. |
| channelId | integer | 2 | Identifier of the associated channel. |
| consumptionMode | string | "MODE_TAKE_AWAY" | The consumption mode value. |
| menuId | integer | 24194 | Identifier of the menu. |
| cart | array | […] | List of cart entries. |
| cart[] | object | {…} | Object containing cart fields. |
| cart[].productId | integer | 1670891 | Identifier of the product. |
| cart[].quantity | integer | 1 | The quantity value. |
| cart[].steps | array | […] | List of steps entries. |
| cart[].steps[] | object | {…} | Object containing steps fields. |
| cart[].steps[].stepId | integer | 501 | Identifier of the associated step. |
| cart[].steps[].products | array | […] | List of products entries. |
| cart[].steps[].products[] | object | {…} | Object containing products fields. |
| cart[].steps[].products[].productId | integer | 9901 | Identifier of the product. |
| cart[].steps[].products[].quantity | integer | 1 | The quantity value. |
| cart[].steps[].products[].steps | array | [] | List of steps entries. |
| customerId | integer | 1008881 | Identifier of the customer. |
| expectedAt | string | "2025-12-03T15:53:44.311Z" | Date or timestamp for expected. |
| payments | array | […] | List of payments entries. |
| payments[] | object | {…} | Object containing payments fields. |
| payments[].paymentMethodId | integer | 22521 | Identifier of the associated payment method. |
| payments[].amount | integer | 273 | The amount value. |
| payments[].quantity | integer | 1 | The quantity value. |
| payments[].paymentMethodCode | string | "EWallet" | The payment method code value. |
| comment | string | "No cutlery please" | The comment value. |
Response
{
"status": 200,
"code": "order_created",
"message": "Your order was successfully created.",
"data": {
"orderId": 1927055,
"brandId": 2285,
"restaurantId": 2285,
"channelId": 2,
"menuId": 24194,
"ticketNumber": "1747_2285_2025-12-03_2",
"mainStatus": "VALIDATED",
"paymentStatus": "PAID",
"consommationMode": 2,
"ttcTotalPrice": 273,
"vatTotalPrice": 25,
"currency": "EUR",
"expectedDate": "2025-12-03T15:53:44.000Z",
"created_at": "2025-12-03T15:50:00.000Z",
"updated_at": "2025-12-03T15:50:00.000Z",
"userName": "Alice",
"metadata": null,
"orderUuid": "c4d2261e-2779-4eb6-beb0-cb41235c751e"
}
}Response Properties
Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.
| Property | Type | Example | Description |
|---|---|---|---|
| status | integer | 200 | HTTP status code returned by the API. |
| code | string | "order_created" | Machine-readable application code for the result. |
| message | string | "Your order was successfully created." | Human-readable result message. Do not use this value for program logic. |
| data | object | {…} | Endpoint-specific response payload. |
| data.orderId | integer | 1927055 | Identifier of the order. |
| data.brandId | integer | 2285 | Identifier of the brand. |
| data.restaurantId | integer | 2285 | Identifier of the restaurant. |
| data.channelId | integer | 2 | Identifier of the associated channel. |
| data.menuId | integer | 24194 | Identifier of the menu. |
| data.ticketNumber | string | "1747_2285_2025-12-03_2" | The ticket number value. |
| data.mainStatus | string | "VALIDATED" | The main status value. |
| data.paymentStatus | string | "PAID" | The payment status value. |
| data.consommationMode | integer | 2 | The consommation mode value. |
| data.ttcTotalPrice | integer | 273 | The ttc total price value. |
| data.vatTotalPrice | integer | 25 | The vat total price value. |
| data.currency | string | "EUR" | ISO 4217 currency code. |
| data.expectedDate | string | "2025-12-03T15:53:44.000Z" | Date or timestamp for expected. |
| data.created_at | string | "2025-12-03T15:50:00.000Z" | Timestamp when this resource was created. |
| data.updated_at | string | "2025-12-03T15:50:00.000Z" | Timestamp when this resource was last updated. |
| data.userName | string | "Alice" | The user name value. |
| data.metadata | null | null | Additional metadata supplied with the response. |
| data.orderUuid | string | "c4d2261e-2779-4eb6-beb0-cb41235c751e" | The order uuid value. |
Sit-in orders on a table
An order is added to the shared bill of a physical table when the three conditions below hold together. This is the only combination that triggers the table injection; a Sit-in order without tableId, or with a payment attached, is a regular order.
consumptionModeisMODE_SIT_IN;tableIdis the UUID of the table;willPayLateristrue(the bill is settled at the point of sale later, sopaymentsis sent as an empty array, since it is a required field on this endpoint).
The table must belong to the restaurant. tableId is checked against the table layout attached to the restaurant's master POS device, the layout that is published to the point of sale. A table that does not exist, or that belongs to another layout or another restaurant, is refused with table_not_found (404) and no order is created. Retrying the same payload cannot succeed: correct the tableId first.
A restaurant with no master POS device does not operate table service, so no tableId is orderable there.
{
"status": 404,
"code": "table_not_found",
"message": "No table was found for this identifier in this restaurant.",
"extraData": {
"restaurantId": 2285,
"tableId": "11112222-3333-4444-5555-666677778888"
}
}Error responses
A failure raised while the order is being persisted is returned with its own status and code; table_not_found (404) above is one such case. A 4xx means the order was rolled back and does not exist. The one exception is restaurant_offline (503) on a table order, described below.
- The generic
create_order_max_retries_reached(409, "please try again") is no longer returned. Failures that used to be reported under that code now surface with their real code, so a deterministic refusal is no longer indistinguishable from a transient fault. Do not branch oncreate_order_max_retries_reached; branch on the returnedcode. - Retry only on
5xxresponses and network timeouts, reusing the sameidempotency-key. A4xxis a refusal of the payload and will be refused again identically. - A failure to notify the point of sale never costs a regular order: it is committed and reconciled with the POS afterwards, and the call still answers
200with the created order. - A table order is different, because it is confirmed by the restaurant point of sale inside the request. When that point of sale does not answer, the call returns
restaurant_offline(503): nothing was added to the table bill and nothing will be, so the order is not served. An order row is written and left in a non servable state for audit; it is never fulfilled and never charged. Present this to the guest as "the restaurant is unreachable, try again", not as a failed order they might already have been served. - After a
restaurant_offlineon a table order, retry with a newidempotency-key. Reusing the previous one returns the earlier, non servable order as a success instead of placing a new one.
Request Payload
| Field | Validation | Description |
|---|---|---|
| restaurantId | Required | Integer > 0. Target restaurant. |
| channelId | Required | 1 (KIOSK), 2 (WEB). |
| consumptionMode | Required | Enum (e.g. MODE_TAKE_AWAY). |
| menuId | Required | Integer > 0. Catalog context. |
| cart | Required | Array of Products (see Preview). |
| payments | Required | Array of PaymentSchema (see below). |
| expectedAt | Required | ISO 8601 Date. Pickup time. |
| customerId | Optional | Integer > 0. Linked customer account. |
| cartId | Optional | String. Reference to a saved cart. |
| willPayLater | Optional | Boolean. If true, payment is on site. |
| expectedAtEnd | Optional | ISO Date. Must be >= expectedAt. |
| royaltyDiscountValue | Optional | Number. Amount covered by loyalty points. |
| promocode | Optional | String. Coupon code. |
| comment | Optional | String (allows empty). Kitchen notes. |
| userName | Conditional | If KIOSK: Opt, min 1 char. Else: Opt, min 2 chars. |
| addressId | Optional | Integer > 0. Delivery address ID. |
| applyDate | Optional | ISO Date. Logic application date. |
| tableName | Optional | String. For Sit-in mode. Free text, not unique per room. |
| tableId | Optional | String (UUID). Identifier of the physical table, for Sit-in mode. Required to have the order injected into the shared bill of that table (see Sit-in orders on a table above). |
| metadata | Optional | JSON-encoded string. Arbitrary integration data, persisted as-is on the order and returned by the order read endpoints. It must parse as valid JSON, otherwise the order is rejected with 400 / order_metadata_invalid; send a JSON object, not an array or a scalar. kioskPaymentState is a reserved key owned by the platform: on KIOSK orders (channelId: 1) any value you send under that key is overwritten or removed - see the Kiosk payment state section below. All your other keys are preserved untouched. |
| formulaDetection | Optional | Boolean. |
| loyalty | Optional | Object. See Loyalty Schema below. |
Detailed Schemas
Loyalty Object
| Field | Type | Required | Description |
|---|---|---|---|
| memberId | String | Yes | External ID of the loyalty member. |
| selectedRewards | Array<Object> | No | { id: string, selectedProductId?: number } |
| usedPromocodes | Array<Object> | No | { id: string, code: string } |
| usedPointsValue | Integer | No | Amount of points to burn. |
| shouldApplyDeals | Boolean | No | Auto-apply best deals. |
Payment Object
| Field | Type | Required | Description |
|---|---|---|---|
| paymentMethodId | Integer | Yes | ID of the payment method (from configuration). |
| amount | Integer | Yes | Amount in cents. |
| quantity | Integer | Yes | Usually 1. |
| paymentMethodCode | String | No | See Enum below. |
| isExternal | Boolean | No | Flag for external payment processors. |
PaymentMethodCode Enum
Paying with Stripe
- The payment
metadatamust be a JSON-encoded string containing{"stripePaymentMethodId":"pm_..."}(one-shot card) or{"cardId":42}(saved card, authenticated customer only); otherwise the API returnsstripe_payment_metadata_invalid(400). - If 3-D Secure is required, the response is a
200with coderequired_actionand arequiredActionobject carrying thepayment_intent_client_secret; complete the challenge client-side, then callPOST /orders/confirmbelow. - See the Stripe Payments guide for the full flow (platform publishable key, tokenization, saved cards, SCA).
Kiosk payment state (reserved metadata)
A kiosk order placed with willPayLater: true is a "pay at the counter" order: the guest orders on the kiosk but settles at the counter. For those orders the API writes the reserved key kioskPaymentState inside the order metadata, so a consumer can tell that the guest has not paid at the kiosk even when the sale is already represented as paid for reporting.
| Order | Resulting metadata.kioskPaymentState |
|---|---|
channelId: 1 (KIOSK), willPayLater: true and an amount left to pay > 0 | Set by the API to "NOT_PAID_AT_KIOSK", replacing any value sent by the client. |
| Any other KIOSK order (paid at the kiosk, free order, negative/deposit-refund order) | Absent. A value sent by the client under that key is removed. |
Non-KIOSK order (channelId: 2 WEB, vending machine) | The metadata string is stored exactly as sent, this key included. |
Which creation paths enforce the key: POST /orders and POST /orders/bulk share the same order-creation code, so a KIOSK-channel order sent in a bulk batch also has a client-provided kioskPaymentState removed from its metadata object. Bulk payloads carry no willPayLater field, so the key is never set on that path. Multi-restaurant orders (POST /multi-orders) use a different creation path and their metadata is left untouched.
Only that one key is platform-owned: every other property of your metadata object is preserved. That merge needs an object: when the metadata of an eligible kiosk order is valid JSON of another shape (an array, a number, a bare string), the API replaces the whole value with {"kioskPaymentState":"NOT_PAID_AT_KIOSK"} instead of merging into it. Response variant for a kiosk pay-at-counter order - same 200 / order_created envelope as the main example above, with the reserved key added to metadata:
{
"status": 200,
"code": "order_created",
"message": "Your order was successfully created.",
"data": {
"orderId": 1927056,
"restaurantId": 2285,
"channelId": 1,
"ticketNumber": "1748_2285_2025-12-03_1",
"paymentStatus": null,
"ttcTotalPrice": 1350,
"metadata": "{\"kioskPaymentState\":\"NOT_PAID_AT_KIOSK\"}",
"orderUuid": "9f3b0f0e-6f0a-4c0b-9a4c-9e4a1d3f8b21"
}
}Do not read the payment status alone. At creation, a pay-at-counter order has a paymentStatus of null when settlement is deferred to a POS receiving kiosk orders, as in the example above. Without such a POS, the counter sale is recorded immediately through a synthetic ExternalPayment: the POST /orders response contains the numeric value 1 (internally PAYMENT_OK), while order read endpoints and webhooks report status: "PAID". A deferred order can also become paid when the POS later settles it. In every case, metadata.kioskPaymentState keeps the original payment intent and still reads "NOT_PAID_AT_KIOSK". Use the reserved key, not the accounting status, to know whether the guest actually paid at the kiosk.
Two properties of the key matter when you store or replay orders:
- It is written once, at order creation, and never updated. It records where the guest was expected to pay, not whether the money has been collected. An order settled at the counter afterwards still reads
"NOT_PAID_AT_KIOSK". "NOT_PAID_AT_KIOSK"is the only value the API ever writes. Treat the key as absent-or-"NOT_PAID_AT_KIOSK", and do not read its absence as a payment confirmation: it is also absent on free orders, on deposit-refund orders and on every non-kiosk channel.
Where to read it afterwards - the key lives inside metadata, so only the endpoints that load that field expose it:
| Endpoint | metadata |
|---|---|
| POST /orders | Returned, already carrying the reserved key. |
| GET /v1/orders | Returned on each listed order. |
| GET /v1/orders/{orderId} | Returned. |
| GET /v1/orders/uuid/{orderUuid} | Returned. Anonymous lookup is supported for WEB orders only; authenticated callers can use it for kiosk orders. |
| GET /v1/orders/search | Always null. The lightweight search payload does not load the field, so an order carrying the reserved key still reads null here. Do not conclude from that search result that the guest paid at the kiosk. |
| orders.paid / orders.cancelled webhooks | Returned in the OmnichannelOrder payload. |
Confirm Payment
After creating an order that requires a payment action (e.g. Stripe 3D-Secure), use these endpoints to confirm the payment and finalize the order.
POST/orders/confirmConfirm Stripe Payment
Confirms a Stripe payment intent for a previously created order. This finalizes the transaction after 3D-Secure or other Stripe authentication flows. paymentIntentId is the intentId returned in the requiredAction object of the create response. If the intent still requires an action, the API returns a 400 stripe_still_requires_action with the client_secret in extraData so the challenge can be retried.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| idempotency-key | string (header) | Yes | Same idempotency key used during order creation. |
Request Body
{
"orderId": 1927055,
"paymentIntentId": "pi_3Abc123def456ghi",
"cartId": "cart_abc123"
}Request Body Properties
Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.
| Property | Type | Example | Description |
|---|---|---|---|
| orderId | integer | 1927055 | Identifier of the order. |
| paymentIntentId | string | "pi_3Abc123def456ghi" | Identifier of the associated payment intent. |
| cartId | string | "cart_abc123" | Identifier of the associated cart. |
Response
{
"status": 200,
"code": "order_created",
"message": "Your order was successfully created.",
"data": {
"orderId": 1927055,
"mainStatus": "VALIDATED",
"paymentStatus": "PAID"
}
}Response Properties
Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.
| Property | Type | Example | Description |
|---|---|---|---|
| status | integer | 200 | HTTP status code returned by the API. |
| code | string | "order_created" | Machine-readable application code for the result. |
| message | string | "Your order was successfully created." | Human-readable result message. Do not use this value for program logic. |
| data | object | {…} | Endpoint-specific response payload. |
| data.orderId | integer | 1927055 | Identifier of the order. |
| data.mainStatus | string | "VALIDATED" | The main status value. |
| data.paymentStatus | string | "PAID" | The payment status value. |
POST/orders/confirm/adyenConfirm Adyen Payment
Confirms an Adyen payment for a previously created order. Used for Adyen 3D-Secure authentication flows.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| idempotency-key | string (header) | Yes | Same idempotency key used during order creation. |
Request Body
{
"orderId": 1927055,
"ioPayTransactionId": 98765,
"adyenAuthenticationResult": "eyJhbGciOiJIUzI1NiJ9..."
}Request Body Properties
Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.
| Property | Type | Example | Description |
|---|---|---|---|
| orderId | integer | 1927055 | Identifier of the order. |
| ioPayTransactionId | integer | 98765 | Identifier of the associated io pay transaction. |
| adyenAuthenticationResult | string | "eyJhbGciOiJIUzI1NiJ9..." | The adyen authentication result value. |
Response
{
"status": 200,
"code": "order_created",
"message": "Your order was successfully created.",
"data": {
"orderId": 1927055,
"mainStatus": "VALIDATED",
"paymentStatus": "PAID"
}
}Response Properties
Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.
| Property | Type | Example | Description |
|---|---|---|---|
| status | integer | 200 | HTTP status code returned by the API. |
| code | string | "order_created" | Machine-readable application code for the result. |
| message | string | "Your order was successfully created." | Human-readable result message. Do not use this value for program logic. |
| data | object | {…} | Endpoint-specific response payload. |
| data.orderId | integer | 1927055 | Identifier of the order. |
| data.mainStatus | string | "VALIDATED" | The main status value. |
| data.paymentStatus | string | "PAID" | The payment status value. |
Send Receipt
Send an order receipt by email. Primarily used for anonymous orders placed via web ordering.
POST/orders/receiptSend Anonymous Order Receipt
Sends a receipt email for an anonymous order identified by its UUID. Only supports Web channel orders.
Request Body
{
"email": "customer@example.com",
"orderUuid": "c4d2261e-2779-4eb6-beb0-cb41235c751e",
"channelId": 2
}Request Body Properties
Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.
| Property | Type | Example | Description |
|---|---|---|---|
| string | "customer@example.com" | Email address. | |
| orderUuid | string | "c4d2261e-2779-4eb6-beb0-cb41235c751e" | The order uuid value. |
| channelId | integer | 2 | Identifier of the associated channel. |
Response
{
"status": 200,
"code": "order_receipt_sent",
"message": "The receipt has been sent successfully."
}Response Properties
Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.
| Property | Type | Example | Description |
|---|---|---|---|
| status | integer | 200 | HTTP status code returned by the API. |
| code | string | "order_receipt_sent" | Machine-readable application code for the result. |
| message | string | "The receipt has been sent successfully." | Human-readable result message. Do not use this value for program logic. |
Bulk Order Creation
Create multiple orders in a single request. This endpoint is designed for system integrations (e.g. importing orders from external platforms). Each order is processed independently -- individual failures do not affect other orders in the batch.
Idempotency: Provide a comma-separated list of UUIDs in the idempotency-key header, one per order in the array.
POST/orders/bulkCreate Bulk Orders
Creates multiple orders at once. Requires Brand role. Each order in the array is matched to its corresponding idempotency key by position.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| idempotency-key | string (header) | Yes | Comma-separated list of UUIDs, one per order. |
Request Body
[
{
"restaurantId": 2285,
"channelId": 2,
"consumptionMode": "MODE_TAKE_AWAY",
"customerId": 1008881,
"expectedAt": "2025-12-03T15:53:44.311Z",
"cart": [
{
"productId": 1670891,
"quantity": 1,
"customPrice": 500
}
],
"payments": [
{
"paymentMethodId": 22521,
"amount": 500,
"quantity": 1
}
],
"metadata": {
"externalOrderId": "EXT-001",
"productsMetadata": [
{
"cartLine": 0,
"cegidLine": "L1",
"unit": "1"
}
],
"paymentsMetadata": [
{
"paymentLine": 0,
"paymentMethodId": "22521"
}
]
}
}
]Request Body Properties
Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.
| Property | Type | Example | Description |
|---|---|---|---|
| [] | object | {…} | Object containing fields. |
| [].restaurantId | integer | 2285 | Identifier of the restaurant. |
| [].channelId | integer | 2 | Identifier of the associated channel. |
| [].consumptionMode | string | "MODE_TAKE_AWAY" | The consumption mode value. |
| [].customerId | integer | 1008881 | Identifier of the customer. |
| [].expectedAt | string | "2025-12-03T15:53:44.311Z" | Date or timestamp for expected. |
| [].cart | array | […] | List of cart entries. |
| [].cart[] | object | {…} | Object containing cart fields. |
| [].cart[].productId | integer | 1670891 | Identifier of the product. |
| [].cart[].quantity | integer | 1 | The quantity value. |
| [].cart[].customPrice | integer | 500 | The custom price value. |
| [].payments | array | […] | List of payments entries. |
| [].payments[] | object | {…} | Object containing payments fields. |
| [].payments[].paymentMethodId | integer | 22521 | Identifier of the associated payment method. |
| [].payments[].amount | integer | 500 | The amount value. |
| [].payments[].quantity | integer | 1 | The quantity value. |
| [].metadata | object | {…} | Additional metadata supplied with the response. |
| [].metadata.externalOrderId | string | "EXT-001" | Identifier of the associated external order. |
| [].metadata.productsMetadata | array | […] | List of products metadata entries. |
| [].metadata.productsMetadata[] | object | {…} | Object containing products metadata fields. |
| [].metadata.productsMetadata[].cartLine | integer | 0 | The cart line value. |
| [].metadata.productsMetadata[].cegidLine | string | "L1" | The cegid line value. |
| [].metadata.productsMetadata[].unit | string | "1" | The unit value. |
| [].metadata.paymentsMetadata | array | […] | List of payments metadata entries. |
| [].metadata.paymentsMetadata[] | object | {…} | Object containing payments metadata fields. |
| [].metadata.paymentsMetadata[].paymentLine | integer | 0 | The payment line value. |
| [].metadata.paymentsMetadata[].paymentMethodId | string | "22521" | Identifier of the associated payment method. |
Response
{
"status": 200,
"code": "bulk_order_created",
"data": [
{
"status": 200,
"code": "order_created",
"message": "Order created successfully",
"data": {
"omnichannelOrderId": "12345678",
"restaurantId": 2285,
"customerId": 1008881,
"channelId": 2,
"consumptionModeId": 2,
"status": "VALIDATED"
}
}
]
}Response Properties
Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.
| Property | Type | Example | Description |
|---|---|---|---|
| status | integer | 200 | HTTP status code returned by the API. |
| code | string | "bulk_order_created" | Machine-readable application code for the result. |
| data | array | […] | Endpoint-specific response payload. |
| data[] | object | {…} | Endpoint-specific response payload. |
| data[].status | integer | 200 | HTTP status code returned by the API. |
| data[].code | string | "order_created" | Machine-readable application code for the result. |
| data[].message | string | "Order created successfully" | Human-readable result message. Do not use this value for program logic. |
| data[].data | object | {…} | Endpoint-specific response payload. |
| data[].data.omnichannelOrderId | string | "12345678" | Identifier of the associated omnichannel order. |
| data[].data.restaurantId | integer | 2285 | Identifier of the restaurant. |
| data[].data.customerId | integer | 1008881 | Identifier of the customer. |
| data[].data.channelId | integer | 2 | Identifier of the associated channel. |
| data[].data.consumptionModeId | integer | 2 | Identifier of the associated consumption mode. |
| data[].data.status | string | "VALIDATED" | HTTP status code returned by the API. |
Per-Order Response Codes
| Code | Meaning |
|---|---|
| order_created | Order was successfully created. |
| order_already_created | Idempotent duplicate -- returns the existing order. |
| invalid_parameters | Validation failure for this specific order. |
Multi-Restaurant Orders
Multi-orders allow customers to place a single order spanning multiple restaurants within the same brand. The workflow mirrors the single-order flow: Preview, then Create, with an optional Confirm step for Stripe payments.
Preview Multi-Order
POST/multi-orders/previewPreview Multi-Order
Validate a multi-restaurant cart and calculate totals without persisting. Each restaurantCart contains its own cart array, menuId, and expectedAt.
Request Body
{
"brandId": 100,
"channelId": 2,
"consumptionMode": "MODE_TAKE_AWAY",
"customerId": 1008881,
"restaurantCarts": [
{
"restaurantId": 2285,
"menuId": 24194,
"expectedAt": "2025-12-03T15:00:00.000Z",
"cart": [
{
"productId": 1670891,
"quantity": 1,
"steps": []
}
]
},
{
"restaurantId": 2290,
"menuId": 24200,
"expectedAt": "2025-12-03T15:30:00.000Z",
"cart": [
{
"productId": 1670950,
"quantity": 2,
"steps": []
}
]
}
]
}Request Body Properties
Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.
| Property | Type | Example | Description |
|---|---|---|---|
| brandId | integer | 100 | Identifier of the brand. |
| channelId | integer | 2 | Identifier of the associated channel. |
| consumptionMode | string | "MODE_TAKE_AWAY" | The consumption mode value. |
| customerId | integer | 1008881 | Identifier of the customer. |
| restaurantCarts | array | […] | List of restaurant carts entries. |
| restaurantCarts[] | object | {…} | Object containing restaurant carts fields. |
| restaurantCarts[].restaurantId | integer | 2285 | Identifier of the restaurant. |
| restaurantCarts[].menuId | integer | 24194 | Identifier of the menu. |
| restaurantCarts[].expectedAt | string | "2025-12-03T15:00:00.000Z" | Date or timestamp for expected. |
| restaurantCarts[].cart | array | […] | List of cart entries. |
| restaurantCarts[].cart[] | object | {…} | Object containing cart fields. |
| restaurantCarts[].cart[].productId | integer | 1670891 | Identifier of the product. |
| restaurantCarts[].cart[].quantity | integer | 1 | The quantity value. |
| restaurantCarts[].cart[].steps | array | [] | List of steps entries. |
Response
{
"status": 200,
"code": "multi_order_verified",
"message": "Your multi order was successfully verified.",
"data": {
"totalPriceWithTaxIncluded": 2500,
"valid": true,
"restaurantCarts": [
{
"restaurantId": 2285,
"totalPriceWithTaxIncluded": 1000
},
{
"restaurantId": 2290,
"totalPriceWithTaxIncluded": 1500
}
]
}
}Response Properties
Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.
| Property | Type | Example | Description |
|---|---|---|---|
| status | integer | 200 | HTTP status code returned by the API. |
| code | string | "multi_order_verified" | Machine-readable application code for the result. |
| message | string | "Your multi order was successfully verified." | Human-readable result message. Do not use this value for program logic. |
| data | object | {…} | Endpoint-specific response payload. |
| data.totalPriceWithTaxIncluded | integer | 2500 | The total price with tax included value. |
| data.valid | boolean | true | The valid value. |
| data.restaurantCarts | array | […] | List of restaurant carts entries. |
| data.restaurantCarts[] | object | {…} | Object containing restaurant carts fields. |
| data.restaurantCarts[].restaurantId | integer | 2285 | Identifier of the restaurant. |
| data.restaurantCarts[].totalPriceWithTaxIncluded | integer | 1000 | The total price with tax included value. |
Create Multi-Order
Idempotency Required: You must provide a unique idempotency-key header.
POST/multi-ordersCreate Multi-Order
Creates a multi-restaurant order. Includes payment information shared across all restaurant carts. Each restaurant cart must include its own cart, menuId, expectedAt, and payments array.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| idempotency-key | string (header) | Yes | Unique UUID to prevent duplicate creations. |
Request Body
{
"brandId": 100,
"channelId": 2,
"consumptionMode": "MODE_TAKE_AWAY",
"customerId": 1008881,
"payment": {
"currency": "EUR",
"metadata": "{}"
},
"restaurantCarts": [
{
"restaurantId": 2285,
"menuId": 24194,
"expectedAt": "2025-12-03T15:00:00.000Z",
"cart": [
{
"productId": 1670891,
"quantity": 1,
"steps": []
}
],
"payments": [
{
"paymentMethodId": 22521,
"amount": 1000,
"quantity": 1
}
]
}
]
}Request Body Properties
Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.
| Property | Type | Example | Description |
|---|---|---|---|
| brandId | integer | 100 | Identifier of the brand. |
| channelId | integer | 2 | Identifier of the associated channel. |
| consumptionMode | string | "MODE_TAKE_AWAY" | The consumption mode value. |
| customerId | integer | 1008881 | Identifier of the customer. |
| payment | object | {…} | Object containing payment fields. |
| payment.currency | string | "EUR" | ISO 4217 currency code. |
| payment.metadata | string | "{}" | Additional metadata supplied with the response. |
| restaurantCarts | array | […] | List of restaurant carts entries. |
| restaurantCarts[] | object | {…} | Object containing restaurant carts fields. |
| restaurantCarts[].restaurantId | integer | 2285 | Identifier of the restaurant. |
| restaurantCarts[].menuId | integer | 24194 | Identifier of the menu. |
| restaurantCarts[].expectedAt | string | "2025-12-03T15:00:00.000Z" | Date or timestamp for expected. |
| restaurantCarts[].cart | array | […] | List of cart entries. |
| restaurantCarts[].cart[] | object | {…} | Object containing cart fields. |
| restaurantCarts[].cart[].productId | integer | 1670891 | Identifier of the product. |
| restaurantCarts[].cart[].quantity | integer | 1 | The quantity value. |
| restaurantCarts[].cart[].steps | array | [] | List of steps entries. |
| restaurantCarts[].payments | array | […] | List of payments entries. |
| restaurantCarts[].payments[] | object | {…} | Object containing payments fields. |
| restaurantCarts[].payments[].paymentMethodId | integer | 22521 | Identifier of the associated payment method. |
| restaurantCarts[].payments[].amount | integer | 1000 | The amount value. |
| restaurantCarts[].payments[].quantity | integer | 1 | The quantity value. |
Response
{
"status": 200,
"code": "multi_order_created",
"data": {
"multiOrderId": "mo_abc123",
"orders": [
{
"orderId": 1927060,
"restaurantId": 2285,
"mainStatus": "VALIDATED"
}
]
}
}Response Properties
Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.
| Property | Type | Example | Description |
|---|---|---|---|
| status | integer | 200 | HTTP status code returned by the API. |
| code | string | "multi_order_created" | Machine-readable application code for the result. |
| data | object | {…} | Endpoint-specific response payload. |
| data.multiOrderId | string | "mo_abc123" | Identifier of the associated multi order. |
| data.orders | array | […] | List of orders entries. |
| data.orders[] | object | {…} | Object containing orders fields. |
| data.orders[].orderId | integer | 1927060 | Identifier of the order. |
| data.orders[].restaurantId | integer | 2285 | Identifier of the restaurant. |
| data.orders[].mainStatus | string | "VALIDATED" | The main status value. |
Confirm Multi-Order
POST/multi-orders/confirmConfirm Multi-Order Stripe Payment
Confirms a Stripe payment intent for a previously created multi-order. Similar to single-order confirm but for multi-restaurant orders.
Request Body
{
"multiOrderId": "mo_abc123",
"paymentIntentId": "pi_3Abc123def456ghi"
}Request Body Properties
Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.
| Property | Type | Example | Description |
|---|---|---|---|
| multiOrderId | string | "mo_abc123" | Identifier of the associated multi order. |
| paymentIntentId | string | "pi_3Abc123def456ghi" | Identifier of the associated payment intent. |
Response
{
"status": 200,
"code": "multi_order_created",
"data": {
"multiOrderId": "mo_abc123",
"orders": [
{
"orderId": 1927060,
"restaurantId": 2285,
"mainStatus": "VALIDATED",
"paymentStatus": "PAID"
}
]
}
}Response Properties
Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.
| Property | Type | Example | Description |
|---|---|---|---|
| status | integer | 200 | HTTP status code returned by the API. |
| code | string | "multi_order_created" | Machine-readable application code for the result. |
| data | object | {…} | Endpoint-specific response payload. |
| data.multiOrderId | string | "mo_abc123" | Identifier of the associated multi order. |
| data.orders | array | […] | List of orders entries. |
| data.orders[] | object | {…} | Object containing orders fields. |
| data.orders[].orderId | integer | 1927060 | Identifier of the order. |
| data.orders[].restaurantId | integer | 2285 | Identifier of the restaurant. |
| data.orders[].mainStatus | string | "VALIDATED" | The main status value. |
| data.orders[].paymentStatus | string | "PAID" | The payment status value. |
Get Multi-Order
GET/multi-orders/{multiOrderId}Get Multi-Order by ID
Retrieve a multi-order and all its constituent orders. No authentication required.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| multiOrderId | string | Yes | The multi-order ID. |
Response
{
"status": 200,
"code": "multi_order_found",
"message": "Your multi order was successfully fetched.",
"data": {
"multiOrderId": "mo_abc123",
"orders": [
{
"orderId": 1927060,
"restaurantId": 2285,
"mainStatus": "VALIDATED"
}
]
}
}Response Properties
Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.
| Property | Type | Example | Description |
|---|---|---|---|
| status | integer | 200 | HTTP status code returned by the API. |
| code | string | "multi_order_found" | Machine-readable application code for the result. |
| message | string | "Your multi order was successfully fetched." | Human-readable result message. Do not use this value for program logic. |
| data | object | {…} | Endpoint-specific response payload. |
| data.multiOrderId | string | "mo_abc123" | Identifier of the associated multi order. |
| data.orders | array | […] | List of orders entries. |
| data.orders[] | object | {…} | Object containing orders fields. |
| data.orders[].orderId | integer | 1927060 | Identifier of the order. |
| data.orders[].restaurantId | integer | 2285 | Identifier of the restaurant. |
| data.orders[].mainStatus | string | "VALIDATED" | The main status value. |
Send Multi-Order Receipt
POST/multi-orders/receiptSend Multi-Order Receipt Email
Sends a receipt email for a multi-order. Supports anonymous orders. Only Web channel.
Request Body
{
"email": "customer@example.com",
"multiOrderId": "mo_abc123",
"channelId": 2
}Request Body Properties
Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.
| Property | Type | Example | Description |
|---|---|---|---|
| string | "customer@example.com" | Email address. | |
| multiOrderId | string | "mo_abc123" | Identifier of the associated multi order. |
| channelId | integer | 2 | Identifier of the associated channel. |
Response
{
"status": 200,
"code": "order_receipt_sent",
"message": "The receipt has been sent successfully."
}Response Properties
Every field in the example is listed below. Explicit requiredness is shown when the endpoint contract defines it.
| Property | Type | Example | Description |
|---|---|---|---|
| status | integer | 200 | HTTP status code returned by the API. |
| code | string | "order_receipt_sent" | Machine-readable application code for the result. |
| message | string | "The receipt has been sent successfully." | Human-readable result message. Do not use this value for program logic. |