News Malta Budget 2027 announced an eco tax of €10 per adult per night for short lets (capped at €80 per person) from 1 January 2027 — not yet law. Leggi di più
Guestbud

Sviluppatori · per Sviluppatori

Webhook

Ricevi eventi firmati in tempo reale — prenotazioni, check-in, pagamenti, soggiorni sbloccati, extra e messaggi — e verifica la firma HMAC-SHA256.

I webhook inviano gli eventi al tuo sistema nel momento in cui avvengono, così non devi interrogare l'API a intervalli regolari.

Eventi #

EventoQuando
booking.createdÈ stata creata una prenotazione (dashboard, importazione dal canale o API)
booking.updatedSono cambiati date, ospiti, orari di check-in/check-out o recapiti
booking.cancelledUna prenotazione è stata cancellata
checkin.completedL'ospite ha completato (o aggiornato) il check-in online
payment.completedTassa di soggiorno pagata o deposito bloccato/pagato (anche quando lo staff lo segna come pagato)
booking.unlockedTutti i passaggi sono completati: la guida del soggiorno è sbloccata
extras.orderedL'ospite ha pagato degli extra, compreso un early check-in o un late check-out
message.sentÈ stato inviato un messaggio all'ospite tramite il canale della prenotazione (Airbnb, Booking.com … tramite Hostaway o Channex)
feedback.receivedL'ospite ha valutato il soggiorno (1–5) nella pagina di feedback dopo una richiesta di recensione
pingEvento di prova dal pulsante Test

Cosa contiene data #

EventoCampi di data
booking.created, booking.updated, booking.cancelledbookingId, ref, source (importazioni dai canali); reason: "stay-times" quando un early check-in / late check-out acquistato ha spostato gli orari
checkin.completedbookingId, ref
payment.completedbookingId, leg (eco o deposit), status (paid o held), manual: true quando lo staff lo ha segnato come pagato
booking.unlockedbookingId
extras.orderedbookingId, leg: "extras", status: "paid"
message.sentbookingId, ref, via (ad es. Hostaway)
feedback.receivedbookingId, ref, rating (1–5)

La versione leggibile dalle macchine di ogni evento — header, body e data — si trova nella sezione webhooks del documento OpenAPI e nel riferimento API.

Aggiungere un webhook #

Settings → Webhooks: inserisci un URL https://, spunta gli eventi che ti interessano (nessuno = tutti) e clicca su Add webhook. Il signing secret (segreto di firma) viene mostrato una sola volta: conservalo insieme al tuo ricevitore.

Settings → Webhooks
Settings → Webhooks

La richiesta #

POST con un body JSON:

{
  "id": "evt_…",
  "event": "payment.completed",
  "createdAt": "2026-11-18T14:03:11.000Z",
  "tenant": "t_…",
  "data": { "bookingId": "b_…", "leg": "eco", "status": "paid" }
}

Header:

HeaderContenuto
X-GP-Eventil nome dell'evento
X-GP-DeliveryID univoco della consegna
X-GP-Timestampora Unix in secondi
X-GP-Signaturev1= + HMAC-SHA256 esadecimale di <timestamp>.<raw body> con il tuo signing secret

Verificare la firma (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));
}

Verifica sempre sul body grezzo della richiesta e rifiuta i timestamp vecchi per bloccare i replay.

Verificare la firma (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 ?? ""));
}

Su .NET Framework usa BitConverter.ToString(hash).Replace("-", "").ToLowerInvariant() al posto di Convert.ToHexString ed esegui il confronto a tempo costante con un semplice ciclo.

Verificare la firma (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'] ?? '');

Consegna e nuovi tentativi #

Rispondi con un qualsiasi stato 2xx entro 10 secondi. Le consegne non riuscite vengono ritentate dopo 30 secondi e dopo 5 minuti (tre tentativi in totale). Recent deliveries mostra gli ultimi 200 tentativi con il relativo esito.

  • L'id nel body e l'header X-GP-Delivery restano uguali a ogni nuovo tentativo: salvali e ignora i duplicati.
  • Gli eventi possono arrivare in ordine diverso; usa createdAt e recupera la prenotazione per conoscerne lo stato attuale.
  • I redirect non vengono seguiti e vengono chiamati solo indirizzi https:// pubblici (nessuna rete privata o locale).
  • Le richieste arrivano con Content-Type: application/json e User-Agent: GuestPortal-Webhooks/1.

Domande frequenti #

Ricevo la prenotazione completa nell'evento? #

L'evento contiene gli ID e la modifica. Recupera la prenotazione completa con GET /api/v1/bookings/{id} usando una chiave API: in questo modo nessun dato personale viaggia nei body dei webhook.

I canali possono inviare webhook a Guestbud? #

Sì, è la direzione opposta. Hostaway e Channex possono comunicare subito a Guestbud le prenotazioni nuove e modificate; vedi Hostaway e Channex. Questi indirizzi in entrata sono segreti e distinti per ogni azienda e attivano solo una nuova importazione di quella prenotazione.

L'account demo invia webhook? #

No.