Bookings
Read, record, update and cancel meetings booked through Signal's Scheduler.
A booking is a meeting on the calendar of someone in your workspace, usually made through a Scheduler booking page. Bookings can link to an Account, a Contact, a prospect contact and a Deal.
The booking object#
| Field | Type | Notes |
|---|---|---|
id |
string | 25-character ID. |
title |
string or null | |
invitee_name |
string | The person the meeting is with. |
invitee_email |
string or null | |
invitee_phone |
string or null | |
start_at |
string or null | ISO 8601 timestamp. |
end_at |
string or null | ISO 8601 timestamp. |
duration |
integer or null | Length in minutes. |
status |
string or null | scheduled, rescheduled or cancelled. |
notes |
string or null | |
event_type_id |
string or null | The Scheduler event type it was booked through. |
owner_id |
string or null | User ID of the host. |
account_id |
string or null | |
contact_id |
string or null | |
prospect_id |
string or null | |
deal_id |
string or null | |
timezone |
string or null | IANA time zone, such as America/New_York. |
location_type |
string or null | For example zoom, google_meet, teams, phone, in_person or other. |
location_details |
string or null | A link, phone number or address. |
cancelled_at |
string or null | When it was canceled. |
cancel_reason |
string or null | |
created_at |
string | ISO 8601 timestamp. |
updated_at |
string | ISO 8601 timestamp. |
{
"id": "cm3ka3c8u0007ab7c4d5e6f7g",
"title": "Product demo",
"invitee_name": "Sam Lee",
"invitee_email": "sam.lee@fabrikam.example",
"invitee_phone": null,
"start_at": "2026-11-18T16:00:00.000Z",
"end_at": "2026-11-18T16:30:00.000Z",
"duration": 30,
"status": "scheduled",
"notes": null,
"event_type_id": null,
"owner_id": "5b8d1f3a-7e2c-4a9b-b6d4-1c3e5f7a9b20",
"account_id": null,
"contact_id": null,
"prospect_id": "e4b7c1d9-2f6a-4b3e-9c8d-5a1f7e2b4c63",
"deal_id": null,
"timezone": "America/New_York",
"location_type": "zoom",
"location_details": "https://zoom.us/j/0000000000",
"cancelled_at": null,
"cancel_reason": null,
"created_at": "2026-11-12T09:30:00.000Z",
"updated_at": "2026-11-12T09:30:00.000Z"
}
List bookings#
GET /bookings · Scope: bookings:read
Returns bookings newest first (by when they were made, not when they take place).
Query parameters#
| Parameter | Type | Required | Notes |
|---|---|---|---|
status |
string | No | Such as scheduled or cancelled. |
contact_id |
string | No | |
deal_id |
string | No | |
owner_id |
string | No | |
limit |
integer | No | 1 to 100. Default 20. |
cursor |
string | No | meta.cursor from the previous page. |
Example#
curl "https://crm.empiraa.app/api/v1/bookings?status=scheduled" \
-H "Authorization: Bearer YOUR_API_KEY"
const res = await fetch("https://crm.empiraa.app/api/v1/bookings?status=scheduled", {
headers: { Authorization: "Bearer YOUR_API_KEY" },
});
const { data, meta } = await res.json();
Response 200#
An array of booking objects in data; meta has cursor and hasMore.
Record a booking#
POST /bookings · Scope: bookings:write · Supports Idempotency-Key
Adds a booking to Signal, for example one made in another scheduling tool.
Request body#
| Field | Type | Required | Notes |
|---|---|---|---|
invitee_name |
string | Yes | |
title |
string or null | No | |
invitee_email |
string or null | No | |
invitee_phone |
string or null | No | |
start_at |
string or null | No | ISO 8601 timestamp. |
end_at |
string or null | No | ISO 8601 timestamp. |
duration |
integer or null | No | Minutes. |
status |
string or null | No | Defaults to scheduled. |
notes |
string or null | No | |
event_type_id |
string or null | No | |
owner_id |
string or null | No | A user ID from GET /users. |
account_id |
string or null | No | |
contact_id |
string or null | No | |
prospect_id |
string or null | No | |
deal_id |
string or null | No | |
timezone |
string or null | No | Defaults to UTC. |
location_type |
string or null | No | |
location_details |
string or null | No |
Example#
curl -X POST https://crm.empiraa.app/api/v1/bookings \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 0f2d4b6a-8c1e-4a3b-9d5f-7e9a1c3b5d70" \
-d '{
"invitee_name": "Sam Lee",
"invitee_email": "sam.lee@fabrikam.example",
"title": "Product demo",
"start_at": "2026-11-18T16:00:00Z",
"end_at": "2026-11-18T16:30:00Z",
"duration": 30,
"timezone": "America/New_York",
"owner_id": "5b8d1f3a-7e2c-4a9b-b6d4-1c3e5f7a9b20",
"prospect_id": "e4b7c1d9-2f6a-4b3e-9c8d-5a1f7e2b4c63"
}'
await fetch("https://crm.empiraa.app/api/v1/bookings", {
method: "POST",
headers: {
Authorization: "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
"Idempotency-Key": crypto.randomUUID(),
},
body: JSON.stringify({
invitee_name: "Sam Lee",
invitee_email: "sam.lee@fabrikam.example",
title: "Product demo",
start_at: "2026-11-18T16:00:00Z",
end_at: "2026-11-18T16:30:00Z",
duration: 30,
timezone: "America/New_York",
owner_id: "5b8d1f3a-7e2c-4a9b-b6d4-1c3e5f7a9b20",
prospect_id: "e4b7c1d9-2f6a-4b3e-9c8d-5a1f7e2b4c63",
}),
});
Response 201#
The new booking object in data.
Errors#
| Status | Code | When |
|---|---|---|
| 400 | INVALID_REQUEST |
invitee_name is missing, or start_at or end_at isn't a date. |
| 404 | NOT_FOUND |
A linked Account, Contact, Deal or prospect contact, or the event_type_id, isn't in this workspace (title says which), or owner_id isn't an active member of the workspace. |
Webhook events: none. Starts any Autopilot workflows that run when a booking is confirmed.
Get a booking#
GET /bookings/{id} · Scope: bookings:read
Example#
curl https://crm.empiraa.app/api/v1/bookings/cm3ka3c8u0007ab7c4d5e6f7g \
-H "Authorization: Bearer YOUR_API_KEY"
await fetch("https://crm.empiraa.app/api/v1/bookings/cm3ka3c8u0007ab7c4d5e6f7g", {
headers: { Authorization: "Bearer YOUR_API_KEY" },
});
Response 200#
The booking object in data.
Errors#
| Status | Code | When |
|---|---|---|
| 404 | NOT_FOUND |
No booking with that ID in this workspace. |
Update a booking#
PATCH /bookings/{id} · Scope: bookings:write
Send only the fields you want to change.
Request body#
| Field | Type | Notes |
|---|---|---|
title |
string or null | |
invitee_name |
string | |
invitee_email |
string or null | |
invitee_phone |
string or null | |
start_at |
string or null | ISO 8601 timestamp. |
end_at |
string or null | ISO 8601 timestamp. |
duration |
integer or null | Minutes. |
status |
string or null | Set cancelled to cancel. |
notes |
string or null | |
owner_id |
string or null | |
deal_id |
string or null | |
location_type |
string or null | |
location_details |
string or null | |
cancel_reason |
string or null | A non-empty reason also sets cancelled_at to now; null or empty clears cancelled_at. It doesn't change status. |
account_id, contact_id, prospect_id, event_type_id and timezone can't be changed after creation.
Example: cancel with a reason#
curl -X PATCH https://crm.empiraa.app/api/v1/bookings/cm3ka3c8u0007ab7c4d5e6f7g \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"status": "cancelled", "cancel_reason": "Invitee asked to move to next quarter"}'
await fetch("https://crm.empiraa.app/api/v1/bookings/cm3ka3c8u0007ab7c4d5e6f7g", {
method: "PATCH",
headers: { Authorization: "Bearer YOUR_API_KEY", "Content-Type": "application/json" },
body: JSON.stringify({ status: "cancelled", cancel_reason: "Invitee asked to move to next quarter" }),
});
Response 200#
The updated booking object in data.
Errors#
| Status | Code | When |
|---|---|---|
| 400 | INVALID_REQUEST |
start_at or end_at isn't a date. |
| 404 | NOT_FOUND |
No booking with that ID in this workspace, deal_id isn't a Deal in it, or owner_id isn't an active member of the workspace. |
Webhook events: none. Changing status to cancelled starts any Autopilot workflows that run when a booking is canceled.
Cancel a booking#
DELETE /bookings/{id} · Scope: bookings:write
Cancels the booking: sets status to cancelled and cancelled_at to now. The booking is kept.
Example#
curl -X DELETE https://crm.empiraa.app/api/v1/bookings/cm3ka3c8u0007ab7c4d5e6f7g \
-H "Authorization: Bearer YOUR_API_KEY"
await fetch("https://crm.empiraa.app/api/v1/bookings/cm3ka3c8u0007ab7c4d5e6f7g", {
method: "DELETE",
headers: { Authorization: "Bearer YOUR_API_KEY" },
});
Response 204#
No body.
Errors#
| Status | Code | When |
|---|---|---|
| 404 | NOT_FOUND |
No booking with that ID in this workspace. |
Webhook events: none. Starts any Autopilot workflows that run when a booking is canceled (unless it was already canceled).

