Skip to navigation

Core concepts

The conventions every endpoint follows

Money is in øre

All amounts are integers in øre: 1 NOK = 100 øre, so 12900 is kr 129,00. The server calculates every price and total itself and ignores prices you send. Show the totals the API returns.

Time

  • Timestamps are ISO 8601 in UTC, for example 2026-10-11T16:30:00.000Z. Format them for display in the Europe/Oslo time zone.
  • Opening hours, menu schedules and coupon time windows are wall-clock times in Oslo ("15:00"), not UTC.
  • Reservation dates (date=2026-10-16) are Oslo dates.

Restaurants are identified by slug

The slug is the restaurant’s LettBestilt subdomain: pizzaroma for pizzaroma.lettbestilt.no. Pass it as ?slug=, except for the two coupon endpoints, which take it in the JSON body. The internal restaurant ID is not part of the API.

The API only answers for restaurants that are live. Until LettBestilt sets a restaurant live, every endpoint that takes a slug responds 404 RESTAURANT_NOT_FOUND, except GET /site-gate.

Order IDs and public tokens

POST /orders returns both orderId and publicToken.

  • publicToken is safe to put in URLs and share with the customer. Use it for order tracking.
  • orderId is internal. Keep it for support requests, but do not build URLs with it. Webhooks carry both.

Capabilities

/restaurant and /menu include restaurant.capabilities:

{
"pickup": true,
"delivery": false,
"reservations": true,
"payment": { "online": true, "cash": true }
}

Read this object instead of keeping your own feature flags. It follows the restaurant’s settings, so your site never offers a flow the API would reject. payment.online covers card, Vipps and the other methods on SagaPay’s hosted payment page. Treat a missing or false field as “not offered”.

Opening hours

restaurant.openingHours in /menu are the kitchen’s hours and decide whether an order is accepted. Gate your ordering flow on them. restaurant.venueHours are when the doors are open, and are for display only; an empty list means the venue follows the kitchen. restaurant.hoursOverrides holds special opening hours, such as holidays.

Preparation time

Rush mode adds minutes to the preparation time. GET /prep-time returns base time plus rush, already added up, and is never cached. Use it for “ready in about X minutes”. The same value is in restaurant.prepTime, but that response is cached.

Caching

EndpointCache
GET /menu30 s at the edge, then served stale for up to 300 s while refreshing. Weak ETag
GET /restaurant60 s at the edge, then stale for up to 600 s while refreshing
GET /dine-in/availability15 s at the edge, then stale for up to 30 s
GET /prep-time, GET /site-gateNever cached
GET /orders/{token}, GET /address-searchNever cached (private, no-store)

Changes the restaurant makes in its dashboard therefore reach your site within a few minutes. Send If-None-Match with the menu’s ETag to get a 304 when nothing has changed.

Order statuses

StatusMeaning
AWAITING_PAYMENTOnline order waiting for payment. Not shown to the kitchen
PAIDOnline payment confirmed
CONFIRMEDAccepted. Cash orders start here
PREPARINGThe kitchen is making it
READY_FOR_PICKUPReady to be picked up
OUT_FOR_DELIVERYOn its way
COMPLETEDPicked up or delivered
CANCELLEDCancelled by the restaurant
FAILEDThe online payment failed

A table reservation uses the same statuses: PENDING_APPROVAL while the restaurant decides, then CONFIRMED or CANCELLED.

Address

restaurant.address is the restaurant’s visiting address, or null if it has none. It is never an object with empty fields, so address ?? fallback works. latitude and longitude are either both set or both null.

Language

Names and descriptions come in Norwegian, with English versions in nameEn and descriptionEn where the restaurant has entered them. Set locale to nb (default) or en on orders and reservations to choose the language of the emails LettBestilt sends to the customer. Error messages are often in Norwegian.

API version

The API is versioned in the path (/api/v1). Every response carries X-LettBestilt-Api-Version: 1. New fields can be added to responses at any time, so ignore fields you do not know.