Documentation menu

Guesty

A confirmed booking in Guesty sends the guest your rental agreement and the waivers that property needs, and you see who has signed before they reach the door.

Beta. It is built against Guesty's published Open API and tested against it on our side; it has not yet run against a live Guesty account. It uses the Open API credentials you create yourself, which needs no partnership — the Guesty Marketplace listing is a separate programme we have not joined yet. Links go by email. They go by text only to a guest whose consent to receive texts from you is on file in SignSealer: a booking system knowing a phone number is not that guest agreeing to be texted, and SignSealer never treats it as if it were.

Before you start

  • A SignSealer account, with the terms signed, and a published form for each document you want signed.
  • Admin access to your Guesty account, to create an OAuth application.
  • Requirements that say what each stay needs — a rental agreement for the primary guest at least.

Connect Guesty

  1. In Guesty, open Integrations → Developer tools → OAuth applications and create a new application named SignSealer. Copy the client ID and the client secret (Guesty shows the secret once).
  2. In SignSealer, open Integrations, choose Guesty → Connect, and paste both.
  3. Choose whether bookings send straight away and whether a cancellation voids what is unsigned, then press Connect Guesty.
  4. SignSealer asks Guesty for a token with those credentials (proving them), registers its webhook for reservation.created.v2 and reservation.updated.v2, and fetches the webhook's signing secret. You land on the connection's page.
  5. Make or change a test reservation in Guesty and watch it arrive under the connection's activity.

What SignSealer sets up in Guesty

