Webhooks let your app react to things happening in a merchant's account (bookings, payments, …) without polling. RentalTide signs every delivery and retries failures with exponential backoff.
Setup
- Register a Webhook URL and a Webhook secret on your app in the partner portal.
- Request the
webhooks:receivescope. - Verify the signature on every request before trusting it.
Use the Test webhook button in the developer portal to send a signed sample delivery to your endpoint at any time.
Event catalog
| Event | When |
|---|---|
booking.created | A new booking/order was created. |
booking.updated | A booking changed (notes, timing, add-ons, assets). |
booking.status_changed | A booking moved to a new status. |
booking.checked_in | A booking was checked in. |
booking.cancelled | A booking was cancelled. |
booking.rescheduled | A booking was rescheduled. |
payment.received | A payment was recorded against a booking. |
payment.refunded | A refund was issued. |
customer.created | A new customer was created. |
customer.updated | A customer record was updated. |
app.installed | Your app was installed by a merchant (provision here). |
app.uninstalled | Your app was uninstalled (deprovision / clean up here). |
The same list ships as WEBHOOK_EVENT_CATALOG in @rentaltide/app-sdk.
Payload
Every delivery is a JSON POST:
Verify the signature
The signature is v1= + HMAC_SHA256(secret, "{X-RentalTide-Timestamp}.{rawBody}") in hex. Compute it over the raw request body and compare in constant time. Reject deliveries whose timestamp is more than 5 minutes old (replay protection).
A complete runnable receiver is in the with-backend example.
Delivery & retries
- Respond
2xxquickly to acknowledge. Do slow work asynchronously. - Non-2xx (or a timeout) is retried with exponential backoff — 1m → 5m → 15m → 1h → 6h — up to 6 attempts, then the delivery is marked dead.
- Deliveries can arrive more than once; make your handler idempotent (e.g. dedupe on the
dataids).

