Skip to content

Availability and booking

Find bookable times and book, reschedule or cancel appointments through Agenda's booking operations, with requirements, safe repeats and statuses.

Updated

The booking operations are how a system books for a patient: an AI agent on WhatsApp, a patient-facing app, a contact-centre tool. They find what the clinic offers and when, say what the clinic needs to know, book the time the patient chose, and later move or cancel it. People and machines (API keys and client credentials) may call every one of them. For the whole flow with curl, see Book an appointment.

The operations

Operation Request Effect
agenda.bookingOfferings.list GET /v1/agenda/booking-offerings Reads
agenda.bookingLocations.list GET /v1/agenda/booking-locations Reads
agenda.bookingRequirements.get GET /v1/agenda/booking-requirements Reads
agenda.nearestBookingSlots.list GET /v1/agenda/nearest-booking-slots Reads
agenda.bookingSlots.list GET /v1/agenda/booking-slots Reads
agenda.bookings.create POST /v1/agenda/bookings Writes; idempotent
agenda.bookings.lookup POST /v1/agenda/bookings/lookup Reads
agenda.bookings.get GET /v1/agenda/bookings/{appointmentId} Reads
agenda.bookings.reschedule POST /v1/agenda/bookings/{appointmentId}/reschedule Writes; not idempotent
agenda.bookings.cancel POST /v1/agenda/bookings/{appointmentId}/cancel Deletes; idempotent

Reads accept agenda:bookings:read or agenda:bookings:write; the three writes need agenda:bookings:write. Each operation also accepts channel and connectionId: the platform sets them and they change nothing in Agenda, so leave them out.

Find what to book

agenda.bookingOfferings.list finds active bookable offerings by q (a service’s name, such as neurología), serviceId or locationId, 10 per page by default and at most 20. Search for the service the patient named rather than loading the whole catalog. Each offering carries what to check before you offer a time:

Field Meaning
id, serviceId The offering and its service.
durationMinutes, occupationMinutes How long the appointment lasts, and how long the patient stays when that’s longer, such as a 12-hour study (otherwise null).
agendas, locations The resources that provide it, and their sites, with the address to give the patient.
scheduleSummary Its hours and closures in words. Availability is what counts.
service.eligibility The ages the service takes, minAgeYears and maxAgeYears, in completed years on the appointment day; null for any age.
service.bookingChecklist Requirements to compare with what you know about the patient before you offer a slot.
service.patientInstructions Preparation and arrival instructions to explain to the patient.

When exactly one site applies, use it without asking the patient to choose. A listed service doesn’t establish that the patient’s payer covers it. agenda.bookingLocations.list lists the sites, a page at a time.

Check the requirements

agenda.bookingRequirements.get answers what the organization needs to book:

Field What it says
fields How each built-in field is asked: off, optional or required for phone, email, payer, authorization and notes; optional or required for document; on or off for priority.
customFields The organization’s own fields: key, label, type (text, number, date, select or checkbox), options and required.
documentTypes The document type codes it uses, such as CC or TI.
payers Its active payers. Each has a bookingPolicy, open or staff_only, and sites, the sites (IPS or sedes) the clinic serves under that payer: a patient whose site isn’t listed isn’t served under it, and an empty list means no restriction.

Pass payerQuery with the payer’s name, as it appears on the patient’s insurance card, to leave out unrelated payers; an empty match doesn’t establish coverage. Only the clinic’s team books the patients of a staff_only payer: don’t book them, add them to the waitlist with the reason payer_review through agenda.waitlist.join. Reuse what the patient has already told you, and ask only for required values that are missing or unclear.

Find a slot

Two operations answer slots, earliest first, each with a slotToken:

nearestBookingSlots.list bookingSlots.list
Searches One service, across every agenda that offers it One offering, from from up to to
Requires serviceId, timezone offeringId, from, to, timezone
Narrows or steers with locationId, resourceId, from, days preferredResourceIds, agendas to consider first
Answers Up to limit slots: 20 by default, at most 50 Pages of 25 by default, at most 100
Continues Call again with from set to nextFrom pageInfo.nextCursor