One webhook subscription (POST /v1/webhooks in Guesty's Open API) pointing at this connection's delivery address, for the two v2 reservation events. Guesty's legacy reservation events are being phased out by the end of 2026, which is why only the v2 events are used. Disconnecting deletes the subscription; a new address re-registers it.

What comes across

GuestyIn SignSealerNotes
_idReservation external IDKeys the reservation, so every update is the same reservation
confirmationCode, listing.titleLabel“Harbour Cottage · GY-100”
checkInDateLocalized / checkOutDateLocalizedStarts on / ends onThe property's own dates; minority is judged on check-in
guest.firstName + lastName, email, phonePrimary guestRecognised on update by the Guesty guest ID
guestsCount, numberOfGuestsFacts: guests, adults, minors
integration.platform or sourceFact: channelairbnb2, homeaway, manual …
listingIdFacts: property, property_name
statusWhat happensconfirmed / checked in: worked · inquiry, reserved: ignored · canceled, declined, expired: cancelled

Requirements that read it

The reservation carries these facts, which a requirement's condition can read: guests, adults, minors, channel, property and property_name. For example, a waiver for every adult on stays with more than six guests:

{ "fact": "guests", "op": "gt", "value": 6 }

Rules are set under Requirements in the dashboard or through the API; see Reservations and packets.

How a delivery is proven

Guesty signs each delivery with Svix: svix-id, svix-timestamp and svix-signature, an HMAC-SHA256 of the id, timestamp and exact body under the endpoint's own secret. SignSealer checks it in constant time, refuses a timestamp more than five minutes away, and only then reads the body. The reservation event carries no guest details, so SignSealer then reads the reservation and guest from Guesty's API. Guest events (guest.*) are accepted and ignored.

Settings

SettingChoicesWhat it does
When a booking arrivesSend straight away (default) · Build the list and wait Straight away starts everything the packet owes as soon as the booking is worked. Waiting builds the reservation and its packet and sends nothing until somebody presses Send on the reservation, or your code calls POST /v1/packets/{id}/start.
When a booking is cancelledVoid what nobody has signed (default) · Leave it Voiding marks every unfinished document with the reason and the packet void. Anything already signed is kept: an executed waiver is evidence of what was agreed.

What each guest is sent is decided by your requirements, not by the integration: the reservation's facts (dates, guest counts, property, channel) meet your rules, and each rule says who owes what — the primary guest, every adult, or a guardian for each minor.

Texting and consent

Signing links go by email. They also go by text only when SignSealer holds that guest's consent to receive texts from your business, recorded with the exact words they agreed to — at your counter, on your booking form through POST /v1/sms-consents, or on SignSealer's own opt-in. That check runs when the link is queued (app.may_text), not in the integration.

No booking system can give SignSealer that consent, so none is treated as if it could. Each adapter records what the provider's data said — VERIFIED_CONSENT, NO_CONSENT or INSUFFICIENT_EVIDENCE — and only NO_CONSENT changes anything: the guest's number is not written at all. Every provider built so far can only ever say INSUFFICIENT_EVIDENCE. The connection's activity shows, for each guest with a number, whether the link was also texted and why not.

How to record consent you took yourself.

Duplicates, order and retries

  • Once. A delivery is recorded once per connection and event id. A provider that redelivers the same event gets 200 {"duplicate": true} and nothing happens twice.
  • Newest wins. Each event means "read this booking as it is now". A newer event about a booking supersedes an older one still waiting, and one booking is never worked twice at once.
  • Nothing is sent twice. Guests are recognised by their id in the provider (or by address and name), so an update keeps each guest's link to what they were already sent.
  • Retries. A failure is retried after 1, 2, 4, 8 … minutes, up to six hours apart, and gives up after eight tries. It is then listed, with its reason, under the connection's activity, where it can be tried again once whatever refused it is fixed.
  • Refused credentials. If the provider refuses SignSealer's credentials, the connection goes to needs attention and stops working events until new credentials are given. What arrives meanwhile is kept and worked afterwards.
  • Retention. What arrived is cleared thirty days after it was worked; the outcome and the reservation it made are kept.

Troubleshooting

What you seeWhyWhat to do
“Guesty refused our credentials” when connectingThe client ID or secret is wrong, or the application was deletedCreate the application again in Guesty and paste the new pair
Connection says needs attentionGuesty stopped accepting the credentials (rotated or deleted)Paste new credentials on the connection's page; waiting reservations are then worked
An inquiry never arrives as a reservationInquiries and holds are not bookingsIt is worked when Guesty marks it confirmed
Deliveries refused (401) in Guesty's webhook logThe signing secret changed because the subscription was re-created outside SignSealerPress New address on the connection; SignSealer re-registers and keeps the new secret
A guest got nothingThe guest has no email in Guesty, or no requirement appliesThe activity names the guest and the reason; add the email in Guesty or check Requirements

Guesty's limits

Guesty allows five tokens per OAuth application per day and a token lasts 24 hours, so SignSealer keeps its token sealed and reuses it until ten minutes before it runs out. Guesty rate-limits the Open API per account (15 per second, 120 per minute, 5,000 per hour, shared across every tool using your account); SignSealer makes one read per reservation change. Guesty retries a failed delivery on a schedule up to about a day and a half, and disables an endpoint after five days of failures.

Guesty Marketplace

This connection uses Guesty's Open API with credentials you issue. Guesty asks Marketplace partners not to use Open API credentials (and Marketplace keys do not work with the Open API), so the Marketplace listing will be a separate connection when SignSealer joins it.

Pausing and disconnecting

Pause keeps recording what arrives and works nothing until you resume. New address stops the old delivery address at once (and re-registers the webhook with the provider where SignSealer set it up). Disconnect revokes the connection's key, clears its credentials, removes the webhook from the provider where it can, and closes the address. The reservations and documents it made stay, with where they came from.

From your own code

curl https://api.signsealer.com/v1/integrations -H "Authorization: Bearer $KEY"
curl https://api.signsealer.com/v1/integrations/$CONNECTION/events -H "Authorization: Bearer $KEY"

The first lists every provider with its status and your connections with their state; the second is what arrived from one connection and what became of it. Neither ever returns a credential, a delivery address or what arrived. Both need the signing:read scope. Connecting happens in the dashboard, where the provider confirms the credentials. See the API reference.

Ready to build? An API key takes a minute in the portal, and the free plan covers the first 25 agreements a month.

Get an API key