Receive real-time notifications when events occur in Pivot using webhooks.
Webhooks allow you to receive real-time notifications when events occur in Pivot. When an event happens, Pivot sends an HTTP POST request to your configured endpoint with details about the event.
To create a webhook, send a POST request to the webhooks endpoint:
POST /v1/organizations/{organization_id}/webhooksAuthorization: Bearer your_api_keyContent-Type: application/json
{ "content": { "name": "My Webhook", "description": "Notifications for room messages", "endpoint_url": "https://your-server.com/webhook", "subscriptions": [ { "subject_type": "WEBHOOK_SUBJECT_TYPE_ROOM", "subject_id": "<room_uuid>", "subscription_type": "WEBHOOK_SUBSCRIPTION_TYPE_MESSAGE_SENT", "filter": { "room_type": "chat" } } ] }}The response includes the webhook details and a secret for signature verification:
{ "webhook": { "id": "webhook-uuid", "organization_id": "org-uuid", "name": "My Webhook", "endpoint_url": "https://your-server.com/webhook", "status": "WEBHOOK_STATUS_ACTIVE", "subscriptions": [...] }, "secret": "your-webhook-secret"}Important: Store the secret securely. It cannot be retrieved again and is required to verify webhook signatures.
Triggered when a message is sent in a subscribed room.
Payload example:
{ "event_type": "message_sent", "subject": { "type": "room", "id": "room-uuid" }, "timestamp": "2026-01-01T12:00:00Z", "data": { "message_id": "msg-uuid", "room_id": "room-uuid", "user_id": "user-uuid", "status": "SENT", "created_at": "2026-01-01T12:00:00Z" }}Triggered when a room recording transcript is ready.
Payload example:
{ "event_type": "room_recording_transcript_published", "subject": { "type": "room", "id": "room-uuid" }, "timestamp": "2026-01-01T12:00:00Z", "data": { "recording_id": "recording-uuid", "room_id": "room-uuid", "created_at": "2026-01-01T12:00:00Z" }}Subscriptions define what entities trigger webhook notifications:
| Subject Type | Description |
|---|---|
WEBHOOK_SUBJECT_TYPE_ROOM | Events for a specific room |
WEBHOOK_SUBJECT_TYPE_SPACE | Events for all rooms in a space |
Optionally filter events using the filter object:
{ "subject_type": "WEBHOOK_SUBJECT_TYPE_ROOM", "subject_id": "room-uuid", "subscription_type": "WEBHOOK_SUBSCRIPTION_TYPE_MESSAGE_SENT", "filter": { "room_type": "chat" }}Available filter options:
room_type: Filter by room type (e.g., “chat”, “post”, “video”)All webhook payloads include security headers:
| Header | Description |
|---|---|
X-Pivot-Signature | HMAC-SHA256 signature of the payload |
X-Pivot-Event | The event type (e.g., “message_sent”) |
X-Pivot-Delivery | Unique delivery identifier |
const crypto = require('crypto');
function verifySignature(payload, signature, secret) { const expectedSignature = 'sha256=' + crypto.createHmac('sha256', secret).update(payload).digest('hex');
return crypto.timingSafeEqual( Buffer.from(signature), Buffer.from(expectedSignature) );}
// Usageapp.post('/webhook', (req, res) => { const signature = req.headers['x-pivot-signature']; const isValid = verifySignature( JSON.stringify(req.body), signature, process.env.WEBHOOK_SECRET );
if (!isValid) { return res.status(401).send('Invalid signature'); }
// Process the webhook res.status(200).send('OK');});GET /v1/organizations/{organization_id}/webhooksPATCH /v1/organizations/{organization_id}/webhooks/{webhook_id}
{ "content": { "name": "Updated Name", "status": "WEBHOOK_STATUS_INACTIVE" }}DELETE /v1/organizations/{organization_id}/webhooks/{webhook_id}GET /v1/organizations/{organization_id}/webhooks/{webhook_id}/logsLogs are retained for 30 days and include delivery status, response codes, and retry counts.
X-Pivot-Delivery header to detect duplicate deliveriesFailed webhook deliveries are retried up to 5 times with exponential backoff:
| Retry | Delay |
|---|---|
| 1 | 1 minute |
| 2 | 5 minutes |
| 3 | 30 minutes |
| 4 | 2 hours |
| 5 | 12 hours |
After all retries are exhausted, organization admins receive an email notification about the failed webhook.
| Action | Required Role |
|---|---|
| List webhooks | Organization reader role |
| Create/Update/Delete webhooks | Organization admin or super_admin |
When creating subscriptions, you must have admin access to the room’s space or the space itself.
Was this guide helpful?