Agenda de citas

La agenda convierte la disponibilidad de tu equipo en horarios reservables. Tú defines qué servicios ofreces y cuándo atiendes; Mosend calcula los huecos libres en la zona horaria de la organización, respeta los días bloqueados y la antelación mínima, y evita que dos personas reserven el mismo hueco.

El orden importa

Los cuatro primeros pasos se hacen una vez, al montar la agenda. El quinto y el sexto son los que corren en cada reserva.

  1. Habilitar la agendaPATCH /agenda/settings. Requiere la feature de plan; si no la tienes, responde 403.
  2. Crear los tipos de citaPOST /agenda/types. Cada uno es un servicio reservable con su duración y su colchón entre citas.
  3. Definir la disponibilidad semanal PUT /agenda/availability. Reemplaza el set completo de reglas, no añade: manda siempre la semana entera.
  4. Bloquear los días que no se atiende POST /agenda/exceptions (festivos, vacaciones).
  5. Pedir los huecos libresGET /agenda/slots.
  6. Reservar unoPOST /agenda/appointments.

Reservar: pedir huecos y tomar uno

Nunca inventes un horario. Pide los slots y reserva uno exacto de los que te devolvió: la reserva valida que ese hueco siga libre y responde 409 si alguien se te adelantó entre una llamada y otra.

# 1. Huecos libres de un servicio, en un rango
curl "https://api.mosend.dev/organizations/${ORG_ID}/agenda/slots?typeId=${TYPE_ID}&from=2026-09-01&to=2026-09-07" \
  -H "X-Api-Key: ${API_KEY}"

# 2. Reservar uno exacto para un contacto
curl -X POST "https://api.mosend.dev/organizations/${ORG_ID}/agenda/appointments" \
  -H "X-Api-Key: ${API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{
    "typeId": "'"${TYPE_ID}"'",
    "contactId": "'"${CONTACT_ID}"'",
    "startAt": "2026-09-02T14:00:00.000Z"
  }'

# 409 = ese horario ya no está libre. Vuelve al paso 1 y ofrece otro.

Después de la cita

  • PATCH /agenda/appointments/:id/reschedule — mueve la cita a otro horario disponible. Se valida igual que una reserva nueva.
  • PATCH /agenda/appointments/:id/cancel — cancela y libera el hueco.
  • PATCH /agenda/appointments/:id/status — al terminar, marca COMPLETED o NO_SHOW. Es lo que alimenta los informes de asistencia a citas.

Cada cambio dispara los webhooks salientes appointment.*, que es la forma recomendada de enterarte si tu sistema debe reaccionar. Ver webhooks salientes.

Que el cliente reserve solo

Si prefieres no construir la interfaz de reserva, manda al contacto un Flow de WhatsApp con selector de fecha nativo:

curl -X POST "https://api.mosend.dev/organizations/${ORG_ID}/agenda/booking-flow/send" \
  -H "X-Api-Key: ${API_KEY}" \
  -H "Content-Type: application/json" \
  -d '{ "contactId": "'"${CONTACT_ID}"'", "typeId": "'"${TYPE_ID}"'" }'

El contacto elige día y hora dentro de WhatsApp y la cita queda creada. El endpoint POST /agenda/flow/data lo llama Meta, no tú.

Ver la agenda desde fuera

  • Feed ICSPOST /agenda/ics/rotate genera un token y devuelve una URL pública /public/agenda/:token/calendar.ics para suscribirse desde cualquier calendario. Rotar el token revoca las suscripciones anteriores: úsalo si la URL se filtró.
  • Google CalendarGET /agenda/google/connect devuelve la URL de consentimiento. Una vez conectado, PATCH /agenda/google decide dos cosas por separado: si las citas se envían al calendario, y si los eventos marcados como ocupado en Google bloquean huecos en Mosend.

Detalles que evitan sorpresas

  • Todo se calcula en la zona horaria de la organización, no en la del servidor ni en la de quien llama. Las horas de disponibilidad son minutos locales de esa zona; los instantes de las citas viajan en UTC.
  • PUT /agenda/availability reemplaza todas las reglas. Si mandas solo el lunes, el resto de la semana queda sin disponibilidad.
  • Los slots ya respetan la antelación mínima, el colchón entre citas y los días bloqueados. No hace falta que los filtres otra vez.
  • Habilitar la agenda depende de la feature del plan. Un 403 al tocar /agenda/settings suele ser eso, no un problema de permisos.

Referencia completa de rutas y cuerpos en API · agenda.