Capturia measures its ads and site traffic with the Meta pixel and Google Analytics. You can decline at any time. Learn more

FR

Bookings

3 endpoints

get/v1/bookings

List bookings in the schedule

Returns the paginated list (cursor v2) of bookings in the schedule of the key's account: all its calendars, all its hosts. Bookings archived from the dashboard are excluded. Stable sort start_datetime DESC, id DESC — the furthest-out bookings first, then the history.

Filters

  • ?from (ISO 8601) — start_datetime >= from
  • ?to (ISO 8601) — start_datetime <= to
  • ?status — confirmed, cancelled, completed, or no_show
  • ?event_type_id — a calendar of the account
  • ?contact_id — a contact of the account

An unreadable filter is rejected with 400 validation_error, with the field and the reason (invalid_datetime, invalid_value, invalid_format); an invalid cursor or limit, 400 invalid_request. An event_type_id or a contact_id from another account returns an empty list.

Required scopes: bookings:read

Query parameters

NameTypeRequiredDescription
fromstringoptionalOnly bookings where start_datetime >= from.
tostringoptionalOnly bookings where start_datetime <= to.
statusstringoptionalExact match on status.
event_type_idstringoptionalOnly bookings on this calendar.
contact_idstringoptionalOnly bookings for this contact.

Responses

StatusDescription
200

Paginated list of bookings.

400

The request is malformed (missing header, invalid JSON, invalid parameter).

401

Unknown API key or invalid format.

403

Authorization denied. Two causes, distinguished by code: insufficient_scope (the key lacks the required scope — details.required_scope) or feature_not_available (the public API or the targeted module isn't included in the account's plan — details.feature names the feature, e.g. public_api, quotes). A plan denial is final for the key: don't retry; the account must change plans.

429

The per-window request quota has been exceeded for this API key or endpoint.

500

Unexpected server error. Always include the request_id when contacting support.

Example request

curl -X GET 'https://api.capturia.io/v1/bookings' \
  -H 'Authorization: Bearer cap_live_<your-key>' \
  -H 'Content-Type: application/json'
post/v1/bookings

Book an appointment

Books an appointment in the account's schedule, on one of its calendars, through the same service as the booking page and the dashboard. The calendar's rules apply: its active hosts, their hours and their Google Calendar, the booking window, the slot cadence, the daily maximum, group sessions, required questions, the access rule, and a single upcoming booking per contact on this calendar. The requested time is honored or rejected with its reason — never replaced with another. The duration is the calendar's; the host receives their notification and the event is added to their calendar as for any booking.

Each successful call creates a booking: don't replay a call that succeeded.

Rejections

The details.reason field states why, in a stable way:

