Skip to navigation

Table reservations

Show available times, send a request, follow the answer

Table reservations on LettBestilt are requests. The guest picks a time on your site, the restaurant approves or rejects the request in its dashboard, and the guest gets an email either way, as long as you sent guestEmail. A reservation is not an order: it has no food and no payment.

Check restaurant.capabilities.reservations before you show a booking form. The TypeScript examples use API, SLUG and headers from the shared setup.

1

Show available times

Ask for one date (Oslo time) and party size:

curl "https://www.lettbestilt.no/api/v1/dine-in/availability?slug=pizzaroma&date=2026-10-16&partySize=4" \
-H "Authorization: Bearer $LETTBESTILT_API_KEY"
Response
{
"enabled": true,
"maxPartySize": 8,
"slots": [
{ "time": "17:00", "iso": "2026-10-16T15:00:00.000Z", "available": true },
{ "time": "17:15", "iso": "2026-10-16T15:15:00.000Z", "available": false }
]
}

Slots are 15 minutes apart. Show time to the guest and keep iso for the request. available: false means no table fits the party at that time. Times outside opening hours, inside the restaurant’s minimum notice, or after the restaurant has closed online booking are left out. A party larger than maxPartySize gets no slots, so ask the guest to call instead.

2

Send the request

curl -X POST "https://www.lettbestilt.no/api/v1/reservations?slug=pizzaroma" \
-H "Authorization: Bearer $LETTBESTILT_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 9b1c0e7a-3d4f-4f6e-8a2b-5c6d7e8f9a0b" \
-d '{
"dineInAt": "2026-10-16T15:00:00.000Z",
"partySize": 4,
"guestName": "Kari Nordmann",
"guestEmail": "kari@example.com",
"guestPhone": "+4799999999",
"note": "En barnestol, takk",
"locale": "nb"
}'

The response is 201 with status: "PENDING_APPROVAL". Tell the guest that the restaurant will confirm by email. Always send guestEmail if you can: without it, the guest cannot be told the answer.

The server checks the party size, the minimum notice and whether online booking is open, but not the time against existing bookings. Only offer times from the availability endpoint.

3

Follow the answer

The restaurant approves (and assigns a table) or rejects the request. You can follow it in two ways:

  • Poll GET /orders/{publicToken}. The status is PENDING_APPROVAL, then CONFIRMED or CANCELLED.
  • Webhooks: RESERVATION_REQUESTED when the request is created, then RESERVATION_APPROVED (with tableId) or RESERVATION_REJECTED (with the restaurant’s reason, if any). Webhooks call the reservation’s ID orderId; it is the same value as reservationId. See Webhooks.

Errors

ResponseMeaning
422 DINE_IN_DISABLEDThe restaurant does not take reservations, or has no tables that can be booked online
422 PARTY_TOO_LARGEMore guests than the restaurant takes online
422 TOO_EARLYThe time is inside the restaurant’s minimum notice
422 VALIDATION_FAILEDThe body failed validation; error.details.issues lists the fields
409 ONLINE_BOOKING_CLOSEDThe restaurant has closed online booking for that date or time. This error uses an older, flat shape: { "error": "…", "code": "ONLINE_BOOKING_CLOSED" }
409 IDEMPOTENCY_CONFLICTThe Idempotency-Key was already used with a different body, or by an order
429 RATE_LIMITEDMore than 20 requests in 60 seconds for this slug and IP

Retrying with the same Idempotency-Key and body returns the existing request with status 200 and idempotent: true, so a network error never creates two requests.