Skip to navigation

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 includes stripeUrl, 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-Key header 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 get 409 PRICE_CHANGED instead 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

AuthorizationBearer

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.

OR
Originstring

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

Idempotency-KeystringOptionalformat: "^[A-Za-z0-9_-]+$"16-128 characters

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

slugstringRequired
The restaurant's slug.
successUrlstringOptional

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.

cancelUrlstringOptional

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

This endpoint expects an object.
itemslist of objectsRequired

The cart, 1–100 lines.

fulfillmentenumRequired

Pickup or delivery. Check restaurant.capabilities for what the restaurant offers.

Allowed values:
customerNamestringRequired1-100 characters
The customer's name.
customerEmailstringRequiredformat: "email"
The order confirmation is sent here.
paymentMethodenumRequired

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.

Allowed values:
orderTypeenumOptionalDefaults to TAKEAWAY

Always TAKEAWAY (15 % VAT on food). For table reservations, use POST /reservations instead.

Allowed values:
customerPhonestringOptional
The customer's phone number.
deliveryAddressstringOptional
The street address for delivery.
deliveryCitystringOptional
The postal town for delivery.
deliveryPostalCodestringOptional

Four digits. Used to match postal-code delivery zones (POSTAL_CODES).

deliveryLatdoubleOptional-90-90

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.

deliveryLngdoubleOptional-180-180

Longitude of the delivery address. Required to match radius-based delivery zones (RADIUS); postal-code zones only need deliveryPostalCode.

deliveryNotesstringOptional<=500 characters
A note for the driver, for example a door code.
pickupNotesstringOptional<=500 characters
A note for the restaurant about the pickup.
requestedPickupAtdatetimeOptional

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.

couponCodestringOptional<=64 characters
A coupon code the customer typed. When a code is sent, automatic promotions are not applied.
expectedTotalintegerOptional>=0

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.

localeenumOptional

The language of emails to the customer. Defaults to nb.

Allowed values:
consentGivenAtdatetimeOptional

Optional. When the customer gave marketing consent (ISO 8601).

marketingOptInbooleanOptional
The customer's consent to marketing, given at checkout.
attributionCampaignIdstringOptional<=64 characters

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.

buyerCompanyNamestringOptional<=120 characters

B2B: the company name on the receipt.

buyerOrgNumberstringOptionalformat: "^\d{9}$"

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.

orderIdstring
The order's internal ID. Keep it for support requests, but do not put it in URLs.
publicTokenstring

Safe to put in URLs and share with the customer. Use it with GET /orders/{token}.

totalsobject
The authoritative totals, calculated by the server. Your own prices are only for display. Show these to the customer before you redirect to payment.
stripeUrlstringOptional

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.

vippsUrlstringOptionalDeprecated

Only for old direct-Vipps integrations. Use stripeUrl for online payment.

Errors

400
Bad Request Error
401
Unauthorized Error
404
Not Found Error
409
Conflict Error
422
Unprocessable Entity Error
429
Too Many Requests Error
502
Bad Gateway Error
503
Service Unavailable Error