Skip to contentSkip to Content

Webhooks API

Subscribe to real-time events from your Rentalot account. When events occur (new inquiry, message sent, showing booked, etc.), Rentalot sends a POST request to your URL with the event payload.

Event Types

EventDescription
inquiry.createdA new contact reached out for the first time
message.receivedAn inbound message was received from a contact
message.sentAn outbound message was sent to a contact
showing.bookedA showing was scheduled
showing.cancelledA showing was cancelled
contact.updatedA contact’s details were updated
property.updatedA property listing was updated
workflow.createdA new workflow template was created
workflow.updatedA workflow template was updated
workflow.deletedA workflow template was deleted
workflow.completedA workflow run finished

List Webhooks

GET /api/v1/webhooks

Response:

{ "data": [ { "id": "wh_abc123", "url": "https://example.com/webhooks/rentalot", "events": ["inquiry.created", "showing.booked"], "active": true, "description": "CRM sync", "lastDeliveredAt": "2026-02-11T14:30:00Z", "createdAt": "2026-02-01T10:00:00Z" } ], "pagination": { "page": 1, "limit": 20, "total": 2 } }

Create Webhook

POST /api/v1/webhooks

Request Body:

{ "url": "https://example.com/webhooks/rentalot", "events": ["inquiry.created", "message.received", "showing.booked"], "description": "CRM sync webhook" }
FieldTypeRequiredDescription
urlstringYesHTTPS URL to receive events
eventsstring[]YesAt least one event type from the list above
descriptionstringNoHuman-readable label (max 500 chars)

Response 201 Created:

{ "data": { "id": "wh_abc123", "url": "https://example.com/webhooks/rentalot", "events": ["inquiry.created", "message.received", "showing.booked"], "active": true, "description": "CRM sync webhook", "secret": "whsec_a1b2c3d4e5f6..." } }

The secret is only returned once on creation. Save it — you’ll need it to verify webhook signatures.

Get Webhook

GET /api/v1/webhooks/:id

Update Webhook

PATCH /api/v1/webhooks/:id
{ "events": ["inquiry.created", "showing.booked"], "active": false }
FieldTypeDescription
urlstringNew HTTPS endpoint
eventsstring[]Replace subscribed events
activebooleanEnable or disable delivery
descriptionstringUpdate label

Delete Webhook

DELETE /api/v1/webhooks/:id

Returns 204 No Content.

Test Webhook

POST /api/v1/webhooks/:id/test

Sends a test ping event to the webhook URL. Use this to verify your endpoint is reachable and correctly handling payloads.

Response 200 OK:

{ "data": { "success": true, "statusCode": 200, "deliveredAt": "2026-02-11T15:00:00Z" } }

Payload Format

Every webhook delivery is a POST request with a JSON body:

{ "event": "showing.booked", "data": { "id": "showing_abc123" }, "timestamp": "2026-02-11T14:30:00Z", "webhookId": "wh_abc123" }

Verifying Signatures

Every delivery includes these headers:

HeaderDescription
X-Webhook-Signaturesha256={HMAC-SHA256 hex digest}
X-Webhook-IdUnique delivery ID
X-Webhook-TimestampISO 8601 delivery timestamp

To verify, compute the HMAC-SHA256 of the raw request body using your webhook secret and compare with the signature header.

import crypto from "crypto"; function verifyWebhook(body, signature, secret) { const expected = crypto .createHmac("sha256", secret) .update(body) .digest("hex"); return signature === `sha256=${expected}`; }

Retry Policy

Failed deliveries (non-2xx response or timeout) are retried up to 3 times with exponential backoff: 1 minute, 5 minutes, 30 minutes.

After 10 consecutive failures, the webhook is automatically deactivated. Re-enable it via PATCH with active: true after fixing your endpoint.

Idempotency

POST /api/v1/webhooks supports the Idempotency-Key header.