Webhook-Events
Benachrichtigungen an Ihre Systeme bei Ereignissen zu Reservierungen, Gästen und Treuekarten.
Zuletzt aktualisiert am 16. Oktober 2026
Mit einem Webhook ruft platzeo eine Adresse Ihrer Wahl auf, sobald im Restaurant etwas passiert. Den Aufbau der Anfrage mit einem vollständigen Beispiel finden Sie in der API-Referenz.
Einrichten
Im Admin unter Webhooks → Neuer Webhook:
- Name und URL eintragen. Die Adresse muss öffentlich erreichbar sein und
httpsverwenden. - Ereignisse auswählen.
- Bei Bedarf Methode (POST, PUT oder PATCH), Payload-Format, eigene Header, Timeout und Wiederholungen anpassen.
Nach dem Erstellen zeigt platzeo das Secret des Webhooks an. Es beginnt mit whsec_. Kopieren Sie es gleich. Mit Testereignis senden schicken Sie eine Probe-Zustellung, unter Letzte Zustellungen sehen Sie jeden Versuch.
Ereignisse
reservation.created– Reservierung erstellt, online oder von Ihrem Teamreservation.updated– Tag, Uhrzeit, Personenzahl, Tisch oder Wünsche geändertreservation.confirmed– Reservierung bestätigtreservation.cancelled– Reservierung storniert oder Anfrage abgelehntreservation.seated– Gast am Tischreservation.completed– Besuch abgeschlossenreservation.no_show– Gast nicht erschienenguest.created– neuer Gastguest.updated– Gast geändertloyalty.card.created– Treuekarte erstelltloyalty.stamp.added– Stempel oder Punkte gutgeschriebenloyalty.reward.redeemed– Belohnung eingelöst
Welche Ereignisse eine Änderung sendet
Ändert eine Reservierung ihren Status, kommt genau ein Ereignis: das des neuen Status. reservation.updated kommt dann nicht zusätzlich; es steht für alle anderen Änderungen.
Beginnt eine Reservierung in einem Status mit eigenem Ereignis, folgt es direkt auf reservation.created: reservation.confirmed bei einer sofort bestätigten Online-Buchung und bei einer Reservierung, die Ihr Team einträgt, reservation.seated bei Laufkundschaft. Wer alle bestätigten Reservierungen braucht, abonniert also nur reservation.confirmed.
Gehören mehrere Ereignisse zu einer Aktion, sendet platzeo sie nacheinander in fester Reihenfolge: erst der Gast, dann reservation.created, dann der Status. Eine Wiederholung nach einem Fehlschlag kann später ankommen als das nächste Ereignis.
Aufbau einer Zustellung
Dies ist Version 2 der Inhalte. Im Standard-Format liegt um die Daten ein Umschlag:
{
"id": "0b6f6a52-6c1e-4c0e-9a51-3d8f3f1f2a77",
"event": "reservation.created",
"version": 2,
"timestamp": 1791475200,
"restaurantId": "9b206577-1a4b-4497-9378-48b66f49c18c",
"data": {
"reservation": {
"id": "3a4b5c6d-7e8f-4a1b-9c2d-3e4f5a6b7c8d",
"status": "confirmed",
"date": "2026-04-20",
"time": "19:30",
"partySize": 4,
"durationMinutes": 120,
"tables": [
{
"id": "5f0c2f6e-9d1b-4c1e-8a57-2b1f0c3d4e5f",
"name": "Tisch 4"
}
],
"source": "online",
"occasion": "Geburtstag",
"notes": "Bitte ein Tisch am Fenster.",
"customFields": [
{
"label": "Kinderstuhl",
"value": "Ja"
}
],
"createdAt": "2026-04-15T14:30:00.000Z",
"updatedAt": "2026-04-15T14:30:00.000Z"
},
"guest": {
"id": "0d9c8b7a-6f5e-4d3c-9b2a-1f0e9d8c7b6a",
"firstName": "Anna",
"lastName": "Beispiel",
"email": "anna.beispiel@example.com",
"phone": "+49 30 1234567"
}
}
}id– Kennung der Zustellung, bei jedem Versuch dieselbeevent– Name des Ereignissesversion– Version der Inhalte, auch im HeaderX-platzeo-Payload-Versiontimestamp– Zeitpunkt des Ereignisses in Sekunden seit 1970restaurantId– Kennung Ihres Restaurantsdata– der Inhalt, je nach Ereignis
Mit dem Payload-Format Raw (nur Daten) besteht der Body nur aus dem Inhalt von data.
Gesendet werden genau die Felder, die hier stehen. Neue Felder können jederzeit dazukommen. Fällt ein Feld weg oder ändert es seine Bedeutung, steigt die Version.
Reservierungen
Alle Ereignisse, die mit reservation. beginnen, tragen reservation und guest.
Felder von reservation:
id– Kennung der Reservierungstatus– pending, confirmed, seated, completed, cancelled oder no_showdate– Tag der Reservierung, JJJJ-MM-TTtime– Uhrzeit, HH:MMpartySize– PersonenzahldurationMinutes– geplante Dauer in Minutentables– zugewiesene Tische mit id und name; leer, solange kein Tisch zugewiesen istsource– wie die Reservierung entstand, zum Beispiel online, phone oder walkinoccasion– Anlass, sonst nullnotes– Wünsche des Gastes zu dieser Reservierung, sonst nullcustomFields– Antworten auf Ihre eigenen Fragen im Buchungsformular, je label und valuecreatedAt– angelegt, ISO 8601updatedAt– zuletzt geändert, ISO 8601
Felder von guest:
id– Kennung des GastesfirstName– VornamelastName– Nachnameemail– E-Mail-Adresse, null wenn keine bekannt istphone– Telefonnummer, null wenn keine bekannt ist
guest ist null bei Laufkundschaft ohne Namen. Interne Notizen zum Gast werden nicht gesendet.
reservation.cancelled nennt zusätzlich cancelledBy: guest (über den Link in der E-Mail), restaurant oder expired (der Gast hat seine E-Mail-Adresse nicht rechtzeitig bestätigt).
{
"data": {
"reservation": {
"id": "3a4b5c6d-7e8f-4a1b-9c2d-3e4f5a6b7c8d",
"status": "cancelled",
"date": "2026-04-20",
"time": "19:30",
"partySize": 4,
"durationMinutes": 120,
"tables": [
{
"id": "5f0c2f6e-9d1b-4c1e-8a57-2b1f0c3d4e5f",
"name": "Tisch 4"
}
],
"source": "online",
"occasion": "Geburtstag",
"notes": "Bitte ein Tisch am Fenster.",
"customFields": [
{
"label": "Kinderstuhl",
"value": "Ja"
}
],
"createdAt": "2026-04-15T14:30:00.000Z",
"updatedAt": "2026-04-15T14:30:00.000Z"
},
"guest": {
"id": "0d9c8b7a-6f5e-4d3c-9b2a-1f0e9d8c7b6a",
"firstName": "Anna",
"lastName": "Beispiel",
"email": "anna.beispiel@example.com",
"phone": "+49 30 1234567"
},
"cancelledBy": "guest"
}
}Gäste
guest.created und guest.updated tragen guest mit den Feldern oben und zusätzlich:
marketingConsent– true, wenn der Gast Werbung zugestimmt hatcreatedAt– angelegt, ISO 8601
{
"data": {
"guest": {
"id": "0d9c8b7a-6f5e-4d3c-9b2a-1f0e9d8c7b6a",
"firstName": "Anna",
"lastName": "Beispiel",
"email": "anna.beispiel@example.com",
"phone": "+49 30 1234567",
"marketingConsent": false,
"createdAt": "2026-03-02T09:15:00.000Z"
}
}
}Treueprogramm
Alle Ereignisse, die mit loyalty. beginnen, tragen card:
id– Kennung der KartecardNumber– Kartennummer, wie sie auf der Karte stehtguestId– Kennung des GastesprogramId– Kennung des Treueprogrammsstatus– active oder blockedstamps– Stempel auf der Kartepoints– Punkte auf der KarterewardsRedeemed– bisher eingelöste BelohnungenissuedAt– ausgestellt, ISO 8601expiresAt– Ablauf, ISO 8601, sonst null
Der QR-Code der Karte wird nie gesendet. loyalty.stamp.added trägt zusätzlich delta, die gutgeschriebenen Stempel oder Punkte. loyalty.reward.redeemed trägt delta (abgezogen, negativ) und reward mit id und title; id ist null bei einem Stempelprogramm, dessen Belohnung keine eigene Kennung hat.
{
"data": {
"card": {
"id": "7c6b5a49-3827-4615-a0b9-c8d7e6f5a4b3",
"cardNumber": "PLZ-4821-7730",
"guestId": "0d9c8b7a-6f5e-4d3c-9b2a-1f0e9d8c7b6a",
"programId": "2e3f4a5b-6c7d-4e8f-9a0b-1c2d3e4f5a6b",
"status": "active",
"stamps": 0,
"points": 0,
"rewardsRedeemed": 2,
"issuedAt": "2026-03-02T09:15:00.000Z",
"expiresAt": null
},
"delta": -10,
"reward": {
"id": "6b5a4938-2716-4504-b9a8-d7c6e5f4a3b2",
"title": "Gratis Kaffee"
}
}
}Testereignis
Testereignis senden schickt ein Beispiel des ersten Ereignisses, das der Webhook abonniert hat, mit erfundenen Daten in genau der Form oben. Der Body trägt zusätzlich "test": true (im Format raw steht es neben den Daten), die Anfrage den Header X-platzeo-Test: true. Prüfen Sie eines von beiden, bevor Sie die Daten verarbeiten. Ein Test wird nicht wiederholt und zählt im Admin nicht zu den zugestellten oder fehlgeschlagenen Ereignissen; dort zählt jedes Ereignis einmal, mit seinem Ergebnis nach allen Wiederholungen.
Umstieg von Version 1
Bis Oktober 2026 enthielt data ganze Datensätze ohne Versionsangabe. Wenn Ihr Empfänger aus dieser Zeit stammt, prüfen Sie:
- Felder außerhalb der Listen oben gibt es nicht mehr, zum Beispiel
restaurantId,tableIdundguestIdin der Reservierung (jetzttablesundguest.id),notesundnoShowCountbeim Gast,qrToken,stampCountundpointsBalancebei der Karte (jetztstampsundpoints). - Uhrzeiten kommen als
HH:MMohne Sekunden. - Ein Statuswechsel sendet ein Ereignis statt zwei. Wer bisher nur
reservation.updatedabonniert hat, erfährt Statuswechsel jetzt über die Status-Ereignisse. sourcebeireservation.cancelledheißt jetztcancelledBy.- Das Testereignis hat die Form eines echten Ereignisses und trägt
"test": true.
Signatur prüfen
Jede Anfrage trägt den Header X-platzeo-Signature in der Form t=<Zeitstempel>,v1=<Signatur>. Die Signatur ist der HMAC-SHA256 über <Zeitstempel>.<Body> mit dem Secret, hexadezimal geschrieben. Rechnen Sie mit dem Body genau so, wie er ankommt. Prüfung in Node:
// header: Wert des Headers X-platzeo-Signature, rawBody: Body als Text
const parts = Object.fromEntries(
header.split(",").map((p) => p.split("=")),
);
const expected = crypto
.createHmac("sha256", secret)
.update(parts.t + "." + rawBody)
.digest("hex");
const ok =
parts.v1.length === expected.length &&
crypto.timingSafeEqual(Buffer.from(parts.v1), Buffer.from(expected));Zustellung und Wiederholungen
Als zugestellt gilt eine Antwort mit Status 2xx innerhalb des Timeouts (Standard: 10 Sekunden). Weiterleitungen folgt platzeo nicht. Schlägt ein Versuch fehl, wiederholt platzeo die Zustellung nach 1 Minute, 5 Minuten, 30 Minuten und 2 Stunden, danach alle 6 Stunden. Voreingestellt sind drei Wiederholungen, einstellbar sind 0 bis 10. Nach der letzten gilt die Zustellung als fehlgeschlagen und steht so im Protokoll.
Alle Versuche einer Zustellung tragen dieselbe Kennung im Header X-platzeo-Delivery. Kommt eine Kennung ein zweites Mal an, ist es eine Wiederholung: Verarbeiten Sie jede nur einmal.