---
title: "Disponibilidad y agendamiento"
description: "Busca horarios disponibles y agenda, reprograma o cancela citas con las operaciones de agendamiento de Agenda, con requisitos, repeticiones seguras y estados."
---

> Documentation Index
> Fetch the complete documentation index at: https://docs.getarbol.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Disponibilidad y agendamiento

Las operaciones de agendamiento son la forma en que un sistema agenda por un paciente: un agente de IA en WhatsApp, una app para pacientes, una herramienta de call center. Encuentran qué ofrece la clínica y cuándo, dicen qué necesita saber la clínica, agendan el horario que eligió el paciente y, más adelante, lo mueven o lo cancelan. Personas y máquinas (API keys y client credentials) pueden llamar a todas. Para el flujo completo con curl, consulta [Agendar una cita](/developers/guides/book-an-appointment/).

## Las operaciones

| Operación | Solicitud | Efecto |
| --- | --- | --- |
| [`agenda.bookingOfferings.list`](/api/agenda/booking-offerings/list/) | `GET /v1/agenda/booking-offerings` | Lee |
| [`agenda.bookingLocations.list`](/api/agenda/booking-locations/list/) | `GET /v1/agenda/booking-locations` | Lee |
| [`agenda.bookingRequirements.get`](/api/agenda/booking-requirements/get/) | `GET /v1/agenda/booking-requirements` | Lee |
| [`agenda.nearestBookingSlots.list`](/api/agenda/nearest-booking-slots/list/) | `GET /v1/agenda/nearest-booking-slots` | Lee |
| [`agenda.bookingSlots.list`](/api/agenda/booking-slots/list/) | `GET /v1/agenda/booking-slots` | Lee |
| [`agenda.bookings.create`](/api/agenda/bookings/create/) | `POST /v1/agenda/bookings` | Escribe; idempotente |
| [`agenda.bookings.lookup`](/api/agenda/bookings/lookup/) | `POST /v1/agenda/bookings/lookup` | Lee |
| [`agenda.bookings.get`](/api/agenda/bookings/get/) | `GET /v1/agenda/bookings/{appointmentId}` | Lee |
| [`agenda.bookings.reschedule`](/api/agenda/bookings/reschedule/) | `POST /v1/agenda/bookings/{appointmentId}/reschedule` | Escribe; no idempotente |
| [`agenda.bookings.cancel`](/api/agenda/bookings/cancel/) | `POST /v1/agenda/bookings/{appointmentId}/cancel` | Elimina; idempotente |

Las lecturas aceptan `agenda:bookings:read` o `agenda:bookings:write`; las tres escrituras necesitan `agenda:bookings:write`. Cada operación también acepta `channel` y `connectionId`: los fija la plataforma y no cambian nada en Agenda, así que omítelos.

## Encontrar qué agendar

[`agenda.bookingOfferings.list`](/api/agenda/booking-offerings/list/) busca ofertas activas que se pueden agendar por `q` (el nombre de un servicio, como `neurología`), `serviceId` o `locationId`, 10 por página por defecto y como máximo 20. Busca el servicio que nombró el paciente en lugar de cargar todo el catálogo. Cada oferta lleva lo que debes revisar antes de ofrecer un horario:

| Campo | Significado |
| --- | --- |
| `id`, `serviceId` | La oferta y su servicio. |
| `durationMinutes`, `occupationMinutes` | Cuánto dura la cita, y cuánto tiempo se queda el paciente cuando es más largo, como en un estudio de 12 horas (si no, `null`). |
| `agendas`, `locations` | Los recursos que la prestan y sus sedes, con la dirección que hay que darle al paciente. |
| `scheduleSummary` | Su horario y sus cierres, en palabras. Lo que cuenta es la disponibilidad. |
| `service.eligibility` | Las edades que admite el servicio, `minAgeYears` y `maxAgeYears`, en años cumplidos el día de la cita; `null` para cualquier edad. |
| `service.bookingChecklist` | Requisitos para contrastar con lo que sabes del paciente antes de ofrecerle un cupo. |
| `service.patientInstructions` | Instrucciones de preparación y llegada para explicarle al paciente. |

Cuando aplica exactamente una sede, úsala sin pedirle al paciente que elija. Que un servicio aparezca en la lista no establece que el pagador del paciente lo cubra. [`agenda.bookingLocations.list`](/api/agenda/booking-locations/list/) lista las sedes, una página a la vez.

## Revisar los requisitos

[`agenda.bookingRequirements.get`](/api/agenda/booking-requirements/get/) responde con lo que la organización necesita para agendar:

