Esta guía agenda una cita como lo hace un agente de IA o una app para pacientes, con las operaciones de agendamiento de Agenda: encuentra el servicio, revisa qué exige la clínica, encuentra un cupo, agenda la cita cuando el paciente confirma y se la confirma al paciente. Luego mueve la cita y la cancela. Cómo funciona Agenda explica el modelo, y Disponibilidad y agendamiento, cada campo que se usa aquí.
Necesitas una API key de tu organización con agenda:bookings:write, que cubre todas las operaciones de agendamiento, incluidas las lecturas, y agenda:waitlist:write para poner pacientes en la lista de espera (consulta Autenticación). Los ejemplos leen la key de ARBOL_API_KEY. Todos los ids, tokens y datos de pacientes que aparecen son de ejemplo.
Agendar la cita
-
Encuentra el servicio. Busca el nombre que usó el paciente con
agenda.bookingOfferings.list:curl --get https://api.getarbol.com/v1/agenda/booking-offerings \ --data-urlencode "q=neurología" --data-urlencode "limit=3" \ --header "Authorization: Bearer $ARBOL_API_KEY"Cada oferta en
data.datalleva suid, suserviceId, sus sedes y lo que el servicio le pide al paciente:service.bookingChecklist, para contrastarlo con lo que sabes,service.patientInstructionsyservice.eligibility, como{ "minAgeYears": 18, "maxAgeYears": null }. Si hay una regla de edad, necesitarás la fecha de nacimiento del paciente. -
Revisa los requisitos.
agenda.bookingRequirements.getresponde con los campos de admisión, los tipos de documento y los pagadores;payerQuerydeja fuera los pagadores que no vienen al caso:curl --get https://api.getarbol.com/v1/agenda/booking-requirements \ --data-urlencode "payerQuery=Example Health Plan" \ --header "Authorization: Bearer $ARBOL_API_KEY"En
data.fields, los campos predefinidos comophoneypayersonoff,optionalorequired, ydocumentesoptionalorequired;data.customFieldsagrega los campos propios de la organización;data.documentTypeslista los códigos de documento, comoCC; y cada pagador endata.payerstiene unabookingPolicy,openostaff_only. Reúne cada valor obligatorio que aún no tengas. Si la política del pagador esstaff_only, no agendes: pon al paciente en la lista de espera. -
Encuentra un cupo.
agenda.nearestBookingSlots.listresponde con los horarios más cercanos en todas las agendas que ofrecen el servicio:curl --get https://api.getarbol.com/v1/agenda/nearest-booking-slots \ --data-urlencode "serviceId=svc_00000000-0000-4000-8000-000000000001" \ --data-urlencode "timezone=America/Bogota" --data-urlencode "limit=3" \ --header "Authorization: Bearer $ARBOL_API_KEY"{ "startsAt": "2026-11-05T09:00:00-05:00", "timezone": "America/Bogota", "slotToken": "EXAMPLE_SLOT_TOKEN_0001" }Ese es el primer cupo de
data.data, abreviado: cada uno también tiene suendsAt, suofferingIdy susresourceIds. Ofrécele los horarios al paciente en latimezonedel cupo. Una lista vacía significa que no hay ningún espacio libre en todo el plazo en que se puede agendar el servicio: ofrece la lista de espera. -
Agenda la cita cuando el paciente confirme el horario. Envía el
slotTokensin cambios aagenda.bookings.create, con el paciente y los datos de admisión que exige la clínica:curl https://api.getarbol.com/v1/agenda/bookings \ --request POST \ --header "Authorization: Bearer $ARBOL_API_KEY" \ --header "Content-Type: application/json" \ --data '{ "slotToken": "EXAMPLE_SLOT_TOKEN_0001", "patient": { "name": "Example Patient", "documentNumber": "1234567890", "documentType": "CC" }, "patientBirthDate": "1990-01-01", "intake": { "phone": "+57 300 000 0000", "entity": "Example Health Plan" } }'La respuesta es la cita; guarda su
id, que necesitan la reprogramación y la cancelación. Abreviado, dedata:{ "id": "eng_00000000-0000-4000-8000-000000000005", "startsAt": "2026-11-05T09:00:00-05:00", "guidance": { "attendedBy": ["Dr. Example"], "patientInstructions": "Trae tu orden médica y llega 15 minutos antes.", "location": { "name": "Example Clinic North", "address": "Calle 00 # 00-00", "city": "Bogotá" } }, "slip": { "url": "https://example.com/EXAMPLE-slip.pdf", "expiresAt": "2026-10-30T16:00:00Z" } } -
Confírmale la cita al paciente. Dile el horario y lo que dice
guidance: las instrucciones, quién lo atiende y la sede con su dirección. Descarga el comprobante mientras su enlace funcione, dentro de la hora, y envíale el archivo PDF en lugar del enlace:curl --fail --output appointment-slip.pdf "$SLIP_URL"Aquí
SLIP_URLcontienedata.slip.url; el enlace no lleva credenciales.agenda.bookings.getvuelve a leer la cita más adelante, con sus indicaciones y su comprobante. Poner un estado comoconfirmedle corresponde a la clínica: el personal lo hace conagenda.appointments.changeStatus, que acepta solo personas.
Manejar los errores comunes
| Estado | error.code |
Qué hacer |
|---|---|---|
400 |
INVALID_INPUT, INVALID_APPOINTMENT_INTAKE |
Corrige los campos de error.data.issues: cada path apunta a uno. |
403 |
FORBIDDEN |
A la key le falta agenda:bookings:write. |
409 |
BIRTH_DATE_REQUIRED |
El servicio tiene una regla de edad: pregúntale al paciente su fecha de nacimiento y envía patientBirthDate. |
409 |
AGE_NOT_ELIGIBLE |
La edad del paciente ese día está fuera de la regla de edad del servicio, así que no se le puede agendar este servicio. |
409 |
PAYER_STAFF_ONLY |
Solo el equipo de la clínica agenda a los pacientes de este pagador: pon al paciente en la lista de espera. |
409 |
RESOURCE_CAPACITY_EXCEEDED, SERVICE_CAPACITY_EXCEEDED, SCHEDULE_CHANGED |
El horario ya no está libre: busca otro cupo y confírmalo con el paciente. |
409 |
INVALID_SLOT_TOKEN |
Busca un cupo nuevo y envía su token exactamente como se devolvió. |
502, 504 |
OUTCOME_UNKNOWN, UPSTREAM_TIMEOUT |
Puede que la cita exista: revisa antes de repetir, como en Manejar errores y reintentos, que también cubre 429. |
Poner al paciente en la lista de espera
Con el consentimiento del paciente, agenda.waitlist.join registra la solicitud para el equipo de la clínica, con el motivo payer_review para un pagador staff_only o manual cuando ningún horario le sirve. Nunca agenda: dile al paciente que el equipo de la clínica lo contactará.
curl https://api.getarbol.com/v1/agenda/waitlist/join \
--request POST \
--header "Authorization: Bearer $ARBOL_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"reason": "payer_review",
"serviceId": "svc_00000000-0000-4000-8000-000000000001",
"patient": { "name": "Example Patient", "documentNumber": "1234567890", "documentType": "CC" },
"phone": "+57 300 000 0000", "payer": "Example Health Plan"
}'Reprogramar
agenda.bookings.lookup recibe el documento del paciente y responde con sus citas en data.appointments, de la más reciente a la más antigua. Identifica la que menciona el paciente por su startsAt y su status; found: false significa que ningún paciente tiene ese documento.
curl https://api.getarbol.com/v1/agenda/bookings/lookup \
--request POST \
--header "Content-Type: application/json" \
--data '{ "documentNumber": "1234567890", "documentType": "CC" }' \
--header "Authorization: Bearer $ARBOL_API_KEY"Busca un horario nuevo para el mismo servicio como en el paso 3, donde sirve otro profesional u otra sala del servicio, y pide al paciente que lo confirme. Luego envía su slotToken a agenda.bookings.reschedule:
curl https://api.getarbol.com/v1/agenda/bookings/eng_00000000-0000-4000-8000-000000000005/reschedule \
--request POST \
--header "Authorization: Bearer $ARBOL_API_KEY" \
--header "Content-Type: application/json" \
--data '{ "slotToken": "EXAMPLE_SLOT_TOKEN_0002" }'Responde con la cita en su nuevo horario, con indicaciones y un comprobante para enviar de nuevo. Un cupo de otro servicio se rechaza con SERVICE_CHANGED, y una cita cerrada, con APPOINTMENT_NOT_MOVABLE. Reprogramar no es idempotente: si la llamada agota el tiempo de espera, lee la cita con agenda.bookings.get y revisa su startsAt antes de enviarla de nuevo.
Cancelar
Una vez que el paciente confirme cuál es la cita, envía el motivo que dio a agenda.bookings.cancel. El cupo se libera y el motivo queda en el historial de la cita. Cancelar es idempotente, así que repetirlo es seguro.
curl https://api.getarbol.com/v1/agenda/bookings/eng_00000000-0000-4000-8000-000000000005/cancel \
--request POST \
--header "Authorization: Bearer $ARBOL_API_KEY" \
--header "Content-Type: application/json" \
--data '{ "reason": "El paciente ya no puede asistir." }'