Bookings
Book, hold, approve, move and cancel.
const { : , } = await ...({
: ,
: "2027-01-04T15:00:00Z",
: { : "patient_77", : "Sam Lee", : "sam@example.com", : "UTC" },
});
if (?. === "slot_unavailable") {
// Someone else got there first: show the slots again.
}The SDK retries safely: every attempt carries the same Idempotency-Key, so a lost response can't
book twice. A refused request keeps no key.
Taking payment first
Hold the slot, charge the customer, then confirm. A hold isn't charged and tells nobody, and confirming one always succeeds before it expires.
const { : } = await ...({
: ,
: "2027-01-04T15:00:00Z",
: { : "patient_77", : "Sam Lee", : "sam@example.com", : "UTC" },
});
// hold?.hold_expires_at: ten minutes by default (the event type's hold_ttl_seconds).
// ...take the payment, then:
await ...(!.);After a hold expires, confirming answers hold_expired, or books anyway with if_still_free if nobody
else took the slot. coss.scheduling.holds.release gives a slot back early.
Approval
An event type with requires_approval makes each booking pending_approval. The time stays blocked
until approve, decline, or the deadline (approval_ttl_minutes), which declines it. Nothing's
charged or added to a calendar until it's approved.
Questions
An event type can ask questions, answered in answers. Answers are encrypted, and only come back
when you retrieve one booking: never in lists, webhooks, logs, emails or calendars. See
Privacy before asking anything sensitive.
Rescheduling and cancelling
reschedule keeps the booking's id, and its old time stays booked unless the new one's free. Your API
key can always do both. Attendees using a manage link are held to the event
type's cancel_notice_minutes and reschedule_notice_minutes.
Recurring series
A series books up to 52 occurrences at the attendee's local time, so a weekly 10:00 stays 10:00 across a clock change. Each is an ordinary booking that can move on its own, and a pool keeps one host throughout.
const = {
: ,
: "2027-01-04T15:00:00Z",
: { : "patient_77", : "America/New_York" },
: { : "weekly" as , : 12 },
: "skip" as ,
};
const { : } = await ...();
const { : } = await ...();
// series?.conflicts lists any occurrence that wasn't free.With on_conflict: "reject", the default, one taken occurrence books nothing.
Webhooks
Bookings send scheduling.booking.confirmed, .pending_approval, .rescheduled, .cancelled,
.declined, .no_show, .external_conflict, .calendar_write_failed and .location_ready. They carry
ids, times and statuses only. Retrieve the booking for anything about the person.