Bijgewerkt
Webhooks zijn de snelste manier om synchroon te blijven met Nowistay. In plaats van om de paar minuten de API te bevragen om nieuwe of gewijzigde reserveringen op te sporen, geef je Nowistay aan waarheen de events moeten worden gestuurd, en je service ontvangt ze zodra ze gebeuren. Dit artikel laat zien hoe je een webhook aanmaakt, de handtekening controleert en nieuwe pogingen afhandelt.
Met de openbare REST-API van Nowistay kunnen je tools en partners via HTTPS gegevens van Nowistay lezen en schrijven. Je authenticeert met OAuth2 (authorization code + PKCE), ontvangt een toegangstoken en roept endpoints aan onder /public/v1/*. Webhooks zijn het push-equivalent: dezelfde gegevens, dezelfde vorm als GET /public/v1/bookings/{id}, maar Nowistay stuurt ze naar jou wanneer er iets verandert.
Heb je OAuth nog niet ingesteld, begin dan met de hoofdgids: De openbare REST-API van Nowistay gebruiken. Die behandelt de registratie, de toestemmingsprocedure, scopes en hoe je aanroepen test in de playground van de documentatie.
booking.created en booking.updated.GET /public/v1/bookings/{id}, inclusief data, kanaal, status, bedragen, velden die voor opdrachten relevant zijn en je eigen reserveringsparameters.webhooks.write hebben. POST /public/v1/webhooks vereist ook bookings.read, omdat de payload een volledig reserveringsdetail is.2xx-status.curl -X POST https://api.nowistay.com/public/v1/webhooks \
-H "Authorization: Bearer nis_access_token_example" \
-H "Content-Type: application/json" \
-d '{
"propertyId": 101,
"url": "https://partner.example.com/nowistay/webhooks",
"events": ["booking.created", "booking.updated"],
"description": "PMS sync"
}'
Antwoord:
{
"id": 801,
"propertyId": 101,
"url": "https://partner.example.com/nowistay/webhooks",
"events": ["booking.created", "booking.updated"],
"description": "PMS sync",
"status": "active",
"createdAt": "2026-05-27T16:40:00Z",
"updatedAt": "2026-05-27T16:40:00Z",
"signingSecret": "whsec_9npwH6J8QyZp1L8U3xqG7sN2"
}
Bewaar de signingSecret nu. Hij wordt maar één keer teruggegeven, bij het aanmaken. Je kunt hem niet opnieuw uit de API lezen. Raak je hem kwijt, verwijder dan de webhook en maak een nieuwe aan.
Elke levering is een HTTP POST naar je URL, met deze headers:
Content-Type: application/jsonUser-Agent: Nowistay-Webhooks/1.0Nowistay-Webhook-Id: 801Nowistay-Webhook-Event-Id: evt_LkP2sxR9zV8QyW... (uniek per event)Nowistay-Webhook-Event-Type: booking.updatedNowistay-Webhook-Timestamp: 1779292800 (Unix-seconden)Nowistay-Webhook-Signature: v1=3a7b...e1c (HMAC-SHA256, hex)En een JSON-body die er zo uitziet:
{
"id": "evt_LkP2sxR9zV8QyW...",
"type": "booking.updated",
"createdAt": "2026-05-27T16:40:00Z",
"apiVersion": "2026-05-27",
"propertyId": 101,
"bookingId": 9001,
"data": {
"booking": {
"id": 9001,
"propertyId": 101,
"arrival": "2026-07-14",
"departure": "2026-07-18",
"status": "confirmed",
"channel": "airbnb",
"reservationNumber": "HMABCDE",
"guest": { "firstName": "Maya", "lastName": "M." },
"amounts": { "amount": "620.00", "currency": "EUR" },
"identity": { "status": "verified" }
}
}
}
Je endpoint moet antwoorden met een willekeurige 2xx-status (200 of 204 zijn gebruikelijk). Al het andere, of een antwoord dat langer dan 10 seconden duurt, telt als een mislukking en leidt tot een nieuwe poging.
Controleer altijd de handtekening voordat je de body vertrouwt. Zonder controle kan iedereen die je URL raadt, nep-events naar je service sturen.
Nowistay berekent de handtekening als volgt:
signature = "v1=" + HMAC_SHA256(
signing_secret,
timestamp + "." + event_id + "." + raw_request_body
).hex()
Bereken hem aan jouw kant opnieuw met de headers Nowistay-Webhook-Timestamp en Nowistay-Webhook-Event-Id en de exacte ruwe request-body (parseer en serialiseer de JSON niet opnieuw voordat je controleert, anders loop je het risico op verschillen in bytes).
import crypto from "node:crypto";
function verify(req, signingSecret) {
const timestamp = req.headers["nowistay-webhook-timestamp"];
const eventId = req.headers["nowistay-webhook-event-id"];
const signature = req.headers["nowistay-webhook-signature"];
const rawBody = req.rawBody; // Buffer of the raw HTTP body
const signed = Buffer.concat([
Buffer.from(`${timestamp}.${eventId}.`, "utf8"),
rawBody,
]);
const expected = "v1=" + crypto
.createHmac("sha256", signingSecret)
.update(signed)
.digest("hex");
const a = Buffer.from(signature);
const b = Buffer.from(expected);
return a.length === b.length && crypto.timingSafeEqual(a, b);
}
import hmac, hashlib
def verify(request, signing_secret: str) -> bool:
timestamp = request.headers["Nowistay-Webhook-Timestamp"]
event_id = request.headers["Nowistay-Webhook-Event-Id"]
signature = request.headers["Nowistay-Webhook-Signature"]
raw_body = request.body # bytes
signed = f"{timestamp}.{event_id}.".encode("utf-8") + raw_body
expected = "v1=" + hmac.new(
signing_secret.encode("utf-8"),
signed,
hashlib.sha256,
).hexdigest()
return hmac.compare_digest(signature, expected)
Controleer ook of de timestamp recent is (bijvoorbeeld binnen de laatste 5 minuten) als bescherming tegen replay-aanvallen.
Het object data.booking weerspiegelt wat GET /public/v1/bookings/{id} teruggeeft wanneer het wordt aangeroepen zonder de scope bookings.sensitive.read. Dat betekent:
Heeft je tool een van die gevoelige velden nodig, haal dan het reserveringsdetail uit de API op met een token met de scope bookings.sensitive.read. De bookingId in de envelop van de webhook is de juiste invoer voor die aanroep.
curl https://api.nowistay.com/public/v1/bookings/9001 \
-H "Authorization: Bearer nis_access_token_with_sensitive_scope"
Als je endpoint een niet-2xx-status teruggeeft, een time-out geeft of om een andere reden faalt, laat Nowistay het event niet vallen. Het plant een nieuwe poging in, met exponentiële backoff en een beetje jitter:
Dit gaat door tot je endpoint het event accepteert, of tot de webhook meer dan 72 uur aaneen faalt. Op dat moment zet Nowistay de status van de webhook op disabled en stopt het met het sturen van nieuwe events. De foutentellers worden gereset telkens wanneer een levering slaagt, dus een op zichzelf staand incident leidt nooit tot automatisch uitschakelen.
Leveringsgegevens worden 30 dagen bewaard en daarna opgeruimd.
Een uitgeschakelde webhook kun je via de API weer inschakelen zodra je endpoint weer gezond is. Stuur een PATCH met status: "active":
curl -X PATCH https://api.nowistay.com/public/v1/webhooks/801 \
-H "Authorization: Bearer nis_access_token_example" \
-H "Content-Type: application/json" \
-d '{"status": "active"}'
Nowistay speelt de events die zijn afgegaan terwijl de webhook was uitgeschakeld niet opnieuw af. Heb je er een paar gemist, doe dan eenmalig een backfill met GET /public/v1/bookings met een datumfilter en hervat daarna je flow op basis van webhooks.
Je kunt leveringen tijdelijk pauzeren (bijvoorbeeld tijdens een onderhoudsvenster) zonder de configuratie van de webhook te verliezen:
# Pause
curl -X PATCH https://api.nowistay.com/public/v1/webhooks/801 \
-H "Authorization: Bearer nis_access_token_example" \
-H "Content-Type: application/json" \
-d '{"status": "paused"}'
# Resume
curl -X PATCH https://api.nowistay.com/public/v1/webhooks/801 \
-H "Authorization: Bearer nis_access_token_example" \
-H "Content-Type: application/json" \
-d '{"status": "active"}'
# Delete permanently
curl -X DELETE https://api.nowistay.com/public/v1/webhooks/801 \
-H "Authorization: Bearer nis_access_token_example"
Je kunt in dezelfde aanroep ook de url, de lijst events of de description aanpassen. Het wijzigen van de URL roteert het ondertekeningsgeheim niet.
# List all webhooks (optionally filtered by property)
curl "https://api.nowistay.com/public/v1/webhooks?propertyId=101" \
-H "Authorization: Bearer nis_access_token_example"
# Read one webhook
curl https://api.nowistay.com/public/v1/webhooks/801 \
-H "Authorization: Bearer nis_access_token_example"
Het antwoord van de lijst toont dezelfde velden als het antwoord bij het aanmaken, min het ondertekeningsgeheim (dat wordt alleen bij het aanmaken teruggegeven).
https://user:pass@... wordt geweigerd).localhost, geen privé- of gereserveerde IP-bereiken. Nowistay lost de hostnaam ook op het moment van levering op en blokkeert aanroepen die naar privéadressen verwijzen.id uit de body op en sla het event over als je het al hebt verwerkt.2xx en verwerk het event in een achtergrondtaak als het zwaar is.Nowistay-Webhook-Event-Id en het request-id in je logs. Dat versnelt de support.GET /public/v1/bookings/{id} aan.Gidsen voor hosts: lees de blog.
Klaar om je verhuur op de automatische piloot te zetten?