Create an order
Creates a takeaway order for pickup or delivery. The server prices every line from its own data and ignores any prices you send. Show the totals it returns.
- Online payment (
paymentMethod: "STRIPE"): the response includesstripeUrl, SagaPay’s hosted payment page. Redirect the customer there. The field name is historical and does not mean Stripe. - Cash (
paymentMethod: "CASH"): there is no payment link, and the order goes straight to the kitchen. - Retries: send an
Idempotency-Keyheader and retry with the same key after a network error. A replay returns the original order instead of creating a new one. - Price check: send
expectedTotal, the total you showed the customer, to get409 PRICE_CHANGEDinstead of an order at a higher price.
Business rules are checked here as well: opening hours, menu schedules, sold-out products, required add-ons, delivery zones and coupon rules. When one fails, error.message explains it in Norwegian and can be shown to the customer.
Table reservations are not orders. orderType only accepts TAKEAWAY, and DINE_IN fails with 422 VALIDATION_FAILED; use POST /reservations instead.
Rate limit: 10 requests per 60 seconds per slug and IP. Walkthrough: Build an ordering flow.
Authentication
Either this or a trusted browser origin. The restaurant’s API key, sent as Authorization: Bearer lbs_…. Use it from your server only, never in browser code. Keys are issued per restaurant by LettBestilt.
Either this or an API key. No key is needed when the request’s Origin header is trusted for this restaurant: https://{slug}.lettbestilt.no, a verified domain of the restaurant, or a partner origin LettBestilt has bound to the restaurant. Browsers set Origin themselves; it is not something you configure. Not accepted by GET /site-gate, which requires an API key.
Headers
Optional. 16–128 URL-safe characters (a-z, A-Z, 0-9, _, -); a UUID works well. A request with a key that was already used for this restaurant returns that earlier order and its payment link instead of creating a new one. The body of the replay is not compared, so create a new key for every new checkout attempt.
Query parameters
Where the customer returns after paying. Put {TOKEN} in the URL to get the order’s publicToken back, for example https://www.pizzaroma.no/order/{TOKEN}. Must be https on a verified domain or on lettbestilt.no; anything else fails with 400 INVALID_SUCCESS_URL. If you leave it out, the customer returns to /order/{TOKEN}?payment=success on the restaurant’s domain.
Where the customer returns if they cancel or the payment fails. Same rules as successUrl (400 INVALID_CANCEL_URL). If you leave it out, the customer returns to the front page of the restaurant’s own domain, or to checkout on {slug}.lettbestilt.no.
Request
The cart, 1–100 lines.
Pickup or delivery. Check restaurant.capabilities for what the restaurant offers.
STRIPE for online payment: the response includes stripeUrl, SagaPay’s hosted page, where the customer chooses card, Vipps or another enabled method. CASH is paid at pickup or delivery. VIPPS is only accepted for old direct-Vipps integrations.
Always TAKEAWAY (15 % VAT on food). For table reservations, use POST /reservations instead.
Four digits. Used to match postal-code delivery zones (POSTAL_CODES).
Latitude of the delivery address. Required to match radius-based delivery zones (RADIUS); postal-code zones only need deliveryPostalCode. Get it from GET /address-search.
Longitude of the delivery address. Required to match radius-based delivery zones (RADIUS); postal-code zones only need deliveryPostalCode.
Optional. The pickup or delivery time for a pre-order (ISO 8601, UTC). Leave it out for as soon as possible. Opening hours, menu schedules and coupon rules are checked against this time.
Optional. The total in øre you showed the customer. If the server’s total is higher, the order is rejected with 409 PRICE_CHANGED and nothing is created. A lower total is accepted (the customer pays less than they saw), so an automatic promotion you could not predict never blocks checkout.
The language of emails to the customer. Defaults to nb.
Optional. When the customer gave marketing consent (ISO 8601).
Campaign attribution: the value of ?lb_campaign=<id> from a LettBestilt campaign link. Pass it on unchanged at checkout, and the order counts as a conversion for the campaign. Optional metadata: an invalid or unknown ID is dropped silently and never blocks the order.
B2B: the company name on the receipt.
B2B: Norwegian organization number, exactly 9 digits. Spaces are removed.
Response
The order was created, or an earlier order was returned for the same Idempotency-Key.
Safe to put in URLs and share with the customer. Use it with GET /orders/{token}.
SagaPay’s hosted payment page, for online orders. Redirect the customer here; they choose card, Vipps or another enabled method on the page. The field name is historical and does not say which provider is used.
Only for old direct-Vipps integrations. Use stripeUrl for online payment.

