Dokumentasjon.
Alt et nettsted trenger for å ta imot bestillinger og bordbookinger gjennom nolabel: klientskriptet, de to kallene, statusen, feilkodene, menyformatet, reglene for bundlen og staging.
- Klientskriptet
- Bestilling
- Bordbooking
- Åpent nå
- Status
- Feilkoder
- menu.json
- Bundlen
- Staging og testordrer
Klientskriptet
Ved opplasting legger nolabel tre tagger inn i <head> i hver HTML-fil i bundlen. Ligger taggene der fra før, byttes de ut, så en bundle kan lastes opp på nytt som den er. Du legger ikke inn noe selv.
<meta name="nolabel-site" content="pk_…">
<meta name="nolabel-menu" content="…">
<script src="https://api.nolabel.no/v1.js" defer></script>
Skriptet endrer ikke siden. Det gir bare nettstedet window.nolabel med fire funksjoner:
nolabel.order(bestilling): sender en bestilling.nolabel.book(booking): sender en bordbooking.nolabel.status(id): henter statusen til en bestilling.nolabel.isOpen(): henterGET https://api.nolabel.no/v1/openog svarertruenåropenertruei svaret. API-et avgjør etter nettstedets tidssone og vet om restauranten er pauset eller stengt for dagen fra dashbordet;reasoni svaret ernull,closed,kitchen_closingellerpaused. Svaret er et hint for visningen.
Skriptet sender nettstedsnøkkelen fra nolabel-site i headeren X-Site-Key. I hver bestilling og booking legger det til menu_sha fra nolabel-menu og et tomt website-felt. website er en felle for roboter: har feltet innhold, får kallet et vanlig svar, men ingenting lagres.
Alle fire returnerer et Promise. Et feilsvar fra API-et avviser det med { code, message } fra svaret. Kommer ikke skriptet fram til API-et, er koden network; mangler svaret en kode, er den error.
Skriptet lastes med defer, så window.nolabel finnes når DOMContentLoaded har kommet.
Bestilling
nolabel.order() sender POST https://api.nolabel.no/v1/orders.
nolabel.order({
name: "Kari",
phone: "+47 912 34 567",
items: [{ id: "margherita", qty: 2 }]
});
Felt
name | Påkrevd. Gjestens navn. |
phone | Påkrevd. Et gyldig telefonnummer. Uten landskode leses det som norsk. Det lagres som +4791234567. |
items | Påkrevd. Minst én linje, hver med id fra items i menu.json og qty, et heltall fra 1 til 20. |
note | Valgfri. En beskjed som vises på kjøkkenskjermen. |
Navn og pris hentes alltid fra menyen i versjonen som serveres; en pris i kallet ignoreres. API-et sjekker i denne rekkefølgen, og første feil avgjør svaret: nøkkel og opprinnelse, at menu_sha er menyen i versjonen som serveres, feltene, at restauranten tar imot bestillinger nå, og til slutt hver linje.
Svar
Et godtatt kall svarer 201 Created:
{
"id": "01K5M8Z3QX7T4V2N9B6C1D0E5F",
"status": "received",
"total": 29800,
"poll_url": "https://api.nolabel.no/v1/orders/01K5M8Z3QX7T4V2N9B6C1D0E5F"
}
total er summen i øre. id er det du gir til nolabel.status(), og poll_url er adressen statusen hentes fra.
Bordbooking
nolabel.book() sender POST https://api.nolabel.no/v1/bookings.
nolabel.book({
name: "Kari",
phone: "+47 912 34 567",
guests: 4,
date: "2026-10-02",
time: "19:00"
});
Felt
name | Påkrevd. Gjestens navn. |
phone | Påkrevd. Et gyldig telefonnummer, som for bestilling. |
guests | Påkrevd. Antall gjester, et positivt heltall, høyst booking.max_guests. |
date | Påkrevd. Datoen, ÅÅÅÅ-MM-DD. |
time | Påkrevd. Klokkeslettet, TT:MM, i nettstedets tidssone. Det må falle på et intervall på booking.slot_minutes regnet fra midnatt, ligge innenfor en åpningsperiode den dagen og være minst én time fram i tid. |
note | Valgfri. En beskjed til restauranten. |
Åpningstidene og grensene hentes fra menyen i versjonen som serveres. API-et sjekker i denne rekkefølgen: nøkkel og opprinnelse, at det finnes en versjon, feltene, antall gjester, intervallet, åpningstiden og til slutt at tiden er minst én time fram.
Svar
Et godtatt kall svarer 201 Created:
{
"id": "01K5M8Z3QX7T4V2N9B6C1D0E5F",
"status": "requested"
}
En booking er en forespørsel. Restauranten bekrefter eller avslår den, og gjesten får svaret på SMS.
Åpent nå
GET https://api.nolabel.no/v1/open svarer på om restauranten tar bestillinger akkurat nå, så kan nettstedet skjule bestillingsknappen når den ikke gjør det. API-et avgjør etter nettstedets tidssone og vet om pauser og stenging for dagen som gjestens klokke ikke ser.
Felt
X-Site-Key | Nettstedsnøkkelen fra nolabel-site, som for de andre kallene. |
|---|
Svar
Et godtatt kall svarer 200 OK:
{
"open": false,
"reason": "kitchen_closing"
}
null | Åpen. reason er null. |
closed | Utenfor dagens åpningstider i menyen, eller stengt resten av dagen fra dashbordet. |
kitchen_closing | Innenfor en periode, men det er færre enn last_order_minutes igjen før den slutter. |
paused | Pauset en stund fra kjøkkenskjermen eller dashbordet. |
Status
nolabel.status(id) sender GET https://api.nolabel.no/v1/orders/{id} og svarer med status, eta_minutes og ready_at. Svaret mellomlagres aldri, så nettstedet kan spørre igjen til bestillingen er ferdig.
nolabel.status("01K5M8Z3QX7T4V2N9B6C1D0E5F").then(function (order) {
// { "status": "accepted", "eta_minutes": 25, "ready_at": null }
});
received | Mottatt, venter på restauranten. |
accepted | Godtatt. eta_minutes er restaurantens anslag, fra 5 til 120 minutter. |
ready | Klar til henting. ready_at er tidspunktet den ble klar. |
collected | Hentet. Bestillingen er ferdig. |
rejected | Avvist. Bestillingen er ferdig. |
Et nettsted kan slå av klar-trinnet i innstillingene. Da går bestillingen rett fra accepted til collected.
Gjesten får SMS når bestillingen blir godtatt, klar eller avvist. En bestilling ingen har svart på, avvises av seg selv etter 15 minutter; restauranten kan endre tiden i innstillingene.
Skriptet har ingen funksjon for bookingstatus. Den hentes med GET https://api.nolabel.no/v1/bookings/{id} med nettstedsnøkkelen i X-Site-Key, og svaret er { "status": … }: requested, confirmed eller declined.
Feilkoder
Et feilsvar har alltid denne formen:
{
"error": {
"code": "unavailable",
"message": "Could not price this order",
"details": { "id": "margherita" }
}
}
message er på engelsk og skrevet for utviklere; vis gjesten en egen tekst ut fra code. details er tomt unntatt der tabellen sier noe annet. network og error kommer bare fra skriptet, aldri fra API-et.
| Kode | HTTP | Når | Hva nettstedet gjør |
|---|---|---|---|
unauthorized |
401 | Nøkkelen i X-Site-Key mangler eller er ukjent, eller nettstedet er ikke i drift, fordi prøvetiden er over eller abonnementet er avsluttet. |
Si at bestilling ikke er tilgjengelig nå. Ikke prøv igjen automatisk. |
bad_origin |
403 | Kallet kommer fra en annen opprinnelse enn staging-adressen eller nettstedets eget domene. | Rett opp adressen siden kalles fra. Gjesten kan ikke gjøre noe med det. |
bad_json |
400 | Kroppen er ikke gyldig JSON. | En feil i nettstedets kode. Rett den. |
menu_changed |
409 | Bestilling: menu_sha er ikke menyen i versjonen som serveres, fordi en ny versjon er publisert mens siden var åpen. Begge: det finnes ingen versjon å bestille fra. |
Last siden på nytt og la gjesten prøve igjen. |
invalid_params |
422 | Et påkrevd felt mangler eller er ugyldig: navn, telefonnummer eller linjer for en bestilling; navn, telefonnummer, antall gjester, dato eller tid for en booking. | Vis hvilket felt som er feil, og la gjesten rette det. |
closed |
422 | Bestilling: restauranten har ikke åpent nå, eller er stengt for dagen fra dashbordet. Booking: tiden ligger utenfor åpningstidene den dagen. | Si at restauranten er stengt. For en booking: be om et annet tidspunkt. |
paused |
422 | Bestilling: restauranten har tatt en pause og tar ikke imot ordrer i en fast tid, satt fra kjøkkenskjermen eller dashbordet, før dagens siste lukketid. | Si at restauranten ikke tar imot ordrer akkurat nå, og at de åpner igjen senere. Ikke prøv automatisk på nytt. |
kitchen_closing |
422 | Det er mindre enn last_order_minutes til stengetid. |
Si at kjøkkenet ikke tar flere bestillinger før neste åpning. |
unknown_item |
422 | En linje har en id som ikke finnes i menyen. details.id sier hvilken. |
En feil i nettstedets kode. Rett id-en. |
unavailable |
422 | Retten er merket utsolgt i dashbordet. details.id sier hvilken. |
Ta retten ut av kurven og vis at den er utsolgt. |
invalid_qty |
422 | qty er ikke et heltall fra 1 til 20. details.id sier hvilken linje. |
Begrens antallet i skjemaet. |
too_many_guests |
422 | Flere gjester enn booking.max_guests. |
Vis grensen i skjemaet. |
invalid_slot |
422 | Tiden faller ikke på et intervall på booking.slot_minutes. |
Tilby bare tider fra intervallene. |
too_soon |
422 | Tiden er mindre enn én time fram. | Be om et senere tidspunkt. |
not_found |
404 | Nettstedet har ingen bestilling eller booking med den id-en. | Slutt å spørre etter statusen. |
network |
– | Skriptet kom ikke fram til API-et. | La gjesten prøve igjen. |
error |
– | Svaret var en feil uten kode. | La gjesten prøve igjen senere. |
Bundlen
En bundle er en zip med hele nettstedet og menu.json i roten. Last den opp i dashbordet, eller fra CI med PUT https://api.nolabel.no/deploy og deploy-nøkkelen som Bearer-token; der kan zip-en være høyst 200 MB. En ny bundle havner alltid på staging. Live endres først når du publiserer.
En bundle avvises i sin helhet hvis én regel brytes, og alle feilene meldes samtidig. Er menu.json ugyldig, sjekkes ikke HTML-en mot menyen. Den samme zip-en lastet opp på nytt gir versjonen som finnes fra før.
| Kode | Regel |
|---|---|
invalid_zip | Filen er ikke en gyldig zip. |
too_many_files | Mer enn 5 000 filer. |
file_too_large | En fil er større enn 25 MB. |
file_type | Filtypen er ikke tillatt. Tillatt er html, css, js, json, webp, png, jpg, jpeg, svg, ico, woff2, txt, xml og webmanifest. |
path_traversal | En sti inneholder .. eller begynner med /. |
symlink | En fil er en symbolsk lenke. |
menu_missing | menu.json mangler i roten. |
menu_invalid_json | menu.json er ikke gyldig JSON. |
menu_schema | menu.json følger ikke skjemaet. |
duplicate_id | To retter har samme id. |
hours_order | En periode stenger ikke etter at den åpner. |
hours_overlap | To perioder samme dag overlapper. |
last_order_minutes | last_order_minutes er ikke kortere enn den korteste perioden. |
slot_minutes | En periode er ikke et helt antall booking.slot_minutes lang. |
unknown_id | En data-nolabel-id finnes ikke i menyen. |
price_mismatch | En data-nolabel-price er ulik prisen i menyen. |
id_not_in_html | En rett i menyen står ikke i noen HTML-fil. |
/ serverer index.html, og en sti som slutter på /, serverer index.html i den mappen. Finnes ikke filen, brukes 404.html fra bundlen hvis den finnes. HTML sendes uten mellomlagring. Alle andre filer, også menu.json, kan mellomlagres i nettleseren i ett år, så gi en endret CSS-, JS- eller bildefil et nytt navn.
Staging og testordrer
Hvert nettsted har en staging-adresse, https://<navn>.nolabel.no, som alltid viser den siste opplastede versjonen. Det egne domenet viser den publiserte versjonen og krever et aktivt abonnement. API-et tar bare imot kall fra disse to opprinnelsene.
Bestillinger og bookinger fra staging-adressen er testordrer. De bruker menyen i staging-versjonen, kommer fram på kjøkkenskjermen og varsler restauranten som vanlige bestillinger, men gjesten får aldri SMS.
Staging-adressen sendes med X-Robots-Tag: noindex, så søkemotorer tar den ikke med. Den kan låses med brukernavn og passord under innstillingene i dashbordet.