timezone is the IANA time zone used to read local dates and working hours, such as America/Bogota.

To quote the nearest time, call agenda.nearestBookingSlots.list with a limit of 1 to 3 and leave days out: it then searches as far ahead as the service can be booked, so an opening months away comes back in one call. Don’t page week by week. group: "offering" answers each offering’s first slots instead of the earliest overall. An empty data means there’s no opening within that reach, and searchedUntil says how far it looked: offer the waitlist. truncatedOfferings: true means some agendas went unexamined; narrow the search with locationId or resourceId.

agenda.firstAvailability.get and agenda.availability.list answer the same kind of slots to credentials with agenda:availability:read. They also take durationMinutes, admitted only when the organization permits changing the duration, and occupationMinutes, a study length the offering offers.

Book

Book only after the patient explicitly confirms the time. agenda.bookings.create takes the slotToken exactly as it was returned:

Field Meaning
slotToken Required. The slot the patient confirmed.
patient name, documentNumber and documentType, one of the organization’s codes (the first one when left out).
patientBirthDate YYYY-MM-DD, as the patient gives it. Needed when the service has an age rule. Never infer age from a name or a document type.
intake phone, email, entity (the payer, as the clinic names it), authorization, notes, priority (normal or urgent), and fields, the custom fields by key.

The booking also creates or updates the patient’s record, whose id comes back as patientId. The answer is the appointment, with:

  • guidance: the service’s patient instructions, whether patients are seen in arrival order, who attends, and the site with its address. Tell the patient.
  • slip: a link to the appointment’s printable PDF slip, valid for an hour (expiresAt). Fetch it right after booking and send the patient the file, never the link as text: the link needs no credential.

The errors a booking can meet, and what to do about each, are in Book an appointment.

Reschedule and cancel

agenda.bookings.lookup finds a patient by the exact documentNumber (and documentType, when known) and answers their appointments, newest first, each with its id, startsAt, status and agendas; upcoming ones also carry guidance. found: false means no patient has that document. When several patients share the number under different types, patients lists them and appointments is empty: ask which one, and call again with documentType. agenda.bookings.get reads one appointment by id, with its guidance and slip.

  • Reschedule. Find a new time for the same service, have the patient confirm it, and send its slotToken to agenda.bookings.reschedule. Another professional or room of that service is fine; a slot of another service is refused with SERVICE_CHANGED. With agenda.bookingSlots.list, pass the appointment’s id as excludeAppointmentId so its current time doesn’t count as taken.
  • Cancel. Once the person confirms which appointment, send the reason they gave to agenda.bookings.cancel. The reason is kept in the appointment’s history, and the slot is freed.

Safe repeats

Operation Effect Idempotency key
agenda.bookings.create Writes; idempotent: repeating it with the same input has no further effect. None
agenda.bookings.reschedule Writes; not idempotent: a repeat may act again. None
agenda.bookings.cancel Deletes; idempotent. None
agenda.waitlist.join Writes; idempotent: the same patient, service and reason return the same open entry. None
agenda.appointments.create Writes. People only. idempotencyKey, required and unique within the organization: reusing it returns the original appointment.

The booking operations take no idempotency key, so when a write’s outcome is unknown, check with agenda.bookings.lookup or agenda.bookings.get before you repeat it. See Retries and Handle errors and retries.

Statuses

An appointment’s status is one of tentative, scheduled, confirmed, checked_in, completed, cancelled, no_show or unknown.

  • Cancelling frees the slot. Cancelled and completed appointments don’t regain capacity through a status change.
  • A cancelled appointment can’t be edited (APPOINTMENT_CLOSED), a closed one can’t be moved (APPOINTMENT_NOT_MOVABLE), and a cancelled one has no slip: slip is null.
  • statusChange records the latest change of status: when, by whom and the reason given.
  • Staff change a status, such as to confirmed or no_show, with agenda.appointments.changeStatus. It accepts only people, applies allowed transitions, and requires the expectedVersion they read.

Waitlist entries have their own statuses: see The waitlist.

Type to search…

↑↓ navigate↵ selectEsc close