Statuscodedetails.reason
400validation_errorslot_in_past, outside_window, off_cadence (details.field = "start_datetime"), contact_or_guest_required, contact_without_email, or the code of the failing question (details.field = "form_responses.<id>", details.questions: the calendar's questions)
404resource_not_found— (details.field: event_type_id, contact_id, or host_id)
409duplicate_resourcealready_booked (details.existing_booking_id)
422business_rule_violationcalendar_without_hosts, host_not_on_calendar, host_unavailable (details.causes), slot_unavailable, contact_archived, lead_not_qualified
503service_unavailable— (retry after Retry-After)

A field format error (400 validation_error) carries details as a list [{ field, reason }].

Required scopes: bookings:write

Request body

PropertyTypeRequiredDescription
event_type_idstringrequiredActive calendar of the account. An unknown or inactive calendar, or one from another account, is rejected with 404 resource_not_found (details.field = "event_type_id").
start_datetimestringrequiredStart of the booking, ISO 8601. The offset is optional: without an offset, the time is read as UTC. Prefer an explicit offset (2026-11-10T10:00:00-05:00).
contact_idstringoptionalExisting contact of the account. An unknown contact or one from another account is rejected with 404 resource_not_found (details.field = "contact_id"); an archived contact, 422 (contact_archived); a contact without an email and without guest_email, 400 (contact_without_email).
guest_namestringoptionalGuest's full name. Required without contact_id.
guest_emailstringoptionalGuest's email. Required without contact_id.
guest_phonestring | nulloptionalGuest's phone number (E.164 recommended). Taken into account with guest_name + guest_email.
host_idstringoptionalTeam member who should hold the booking. The requested host is honored or rejected with its reason, never replaced: unknown to the account, 404 resource_not_found (details.field = "host_id"); not a host of this calendar, 422 host_not_on_calendar; busy or outside their hours, 422 host_unavailable. Without host_id: the contact's sales rep if they can take the slot, otherwise the calendar's rotation.
timezonestring | nulloptionalGuest's IANA time zone (e.g. America/Montreal). If absent: the contact's, otherwise the calendar's. An unknown time zone or a bare offset (-04:00) is rejected: 400 validation_error, reason invalid_timezone.
notesstring | nulloptionalFree-form notes.
form_responsesobjectoptionalAnswers to the calendar's form: one entry per question, under the question's identifier, in the form { "value": ... }. value is text, a number for a numeric question, one of the options for a choice question, or a list of options for a multiple-choice question. A calendar with a required question rejects a booking without its answer: 400 validation_error, details.field = "form_responses.<id>". Every form rejection includes details.questions, the calendar's questions (id, label, type, required, options).

Responses

StatusDescription
201

Booking created.

400

Parameter or body validation failed.

401

Unknown API key or invalid format.

403

Authorization denied. Two causes, distinguished by code: insufficient_scope (the key lacks the required scope — details.required_scope) or feature_not_available (the public API or the targeted module isn't included in the account's plan — details.feature names the feature, e.g. public_api, quotes). A plan denial is final for the key: don't retry; the account must change plans.

404

The requested resource doesn't exist (or isn't within the tenant's scope).

409

The lead already has an upcoming booking on this calendar (duplicate_resource, reason already_booked, with details.existing_booking_id).

415

The Content-Type header is missing or not supported for this endpoint.

422

The requested time or host can't be honored: calendar without an active host (calendar_without_hosts), host who isn't a host of this calendar (host_not_on_calendar), host unavailable (host_unavailable, causes in details.causes: outside_window, outside_hours, other_booking, blocked_time, google_busy, daily_max), slot taken or full (slot_unavailable), archived contact (contact_archived), lead excluded by the calendar's access rule or disqualified (lead_not_qualified).

429

The per-window request quota has been exceeded for this API key or endpoint.

500

Unexpected server error. Always include the request_id when contacting support.

503

Service temporarily unavailable (maintenance, external dependency down, degraded infrastructure). Clients should retry with exponential backoff.

Example request

curl -X POST 'https://api.capturia.io/v1/bookings' \
  -H 'Authorization: Bearer cap_live_<your-key>' \
  -H 'Content-Type: application/json' \
  -d '{
  "event_type_id": "2b3c4d5e-6f7a-4b9c-8d1e-2f3a4b5c6d7e",
  "start_datetime": "2026-11-10T10:00:00-05:00",
  "contact_id": "0a1b2c3d-4e5f-4a7b-8c9d-0e1f2a3b4c5d",
  "notes": "Premier rendez-vous découverte"
}'
delete/v1/bookings/{id}

Cancel a booking

Soft cancel — the booking is not deleted: its status changes to cancelled and cancelled_at is timestamped, like a cancellation made in the dashboard. The event is removed from the host's calendar, the host is notified, and the cancellation is recorded as made by one of your team's integrations. The 200 response returns these 3 fields (not 204 No Content).

Only a confirmed booking can be cancelled. A booking that is already cancelled returns 422 business_rule_violation (reason already_cancelled); a booking that was held or marked as a no-show, 422 (reason booking_not_cancellable). A booking from another account is not found (404).

To change the time, cancel and book again, or reschedule from the dashboard — there is no PATCH.

Required scopes: bookings:write

Responses

StatusDescription
200

Booking cancelled. Returns the cancellation status and timestamp.

401

Unknown API key or invalid format.

403

Authorization denied. Two causes, distinguished by code: insufficient_scope (the key lacks the required scope — details.required_scope) or feature_not_available (the public API or the targeted module isn't included in the account's plan — details.feature names the feature, e.g. public_api, quotes). A plan denial is final for the key: don't retry; the account must change plans.

404

The requested resource doesn't exist (or isn't within the tenant's scope).

422

The booking is already cancelled (already_cancelled), or it was held or marked as a no-show (booking_not_cancellable).

429

The per-window request quota has been exceeded for this API key or endpoint.

500

Unexpected server error. Always include the request_id when contacting support.

Example request

curl -X DELETE 'https://api.capturia.io/v1/bookings/{id}' \
  -H 'Authorization: Bearer cap_live_<your-key>' \
  -H 'Content-Type: application/json'