nolabel.

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

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:

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

namePåkrevd. Gjestens navn.
phonePåkrevd. Et gyldig telefonnummer. Uten landskode leses det som norsk. Det lagres som +4791234567.
itemsPåkrevd. Minst én linje, hver med id fra items i menu.json og qty, et heltall fra 1 til 20.
noteValgfri. 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

namePåkrevd. Gjestens navn.
phonePåkrevd. Et gyldig telefonnummer, som for bestilling.
guestsPåkrevd. Antall gjester, et positivt heltall, høyst booking.max_guests.
datePåkrevd. Datoen, ÅÅÅÅ-MM-DD.
timePå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.
noteValgfri. 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-KeyNettstedsnø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.
closedUtenfor dagens åpningstider i menyen, eller stengt resten av dagen fra dashbordet.
kitchen_closingInnenfor en periode, men det er færre enn last_order_minutes igjen før den slutter.
pausedPauset 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 }
});
receivedMottatt, venter på restauranten.
acceptedGodtatt. eta_minutes er restaurantens anslag, fra 5 til 120 minutter.
readyKlar til henting. ready_at er tidspunktet den ble klar.
collectedHentet. Bestillingen er ferdig.
rejectedAvvist. 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.

KodeHTTPNårHva 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.

KodeRegel
invalid_zipFilen er ikke en gyldig zip.
too_many_filesMer enn 5 000 filer.
file_too_largeEn fil er større enn 25 MB.
file_typeFiltypen er ikke tillatt. Tillatt er html, css, js, json, webp, png, jpg, jpeg, svg, ico, woff2, txt, xml og webmanifest.
path_traversalEn sti inneholder .. eller begynner med /.
symlinkEn fil er en symbolsk lenke.
menu_missingmenu.json mangler i roten.
menu_invalid_jsonmenu.json er ikke gyldig JSON.
menu_schemamenu.json følger ikke skjemaet.
duplicate_idTo retter har samme id.
hours_orderEn periode stenger ikke etter at den åpner.
hours_overlapTo perioder samme dag overlapper.
last_order_minuteslast_order_minutes er ikke kortere enn den korteste perioden.
slot_minutesEn periode er ikke et helt antall booking.slot_minutes lang.
unknown_idEn data-nolabel-id finnes ikke i menyen.
price_mismatchEn data-nolabel-price er ulik prisen i menyen.
id_not_in_htmlEn 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.