| Campo | Qué dice |
| --- | --- |
| `fields` | Cómo se pide cada campo predefinido: `off`, `optional` o `required` para `phone`, `email`, `payer`, `authorization` y `notes`; `optional` o `required` para `document`; `on` u `off` para `priority`. |
| `customFields` | Los campos propios de la organización: `key`, `label`, `type` (`text`, `number`, `date`, `select` o `checkbox`), `options` y `required`. |
| `documentTypes` | Los códigos de tipo de documento que usa, como `CC` o `TI`. |
| `payers` | Sus pagadores activos. Cada uno tiene una `bookingPolicy`, `open` o `staff_only`, y `sites`, las sedes (IPS) que la clínica atiende con ese pagador: un paciente cuya sede no está en la lista no se atiende con él, y una lista vacía significa que no hay restricción. |

Pasa `payerQuery` con el nombre del pagador, tal como aparece en el carné del paciente, para dejar fuera los pagadores que no vienen al caso; que no haya coincidencias no establece la cobertura. Solo el equipo de la clínica agenda a los pacientes de un pagador `staff_only`: no los agendes; agrégalos a la lista de espera con el motivo `payer_review` a través de [`agenda.waitlist.join`](/api/agenda/waitlist/join/). Reutiliza lo que el paciente ya te dijo, y pide solo los valores obligatorios que falten o no estén claros.

## Encontrar un cupo

Dos operaciones responden con cupos, del más cercano al más lejano, cada uno con un `slotToken`:

| | [`nearestBookingSlots.list`](/api/agenda/nearest-booking-slots/list/) | [`bookingSlots.list`](/api/agenda/booking-slots/list/) |
| --- | --- | --- |
| Busca | Un servicio, en todas las agendas que lo ofrecen | Una oferta, desde `from` hasta `to` |
| Requiere | `serviceId`, `timezone` | `offeringId`, `from`, `to`, `timezone` |
| Se acota o se orienta con | `locationId`, `resourceId`, `from`, `days` | `preferredResourceIds`, las agendas que se consideran primero |
| Responde | Hasta `limit` cupos: 20 por defecto, como máximo 50 | Páginas de 25 por defecto, como máximo 100 |
| Continúa | Vuelve a llamar con `from` igual a `nextFrom` | `pageInfo.nextCursor` |

`timezone` es la zona horaria IANA que se usa para leer las fechas locales y el horario de trabajo, como `America/Bogota`.

Para ofrecer el horario más cercano, llama a [`agenda.nearestBookingSlots.list`](/api/agenda/nearest-booking-slots/list/) con un `limit` de 1 a 3 y omite `days`: así busca en todo el plazo en que se puede agendar el servicio, de modo que un espacio libre a meses de distancia vuelve en una sola llamada. No pagines semana por semana. `group: "offering"` responde con los primeros cupos de cada oferta en lugar de los más cercanos en general. Un `data` vacío significa que no hay ningún espacio libre en ese alcance, y `searchedUntil` dice hasta dónde buscó: ofrece la lista de espera. `truncatedOfferings: true` significa que algunas agendas no se revisaron; acota la búsqueda con `locationId` o `resourceId`.

[`agenda.firstAvailability.get`](/api/agenda/first-availability/get/) y [`agenda.availability.list`](/api/agenda/availability/list/) responden con el mismo tipo de cupos a las credenciales con `agenda:availability:read`. También reciben `durationMinutes`, que se admite solo cuando la organización permite cambiar la duración, y `occupationMinutes`, una duración de estudio que ofrece la oferta.

## Agendar

Agenda solo después de que el paciente confirme el horario de forma explícita. [`agenda.bookings.create`](/api/agenda/bookings/create/) recibe el `slotToken` exactamente como se devolvió:

| Campo | Significado |
| --- | --- |
| `slotToken` | Obligatorio. El cupo que confirmó el paciente. |
| `patient` | `name`, `documentNumber` y `documentType`, uno de los códigos de la organización (el primero si se omite). |
| `patientBirthDate` | `YYYY-MM-DD`, tal como la da el paciente. Necesaria cuando el servicio tiene una regla de edad. Nunca deduzcas la edad a partir de un nombre o un tipo de documento. |
| `intake` | `phone`, `email`, `entity` (el pagador, con el nombre que usa la clínica), `authorization`, `notes`, `priority` (`normal` o `urgent`) y `fields`, los campos personalizados por `key`. |

El agendamiento también crea o actualiza el registro del paciente, cuyo id vuelve como `patientId`. La respuesta es la cita, con:

- `guidance`: las instrucciones del servicio para el paciente, si los pacientes se atienden por orden de llegada, quién lo atiende y la sede con su dirección. Cuéntaselo al paciente.
- `slip`: un enlace al comprobante imprimible de la cita en PDF, válido por una hora (`expiresAt`). Descárgalo justo después de agendar y envíale al paciente el archivo, nunca el enlace como texto: el enlace no necesita ninguna credencial.

Los errores que puede encontrar un agendamiento, y qué hacer con cada uno, están en [Agendar una cita](/developers/guides/book-an-appointment/#manejar-los-errores-comunes).

## Reprogramar y cancelar

[`agenda.bookings.lookup`](/api/agenda/bookings/lookup/) busca a un paciente por el `documentNumber` exacto (y el `documentType`, cuando se conoce) y responde con sus citas, de la más reciente a la más antigua, cada una con su `id`, su `startsAt`, su `status` y sus agendas; las próximas también llevan `guidance`. `found: false` significa que ningún paciente tiene ese documento. Cuando varios pacientes comparten el número con tipos distintos, `patients` los lista y `appointments` viene vacío: pregunta cuál es y vuelve a llamar con `documentType`. [`agenda.bookings.get`](/api/agenda/bookings/get/) lee una cita por id, con sus indicaciones y su comprobante.

- **Reprogramar.** Busca un horario nuevo para el mismo servicio, pide al paciente que lo confirme y envía su `slotToken` a [`agenda.bookings.reschedule`](/api/agenda/bookings/reschedule/). Sirve otro profesional u otra sala de ese servicio; un cupo de otro servicio se rechaza con `SERVICE_CHANGED`. Con [`agenda.bookingSlots.list`](/api/agenda/booking-slots/list/), pasa el id de la cita como `excludeAppointmentId` para que su horario actual no cuente como ocupado.
- **Cancelar.** Una vez que la persona confirme cuál es la cita, envía el `reason` que dio a [`agenda.bookings.cancel`](/api/agenda/bookings/cancel/). El motivo queda en el historial de la cita, y el cupo se libera.

## Repeticiones seguras

| Operación | Efecto | Clave de idempotencia |
| --- | --- | --- |
| [`agenda.bookings.create`](/api/agenda/bookings/create/) | Escribe; idempotente: repetirla con la misma entrada no tiene ningún efecto adicional. | Ninguna |
| [`agenda.bookings.reschedule`](/api/agenda/bookings/reschedule/) | Escribe; no idempotente: una repetición puede volver a actuar. | Ninguna |
| [`agenda.bookings.cancel`](/api/agenda/bookings/cancel/) | Elimina; idempotente. | Ninguna |
| [`agenda.waitlist.join`](/api/agenda/waitlist/join/) | Escribe; idempotente: el mismo paciente, servicio y motivo devuelven la misma entrada abierta. | Ninguna |
| [`agenda.appointments.create`](/api/agenda/appointments/create/) | Escribe. Solo personas. | `idempotencyKey`, obligatorio y único dentro de la organización: reutilizarlo devuelve la cita original. |

Las operaciones de agendamiento no reciben clave de idempotencia, así que cuando no se conoce el resultado de una escritura, revisa con [`agenda.bookings.lookup`](/api/agenda/bookings/lookup/) o [`agenda.bookings.get`](/api/agenda/bookings/get/) antes de repetirla. Consulta [Reintentos](/developers/concepts/retries/) y [Manejar errores y reintentos](/developers/guides/handle-errors-and-retries/).

## Estados

El `status` de una cita es uno de `tentative`, `scheduled`, `confirmed`, `checked_in`, `completed`, `cancelled`, `no_show` o `unknown`.

- Cancelar libera el cupo. Las citas canceladas y completadas no recuperan capacidad con un cambio de estado.
- Una cita cancelada no se puede editar (`APPOINTMENT_CLOSED`), una cerrada no se puede mover (`APPOINTMENT_NOT_MOVABLE`), y una cancelada no tiene comprobante: `slip` es `null`.
- `statusChange` registra el último cambio de estado: cuándo, quién lo hizo y el motivo que dio.
- El personal cambia un estado, por ejemplo a `confirmed` o `no_show`, con [`agenda.appointments.changeStatus`](/api/agenda/appointments/change-status/). Acepta solo personas, aplica las transiciones permitidas y requiere la `expectedVersion` que leyeron.

Las entradas de la lista de espera tienen sus propios estados: consulta [La lista de espera](/developers/agenda/#la-lista-de-espera).

Source: https://docs.getarbol.com/developers/agenda/availability-and-booking/index.mdx
