Entwickler · für Entwickler
Webhooks
Signierte Echtzeit-Events empfangen (Buchungen, Check-ins, Zahlungen, freigeschaltete Aufenthalte, Extras, Nachrichten) und HMAC-SHA256 prüfen.
Webhooks senden Events in dem Moment an Ihr System, in dem sie eintreten – Sie müssen die API also nicht abfragen (Polling).
Events #
| Event | Wann |
|---|---|
booking.created | Eine Buchung wurde angelegt (Dashboard, Kanalimport oder API) |
booking.updated | Daten, Gäste, Check-in-/Check-out-Zeiten oder Kontaktdaten haben sich geändert |
booking.cancelled | Eine Buchung wurde storniert |
checkin.completed | Der Gast hat den Online-Check-in abgeschlossen (oder aktualisiert) |
payment.completed | Touristensteuer bezahlt oder Kaution reserviert/bezahlt (auch wenn Mitarbeitende sie als bezahlt markieren) |
booking.unlocked | Alle Schritte sind erledigt – die digitale Gästemappe ist freigeschaltet |
extras.ordered | Der Gast hat Extras bezahlt – auch einen frühen Check-in oder späten Check-out |
message.sent | Eine Nachricht wurde über den Buchungskanal an den Gast gesendet (Airbnb, Booking.com … über Hostaway oder Channex) |
feedback.received | Der Gast hat den Aufenthalt nach einer Bewertungsanfrage auf der Feedback-Seite bewertet (1–5) |
ping | Test-Event über den Button Test |
Was data enthält #
| Event | data-Felder |
|---|---|
booking.created, booking.updated, booking.cancelled | bookingId, ref, source (Kanalimporte); reason: "stay-times", wenn ein gekaufter früher Check-in / später Check-out die Zeiten verschoben hat |
checkin.completed | bookingId, ref |
payment.completed | bookingId, leg (eco oder deposit), status (paid oder held), manual: true, wenn Mitarbeitende sie als bezahlt markiert haben |
booking.unlocked | bookingId |
extras.ordered | bookingId, leg: "extras", status: "paid" |
message.sent | bookingId, ref, via (z. B. Hostaway) |
feedback.received | bookingId, ref, rating (1–5) |
Die maschinenlesbare Fassung jedes Events – Header, Body und data – finden Sie im Abschnitt webhooks des OpenAPI-Dokuments und in der API-Referenz.
Webhook hinzufügen #
Settings → Webhooks: Geben Sie eine https://-URL ein, wählen Sie die gewünschten Events (keine Auswahl = alle) und klicken Sie auf Add webhook. Das Signing Secret wird nur einmal angezeigt – speichern Sie es bei Ihrem Empfänger.
Die Anfrage #
POST mit JSON-Body:
{
"id": "evt_…",
"event": "payment.completed",
"createdAt": "2026-11-18T14:03:11.000Z",
"tenant": "t_…",
"data": { "bookingId": "b_…", "leg": "eco", "status": "paid" }
}
Header:
| Header | Inhalt |
|---|---|
X-GP-Event | der Event-Name |
X-GP-Delivery | eindeutige Zustellungs-ID |
X-GP-Timestamp | Unix-Zeit in Sekunden |
X-GP-Signature | v1= + hexadezimaler HMAC-SHA256 von <timestamp>.<raw body> mit Ihrem Signing Secret |
Signatur prüfen (Node.js) #
const crypto = require('crypto');
function verify(rawBody, headers, secret) {
const ts = headers['x-gp-timestamp'];
const expected = 'v1=' + crypto.createHmac('sha256', secret).update(ts + '.' + rawBody).digest('hex');
const given = String(headers['x-gp-signature'] || '');
const fresh = Math.abs(Date.now() / 1000 - Number(ts)) < 300;
return fresh && given.length === expected.length && crypto.timingSafeEqual(Buffer.from(given), Buffer.from(expected));
}
Prüfen Sie immer gegen den unveränderten (rohen) Request-Body und lehnen Sie alte Zeitstempel ab, um Replay-Angriffe zu verhindern.
Signatur prüfen (C# / .NET) #
using System.Security.Cryptography; using System.Text;
static bool Verify(string rawBody, string ts, string signature, string secret) {
if (!long.TryParse(ts, out var t) || Math.Abs(DateTimeOffset.UtcNow.ToUnixTimeSeconds() - t) > 300) return false;
using var h = new HMACSHA256(Encoding.UTF8.GetBytes(secret));
var hex = Convert.ToHexString(h.ComputeHash(Encoding.UTF8.GetBytes(ts + "." + rawBody))).ToLowerInvariant();
return CryptographicOperations.FixedTimeEquals(Encoding.ASCII.GetBytes("v1=" + hex), Encoding.ASCII.GetBytes(signature ?? ""));
}
Unter .NET Framework verwenden Sie BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant() statt Convert.ToHexString und vergleichen in konstanter Zeit mit einer einfachen Schleife.
Signatur prüfen (PHP) #
$expected = 'v1=' . hash_hmac('sha256', $_SERVER['HTTP_X_GP_TIMESTAMP'] . '.' . file_get_contents('php://input'), $secret);
$ok = abs(time() - (int)$_SERVER['HTTP_X_GP_TIMESTAMP']) < 300 && hash_equals($expected, $_SERVER['HTTP_X_GP_SIGNATURE'] ?? '');
Zustellung und Wiederholungen #
Antworten Sie innerhalb von 10 Sekunden mit einem beliebigen 2xx-Status. Fehlgeschlagene Zustellungen werden nach 30 Sekunden und nach 5 Minuten wiederholt (insgesamt drei Versuche). Recent deliveries zeigt die letzten 200 Versuche mit ihrem Ergebnis.
idim Body und der HeaderX-GP-Deliverybleiben bei jeder Wiederholung gleich – speichern Sie den Wert und ignorieren Sie Duplikate.- Events können in anderer Reihenfolge eintreffen; verwenden Sie
createdAtund rufen Sie die Buchung ab, um den aktuellen Stand zu erhalten. - Weiterleitungen werden nicht verfolgt, und es werden nur öffentliche
https://-Adressen aufgerufen (keine privaten oder lokalen Netzwerke). - Anfragen kommen mit
Content-Type: application/jsonundUser-Agent: GuestPortal-Webhooks/1.
Häufige Fragen #
Erhalte ich die vollständige Buchung im Event? #
Das Event enthält IDs und die Änderung. Rufen Sie die vollständige Buchung mit GET /api/v1/bookings/{id} und einem API-Schlüssel ab – so werden keine personenbezogenen Daten in Webhook-Bodies übertragen.
Können Kanäle Webhooks an Guestbud senden? #
Ja – das ist die andere Richtung. Hostaway und Channex können Guestbud sofort über neue und geänderte Reservierungen informieren; siehe Hostaway und Channex. Diese eingehenden Adressen sind pro Unternehmen geheim und lösen nur einen neuen Import der jeweiligen Reservierung aus.
Werden aus dem Demo-Konto Webhooks gesendet? #
Nein.
