Event types
Every Dolores webhook event with its trigger and payload shape.
Dolores v1 emits five appointment-status events. Each one carries a full snapshot of the appointment plus a previous_attributes diff on updates.
Envelope (shared by every event)
{
"id": "evt_01HXY...",
"object": "event",
"type": "appointment.confirmed",
"created": 1717685011,
"livemode": true,
"api_version": "2026-06-01",
"data": {
"object": { /* full appointment resource */ },
"previous_attributes": { /* present on updates */ }
}
}createdis Unix seconds, not milliseconds.livemodematches the registered endpoint'slivemodeflag. Test deliveries never reach live endpoints; live deliveries never reach test endpoints.data.objectis the appointment as it exists at the moment the event fires.data.previous_attributesis only present on update-shaped events (confirmed,rescheduled,cancelled,failed). It contains just the fields that changed and their old values.
appointment.created
Fires when a new appointment row lands with status = pending or status = reserved. Typically triggered by the voice agent during a live booking flow.
{
"id": "evt_01HXY...",
"object": "event",
"type": "appointment.created",
"created": 1717685011,
"livemode": true,
"data": {
"object": {
"id": "appt_01HXY...",
"object": "appointment",
"customer_id": "cust_01HXY...",
"session_id": "sess_01HXY...",
"appointment_at": "2026-06-10T15:00:00Z",
"status": "pending",
"notes": null,
"metadata": {},
"error_message": null,
"created_at": "2026-06-06T14:23:11Z",
"updated_at": "2026-06-06T14:23:11Z",
"livemode": true
}
}
}No previous_attributes — it's a creation.
appointment.confirmed
Fires when an appointment's status transitions from pending (or reserved) to confirmed. This is the most actionable event — at this point the customer has agreed to the booking and you should write it to your operational system.
{
"type": "appointment.confirmed",
"created": 1717685042,
"livemode": true,
"data": {
"object": {
"id": "appt_01HXY...",
"object": "appointment",
"customer_id": "cust_01HXY...",
"session_id": "sess_01HXY...",
"appointment_at": "2026-06-10T15:00:00Z",
"status": "confirmed",
"metadata": {},
"created_at": "2026-06-06T14:23:11Z",
"updated_at": "2026-06-06T14:23:42Z",
"livemode": true
},
"previous_attributes": { "status": "pending" }
}
}appointment.rescheduled
Fires when appointment_at changes via PATCH /v1/appointments/{id}. The old time appears in previous_attributes.appointment_at.
{
"type": "appointment.rescheduled",
"data": {
"object": {
"id": "appt_01HXY...",
"appointment_at": "2026-06-11T15:00:00Z",
"status": "confirmed",
...
},
"previous_attributes": { "appointment_at": "2026-06-10T15:00:00Z" }
}
}appointment.cancelled
Fires when status flips to cancelled via POST /v1/appointments/{id}/cancel or via the admin UI.
{
"type": "appointment.cancelled",
"data": {
"object": {
"id": "appt_01HXY...",
"status": "cancelled",
"error_message": "customer requested cancellation",
...
},
"previous_attributes": { "status": "confirmed" }
}
}error_message carries the cancellation reason if one was supplied.
appointment.failed
Fires when the workflow's confirmation step reports a downstream error (typically because an external scheduling integration rejected the booking). The appointment is left with status = failed — operationally treat it like a cancelled booking, but with a payload hint pointing at the failure.
{
"type": "appointment.failed",
"data": {
"object": {
"id": "appt_01HXY...",
"status": "failed",
"error_message": "external scheduler returned 503",
...
},
"previous_attributes": { "status": "pending" }
}
}Filtering events
When registering an endpoint, pass event_filters to subscribe to a subset:
{
"url": "https://api.example.com/dolores/webhook",
"event_filters": ["appointment.confirmed", "appointment.cancelled"]
}Wildcards are supported — appointment.* matches all five event types in this section. An empty event_filters array (or omitting it entirely) subscribes to every event Dolores currently emits.
What's not (yet) emitted
These are on the roadmap but not in v1:
appointment.completed— appointment time elapsed without cancellationappointment.no_show— heuristic detection of customer no-showscustomer.*— created / updated / deletedsession.*— call lifecycle
If you need any of these, let us know.