Agent skill
Guesty Webhooks Skill
Receive and verify Guesty webhooks (delivered by Svix). Use when setting up Guesty webhook handlers, debugging svix-signature verification, fetching the secret from GET /webhooks-v2/secret, or handling short-term rental events like reservation.created.v2, reservation.updated.v2, reservation.new, reservation.updated, and listing.updated.
Install this skill
npx skills add hookdeck/webhook-skills --skill guesty-webhooks
Guesty (property management for short-term rentals) sends webhooks through Svix. Every request is signed with the endpoint's signing secret and carries svix-id, svix-timestamp, and svix-signature headers. The event name is in the body's event field (not type).
When to Use This Skill
- How do I receive Guesty webhooks?
- How do I verify Guesty webhook signatures (
svix-signature)? - Where do I get the Guesty webhook secret?
- How do I handle
reservation.created.v2/reservation.updated.v2events? - How do I handle legacy
reservation.new/reservation.updatedevents? - Why is my Guesty webhook signature verification failing?
- How do I deduplicate Guesty webhooks?
Verification (core)
Signed content is ${svix-id}.${svix-timestamp}.${raw_, HMAC-SHA256 keyed with the base64-decoded bytes after the whsec_ prefix, base64-encoded. The header holds one or more space-separated v1,<signature> entries. Use the official svix SDK (Node and Python) — it handles all of that, the 5-minute timestamp tolerance, and constant-time comparison:
const { Webhook } = require('svix');
const wh = new Webhook(process.env.GUESTY_WEBHOOK_SECRET); // "whsec_..." from GET /webhooks-v2/secret
wh.verify(rawBody, { // raw Buffer/string, never re-serialized JSON
'svix-id': req.headers['svix-id'],
'svix-timestamp': req.headers['svix-timestamp'],
'svix-signature': req.headers['svix-signature'],
}); // throws WebhookVerificationError on a bad signature or stale timestamp
const event = JSON.parse(rawBody.toString('utf8'));
// event.event === 'reservation.created.v2', event.meta.eventId, event.data / event.reservation / ...
Python: from svix.webhooks import Webhook and call Webhook(secret).verify(raw_ the same way.
For complete handlers with tests, see examples/express/, examples/nextjs/, examples/fastapi/.
Common Event Types
The payload is { "event": "<name>", "meta": { "eventId": ... }, <object>: {...} }. The object key depends on the event: data (reservation v2), reservation (legacy reservation), listing, guest, payment.
| Event | Object key | Triggered When |
|---|---|---|
reservation.created.v2 | data | A booking request or instant booking is created (recommended) |
reservation.updated.v2 | data | Stay details change; meta.changedFields / meta.subType say what changed |
reservation.new | reservation | Legacy: booking created (being phased out by end of Feb 2027) |
reservation.updated | reservation | Legacy: reservation, folio, or payment changed; also has reservationBefore |
listing.new | listing | A listing is created |
listing.updated | listing | A listing's settings or content change |
listing.removed | listing | A listing is deleted |
guest.created | guest | A guest record is created |
payments.received | payment | A reservation payment succeeds |
Other events: reservation_, calendar.updated.v2, listing.calendar.updated, reservation.messageReceived, reservation.messageSent, guest.updated, guest.deleted, task.created, task.updated, task.deleted, guest-folio.created, guest-folio.updated, and the other payments.* events. See references/overview.md.
Environment Variables
# Per-endpoint signing secret (Svix default format: whsec_ + base64 key)
GUESTY_WEBHOOK_SECRET=whsec_xxxxx
Retrieve it with GET https://open-api.guesty.com/v1/webhooks-v2/secret?url=<your endpoint URL> or from Guesty's webhooks developer dashboard (Developer tools → Webhooks). Deleting and recreating a subscription can issue a new secret.
Local Development
# Start tunnel (no account needed)
npx hookdeck-cli listen 3000 guesty --path /webhooks/guesty
Guesty subscriptions are created through the API (POST /v1/webhooks) and the URL must be HTTPS on port 443, so register the Hookdeck tunnel URL.
Key Gotchas
- Raw body — verify the exact bytes Guesty sent; parse JSON only afterwards.
- Deduplicate on
svix-idand onmeta.eventId(when present). Recovery processes can re-emit old events. - Out-of-order delivery — order by
__v/lastUpdatedAt(ormeta.publishedAton v2), and re-fetch the object from the API. - Respond 2xx within 15 seconds; anything else (including 3xx) is retried on a schedule spanning about 28 hours.
Reference Materials
- references/overview.md - Guesty webhook concepts, events, payloads
- references/setup.md - Creating subscriptions via the API, getting the secret
- references/verification.md - Signature verification details and gotchas