Webhooks
Registering a webhook
Visit the Webhooks page in the SavvyCal Dashboard and follow the prompts to register a new webhook.
For platforms, register webhooks on the platform settings page under the "Platform webhooks" section.
Listening for events
When an event occurs that triggers a webhook, we will send an HTTP POST to the URL you specified, with a JSON-encoded body of this shape:
POST /my-webhook-receiver HTTP/1.1
host: https://myapp.com
user-agent: SavvyCal Webhooks (https://savvycal.app)
x-savvycal-signature: sha256=6CAA4DEF5C3463B785E885FF19B8987B348E19399D2C5FB291274EDFA7128105
x-savvycal-webhook-id: wh_XXXXXXXXXX
content-type: application/json
{
"id": "evt_d025a96ac0c6",
"account_id": "acct_d025a96ac0c6",
"version": "1.0",
"created_at": "2025-03-12T12:34:55Z",
"data": {
"type": "appointment.created",
"object": {...}
}
}
Event types
The following event types are available. The Schema definitions referenced in the table below represent the shape of the data field in the webhook payload.
| Event Type | Description |
|---|---|
account_user.created | Emitted when a new account user is created. (Schema) |
account_user.deleted | Emitted when an account user is removed. (Schema) |
account_user.updated | Emitted when an existing account user is updated. (Schema) |
appointment.created | Emitted when a new appointment is created. (Schema) |
appointment.rescheduled | Emitted when an existing appointment is rescheduled. (Schema) |
appointment.canceled | Emitted when an existing appointment is canceled. (Schema) |
appointment.confirmed | Emitted when an existing appointment is confirmed. (Schema) |
appointment.deleted | Emitted when an existing appointment is deleted. (Schema) |
booking_intent.abandoned | Emitted when a booking intent is abandoned. (Schema) |
booking_intent.completed | Emitted when a booking intent is completed. (Schema) |
booking_intent.created | Emitted when a new booking intent is created. (Schema) |
booking_intent.updated | Emitted when an existing booking intent is updated. (Schema) |
block.created | Emitted when a new block is created. (Schema) |
block.updated | Emitted when an existing block is updated. (Schema) |
block.deleted | Emitted when an existing block is deleted. (Schema) |
client.created | Emitted when a new client is created. (Schema) |
client.deleted | Emitted when a client is deleted. (Schema) |
client.updated | Emitted when an existing client is updated. (Schema) |
connected_account.created | Emitted when a new calendar integration is connected. (Schema) |
connected_account.deleted | Emitted when a calendar integration is disconnected. (Schema) |
connected_account.refresh_failed | Emitted when an OAuth token refresh permanently fails. (Schema) |
connected_account.reconnected | Emitted when a previously failed integration is reconnected. (Schema) |
provider.created | Emitted when a new provider is created. (Schema) |
provider.deactivated | Emitted when a provider is deactivated. (Schema) |
provider.reactivated | Emitted when a previously deactivated provider is reactivated. (Schema) |
provider.updated | Emitted when an existing provider is updated. (Schema) |
provider_schedule.created | Emitted when a new provider schedule is created. (Schema) |
provider_schedule.deleted | Emitted when a provider schedule is deleted. (Schema) |
provider_schedule.updated | Emitted when an existing provider schedule is updated. (Schema) |
service.created | Emitted when a new service is created. (Schema) |
service.deleted | Emitted when a service is deleted. (Schema) |
service.updated | Emitted when an existing service is updated. (Schema) |
service_provider.created | Emitted when a provider is added to a service. (Schema) |
service_provider.deleted | Emitted when a provider is removed from a service. (Schema) |
Sensitive fields
Webhook payloads err on the side of caution when it comes to personally identifiable information. Fields like first_name, last_name, email, and phone on client objects will be null in webhook payloads.
If you need access to these fields, fetch the full record via the API after receiving the webhook. For example, after receiving a client.created event, you can call GET /v1/clients/:id to retrieve the complete client data.