De Tavvo-API
Haal reserveringen op, noteer en verzet ze, en krijg een seintje bij elke nieuwe boeking. Gebouwd voor keukenschermen, kassa's en eigen tools. Beschikbaar met de module API-toegang (Instellingen → API & webhooks).
Beginnen
Maak een sleutel aan onder Instellingen → API & webhooks en stuur ze mee in elke aanvraag. Alle antwoorden zijn JSON; tijden zijn in Belgische tijd (datum en tijd) én als ISO-tijdstip (tijdstip).
curl https://tavvo.app/api/v1/zaak \
-H "Authorization: Bearer tv_live_…"Endpoints
Een reservering
{
"id": "cm1…",
"datum": "2026-10-07",
"tijd": "19:30",
"tijdstip": "2026-10-07T17:30:00.000Z",
"personen": 4,
"kinderstoelen": 1,
"status": "BEVESTIGD",
"bron": "EIGEN_SITE",
"tafels": ["T4", "T5"],
"gast": { "id": "…", "naam": "Sofie Peeters", "telefoon": "+32 476 12 34 56",
"email": "sofie@…", "taal": "nl", "vip": true, "allergie": "noten" },
"notitie": "Raamtafel",
"vraag": "Kan er een taart mee?",
"gelegenheid": "verjaardag",
"menus": [{ "id": "…", "naam": "Menu 5 gangen", "aantal": 4 }],
"allergenen": [{ "gast": 2, "allergenen": ["gluten"], "dieet": ["vegetarisch"] }],
"aangekomenOp": null,
"aangemaaktOp": "2026-10-01T09:14:02.000Z",
"bijgewerktOp": "2026-10-06T18:40:11.000Z"
}Statussen: BEVESTIGD, ONBEVESTIGD (wacht op bevestiging van de gast), WACHTLIJST (aanvraag), AANGEKOMEN, VOLTOOID, GEANNULEERD, TE_LAAT_AFGEZEGD, NO_SHOW. Velden komen erbij, verdwijnen niet.
Een reservering noteren
De gast wordt herkend op telefoonnummer (in elk formaat) of e-mail; bestaat hij nog niet, dan maakt Tavvo een klantenfiche. Zonder tafels kiest Tavvo de best passende vrije tafel. Tafels mag je op naam opgeven, zoals ze in GET /zaak staan. Heeft de gast een e-mailadres, dan krijgt hij de gewone bevestiging met de link om zelf te wijzigen.
POST https://tavvo.app/api/v1/reserveringen
{
"datum": "2026-10-12", "tijd": "19:30", "personen": 4,
"gast": { "naam": "Sofie Peeters", "telefoon": "0476 12 34 56", "email": "sofie@…" },
"tafels": ["T4"], // optioneel
"notitie": "Raamtafel", // optioneel
"kinderstoelen": 1, // optioneel
"bron": "TELEFOON", // of "WALK_IN": datum en tijd mogen dan weg (= nu)
"controleerBeschikbaarheid": false,
"mailGast": true
}
→ 201 { "reservering": { … }, "gemaild": true,
"waarschuwingen": [{ "code": "tafel_bezet", "boodschap": "…" }] }Mogelijke waarschuwingen: buiten_beschikbaarheid (online had dit niet gekund), tafel_bezet en geen_tafel. Ze houden niets tegen — toon ze gewoon aan wie de reservering ingeeft. In de geschiedenis van de reservering staat de naam van je sleutel als wie het deed.
Verzetten of annuleren
PATCH https://tavvo.app/api/v1/reserveringen/{id}
{ "datum": "2026-10-13", "tijd": "20:00", "personen": 6 }
PATCH https://tavvo.app/api/v1/reserveringen/{id}
{ "status": "GEANNULEERD", "mailGast": true }Webhooks
Liever niet blijven vragen? Voeg een https-URL toe onder Instellingen → API & webhooks en kies de gebeurtenissen: reservering.aangemaakt, reservering.gewijzigd, reservering.geannuleerd, reservering.aangekomen. Tavvo stuurt dan een POST met de volledige reservering.
POST https://jouw-systeem.be/tavvo-webhook
X-Tavvo-Event: reservering.aangemaakt
X-Tavvo-Signature: sha256=3f1c…
{ "id": "evt_…", "gebeurtenis": "reservering.aangemaakt",
"tijdstip": "2026-10-07T17:02:11.000Z", "zaakId": "…",
"reservering": { … zoals hierboven … } }Controleer de handtekening: HMAC-SHA256 van het ruwe lichaam met het geheim dat je bij het aanmaken kreeg. Antwoord met een 2xx binnen 8 seconden; na 10 opeenvolgende mislukkingen zet Tavvo de webhook uit (je ziet dat in je instellingen en kan hem opnieuw aanzetten).
// Node.js
import { createHmac, timingSafeEqual } from "node:crypto";
const verwacht = "sha256=" + createHmac("sha256", GEHEIM).update(ruwLichaam).digest("hex");
const ok = timingSafeEqual(Buffer.from(verwacht), Buffer.from(req.headers["x-tavvo-signature"]));Voorbeeld: een keukenscherm
Haal bij het opstarten de hele dag op, en daarna elke 30 seconden enkel de wijzigingen. Combineer met de webhook reservering.aangemaakt als je het meteen wil zien.
const basis = "https://tavvo.app/api/v1";
const koppen = { Authorization: "Bearer " + process.env.TAVVO_SLEUTEL };
let sinds = null;
async function ververs() {
const url = basis + "/reserveringen" + (sinds ? "?sinds=" + encodeURIComponent(sinds) : "");
const r = await fetch(url, { headers: koppen }).then((x) => x.json());
for (const res of r.reserveringen) toonOfUpdate(res); // op id
sinds = r.opgehaaldOp;
}
ververs();
setInterval(ververs, 30_000);Fouten en limieten
Fouten komen als { "fout": { "code": "…", "boodschap": "…" } } met een passende HTTP-status: 401 bij een ontbrekende of ingetrokken sleutel, 403 als de module niet actief is, 404 bij een onbekend id, 400 bij een ongeldige aanvraag. Wees redelijk: één aanvraag per paar seconden per sleutel is ruim voldoende. Vragen? hallo@tavvo.app.