Skip to content

Webhooks

When an event is triggered, a POST is sent to the registered URL with the following format:

Headers:

HeaderDescription
Content-Typeapplication/json
X-CitaPro-EventEvent name (e.g. booking.updated)
X-CitaPro-SignatureHMAC-SHA256 of the body using the webhook secret
X-CitaPro-Delivery-IdUnique UUID for this delivery
X-CitaPro-TimestampUnix timestamp of the delivery

Body structure:

{
"event": "booking.updated",
"aggregate_id": "550e8400-e29b-41d4-a716-446655440000",
"occurred_on": "2026-03-05 14:30:00",
"data": {
"startTime": "2026-04-01 14:00:00",
"endTime": "2026-04-01 15:00:00",
"status": "confirmed",
"internalNote": null,
"clientNote": null,
"payment_status": null,
"isFromWeb": false,
"isFromAgent": false,
"isFromApi": false,
"amount": 75.0,
"clientId": "550e8400-e29b-41d4-a716-446655440001",
"locationId": "550e8400-e29b-41d4-a716-446655440002",
"serviceId": "550e8400-e29b-41d4-a716-446655440003",
"personId": "550e8400-e29b-41d4-a716-446655440004",
"paymentId": null,
"businessAccountId": "550e8400-e29b-41d4-a716-446655440005",
"notifyClient": true,
"lastUpdatedBy": null,
"repeatGroupId": null,
"changes": {
"status": { "old": "pending", "new": "confirmed" },
"amount": { "old": 50.0, "new": 75.0 }
}
}
}

changes field (in *.updated events):

The data.changes field contains the fields that were modified. Each key is the field name and the value is an object with old (previous value) and new (new value). It is present in all *.updated events.

Tracked fields in booking.updated:

FieldType
startTimestring
endTimestring
statusstring
internalNotestring | null
clientNotestring | null
paymentStatusstring | null
amountnumber
clientIdstring
locationIdstring
serviceIdstring
personIdstring | null
paymentIdstring | null

Tracked fields in client.updated:

FieldType
firstnamestring
lastnamestring
emailstring
phonestring
docTypestring | null
docNumberstring | null
birthdatestring | null
addressstring | null
citystring | null
statestring | null
countrystring | null

Tracked fields in service.updated:

FieldType
namestring
durationinteger
domiciliaryboolean
virtualboolean
statusstring
showInMinisiteboolean
pricenumber
categoryIdstring
descriptionstring | null
sessionsinteger | null
simultaneousinteger | null

Tracked fields in person.updated:

FieldType
locationIdstring
firstNamestring
lastNamestring
specialtystring | null
emailstring
statusstring
showInMinisiteboolean
phonestring | null
addressstring | null
idTypestring | null
idNumberstring | null
birthdatestring | null
userIdstring | null

Tracked fields in custom_field.updated:

FieldType
namestring
fieldTypestring
requiredboolean
optionsarray | null
sortOrderinteger
showInMinisiteinteger
requiredInMinisiteinteger
showInIaAgentinteger
requiredInIaAgentinteger

Tracked fields in time_block.updated:

FieldType
namestring
startTimestring
endTimestring
locationIdstring
repetitionobject | null
providersstring[]

If changes is an empty object {}, no changes were detected in the tracked fields.

Signature verification: Compute HMAC-SHA256 of the raw body with your secret and compare to the X-CitaPro-Signature header. See the Webhooks guide for examples in Node.js, PHP, Python, Ruby, and Go.

Retries: If your endpoint does not respond with a 2xx status code, delivery is retried up to 3 times with progressive backoff (10s, 60s, 5min).


GET /v1/webhooks

Returns all webhook endpoints configured for the business.

Success: 200 OK — (same JSON as Spanish docs)

POST /v1/webhooks
FieldTypeRequiredDescription
urlstringYesHTTPS endpoint URL
eventsstring[]YesEvents to subscribe to (min 1)

Available events: booking.created, booking.updated, booking.deleted, booking.status.updated, client.created, client.updated, client.deleted, service.updated, person.updated, person.deleted, custom_field.updated, custom_field.deleted, time_block.created, time_block.updated, time_block.deleted.

Success: 201 Created — Response includes secret only on creation.

PUT /v1/webhooks/{id}

Body: url, events, isActive (all required).

Success: 204 No Content

DELETE /v1/webhooks/{id}

Deletes the webhook and its delivery history.

Success: 204 No Content