# Agendar en tu propia pantalla

Tu sistema muestra los horarios libres de tu equipo y deja que la persona elija uno, sin salir de tu aplicación. La reunión queda en Google Calendar con su link de videollamada, y la invitación le llega sola a quien agendó.

Base de la API de Lelemon: `https://api.lelemon.cl`

La idea de fondo: **el calendario lo maneja Lelemon, la pantalla la manejas tú.** Nosotros preguntamos qué está ocupado, descontamos los buffers y el aviso mínimo, y te devolvemos instantes. Cómo se ven en pantalla, en qué idioma y en qué huso, lo decides tú.

## Antes de empezar

Del lado de Lelemon tiene que haber, una sola vez:

1. **Alguien de tu equipo con su Google conectado**, en Agendamiento del dashboard.
2. **Al menos una agenda**: sus horarios, cuánto dura cada bloque, con cuánta anticipación aceptas que te reserven, y quiénes atienden.

Puedes tener varias —una para el fundador, otra para ventas— con horarios y personas distintas. **Siempre dices cuál usas**, por su slug. No hay "la de por omisión" a propósito: si la hubiera, el día que alguien creara una segunda agenda tus reservas podrían mudarse de calendario sin que nada fallara.

## 1. Ver qué agendas hay

Necesitas una credencial con el alcance `scheduling:read`.

```
GET https://api.lelemon.cl/v1/external/scheduling/agendas
Authorization: Bearer <tu credencial>
```

```json
{
  "agendas": [
    {
      "slug": "fundador",
      "name": "Con el fundador",
      "timezone": "America/Santiago",
      "slotDurationMinutes": 20
    }
  ]
}
```

- **`slug` es lo que mandas en las otras dos rutas.** Lo eligió tu organización al crear la agenda, se lee, y no cambia si la agenda se recrea de nuestro lado.
- **`timezone` y `slotDurationMinutes` los necesitas antes de pedir un solo horario**: sin el huso no sabes en qué hora mostrar, y sin la duración no sabes de qué alto dibujar el bloque.
- Sólo salen las agendas activas.

## 2. Pedir los horarios libres

```
GET https://api.lelemon.cl/v1/external/scheduling/availability?agenda=fundador&daysAhead=7
Authorization: Bearer <tu credencial>
```

```json
{
  "slots": [
    {
      "id": "2026-09-17T14:00:00.000Z",
      "start": "2026-09-17T14:00:00.000Z",
      "end": "2026-09-17T14:20:00.000Z"
    }
  ]
}
```

- **`daysAhead`** es opcional y por omisión son 7 días. El techo real lo pone tu propia agenda, y este número no puede pasarlo.
- **`slots` vacío significa que no hay horarios en esa ventana**, no que algo haya fallado. Puede pasar si el equipo tiene la semana llena, o si nadie tiene su calendario conectado.
- **Las horas van en UTC.** Conviértelas al huso de quien está mirando, no al tuyo.
- **`id` es lo que se manda de vuelta para reservar.** No lo construyas a mano.

## 3. Reservar uno

Necesitas el alcance `scheduling:write`. Va aparte de leer a propósito: reservar escribe en el calendario de una persona de tu equipo y le manda un correo a un tercero.

```
POST https://api.lelemon.cl/v1/external/scheduling/meetings
Authorization: Bearer <tu credencial>
Content-Type: application/json

{
  "slotStart": "2026-09-17T14:00:00.000Z",
  "attendeeEmail": "persona@ejemplo.cl",
  "attendeeName": "Ana Pérez",
  "companyName": "Ejemplo SpA",
  "context": "Quiere ver cómo conectar su primera empresa"
}
```

```json
{
  "meetingId": "...",
  "scheduledFor": "2026-09-17T14:00:00.000Z",
  "durationMinutes": 20,
  "meetLink": "https://meet.google.com/abc-defg-hij"
}
```

- **`agenda` es el mismo slug** con el que pediste los horarios.
- **`slotStart` es el `id` de un bloque** de la respuesta anterior. Si no coincide con uno libre, la reserva se rechaza.
- **`context` le llega a quien atienda**, en la descripción del evento. Sirve para que llegue sabiendo de qué se trata.
- **`meetLink` puede no venir** si tu agenda está configurada sin videollamada.

## El caso que sí pasa: el horario se ocupó

Entre que pintaste la grilla y la persona apretó el botón, alguien más pudo tomar ese bloque. Eso devuelve **`409`**:

```json
{
  "statusCode": 409,
  "message": "Ese horario ya no esta libre. Volve a pedir la disponibilidad y elegi otro."
}
```

Y si nombras una agenda que no existe o está apagada, es un **`404`**. Las que hay salen en la ruta de arriba.

**Un `409` no se reintenta**: ese horario no va a volver a estar libre. Vuelve a pedir la disponibilidad y muestra la grilla actualizada. Un `500`, en cambio, sí es algo nuestro y reintentar tiene sentido.

Es la diferencia que más conviene manejar bien: son los dos únicos errores que tu usuario va a ver en una pantalla.

## Lo que esta API no hace

- **No reagenda ni cancela.** Existe del lado de Lelemon, pero todavía no está expuesto acá. Si lo necesitas, pídelo.
- **No te dice con quién es la reunión.** Repartimos entre quienes tengan el calendario conectado, y quién queda es asunto interno de tu organización.
- **No te deja mirar qué hay en los ratos ocupados.** Sólo cuáles están libres.
