---
title: "Agendar una cita"
description: "Agenda una cita de Agenda para un paciente con curl, desde encontrar el servicio y un cupo hasta confirmarla, y luego reprográmala y cancélala."
---

> 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.

# Agendar una cita

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](/developers/agenda/) explica el modelo, y [Disponibilidad y agendamiento](/developers/agenda/availability-and-booking/), 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](/developers/authentication/)). 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

1. **Encuentra el servicio.** Busca el nombre que usó el paciente con [`agenda.bookingOfferings.list`](/api/agenda/booking-offerings/list/):

   ```bash
   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.data` lleva su `id`, su `serviceId`, sus sedes y lo que el servicio le pide al paciente: `service.bookingChecklist`, para contrastarlo con lo que sabes, `service.patientInstructions` y `service.eligibility`, como `{ "minAgeYears": 18, "maxAgeYears": null }`. Si hay una regla de edad, necesitarás la fecha de nacimiento del paciente.

2. **Revisa los requisitos.** [`agenda.bookingRequirements.get`](/api/agenda/booking-requirements/get/) responde con los campos de admisión, los tipos de documento y los pagadores; `payerQuery` deja fuera los pagadores que no vienen al caso:

   ```bash
   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 como `phone` y `payer` son `off`, `optional` o `required`, y `document` es `optional` o `required`; `data.customFields` agrega los campos propios de la organización; `data.documentTypes` lista los códigos de documento, como `CC`; y cada pagador en `data.payers` tiene una `bookingPolicy`, `open` o `staff_only`. Reúne cada valor obligatorio que aún no tengas. Si la política del pagador es `staff_only`, no agendes: [pon al paciente en la lista de espera](#poner-al-paciente-en-la-lista-de-espera).

3. **Encuentra un cupo.** [`agenda.nearestBookingSlots.list`](/api/agenda/nearest-booking-slots/list/) responde con los horarios más cercanos en todas las agendas que ofrecen el servicio:

   ```bash
   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"
   ```

   ```json
   {
     "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 su `endsAt`, su `offeringId` y sus `resourceIds`. Ofrécele los horarios al paciente en la `timezone` del 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.

4. **Agenda la cita cuando el paciente confirme el horario.** Envía el `slotToken` sin cambios a [`agenda.bookings.create`](/api/agenda/bookings/create/), con el paciente y los datos de admisión que exige la clínica:

   ```bash
   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, de `data`:

   ```json
   {
     "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" }
   }
   ```

5. **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:

   ```bash
   curl --fail --output appointment-slip.pdf "$SLIP_URL"
   ```

   Aquí `SLIP_URL` contiene `data.slip.url`; el enlace no lleva credenciales. [`agenda.bookings.get`](/api/agenda/bookings/get/) vuelve a leer la cita más adelante, con sus indicaciones y su comprobante. Poner un estado como `confirmed` le corresponde a la clínica: el personal lo hace con [`agenda.appointments.changeStatus`](/api/agenda/appointments/change-status/), 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](/developers/guides/handle-errors-and-retries/#un-agendamiento-que-agotó-el-tiempo-de-espera), que también cubre `429`. |

### Poner al paciente en la lista de espera

Con el consentimiento del paciente, [`agenda.waitlist.join`](/api/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á.

```bash
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`](/api/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.

```bash
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`](/api/agenda/bookings/reschedule/):

```bash
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`](/api/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.

```bash
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." }'
```

Source: https://docs.getarbol.com/developers/guides/book-an-appointment/index.mdx
