# Zapini API — Calendario

**Versión:** 1.0.0
**Base URL:** `https://zapini.app/api/v1`

---

## Autenticación

Todos los endpoints requieren un Bearer Token:

```
Authorization: Bearer sk_your_api_token
Accept: application/json
Content-Type: application/json
```

Genera tokens de API en el panel admin en **API Docs → Gestionar Tokens**.

---

## API de Calendario

**Ruta base:** `/api/v1/calendar`
**Requisito:** Sin permiso especial — todos los tenants pueden gestionar citas.

---

## Estados de Citas

| Estado | Descripción |
|--------|-------------|
| `scheduled` | Estado inicial — cita reservada |
| `confirmed` | Cliente confirmó asistencia |
| `completed` | Cita completada |
| `cancelled` | Cita cancelada |
| `no_show` | El cliente no se presentó |

---

## Citas

### Listar Citas
`GET /api/v1/calendar/appointments`

| Parámetro | Tipo | Por Defecto | Descripción |
|-----------|------|-------------|-------------|
| start | date | Inicio del mes | Inicio del rango (ISO 8601) |
| end | date | Fin del mes | Fin del rango (ISO 8601) |
| status | string | — | Filtrar por estado |
| per_page | integer | 50 | Elementos por página |

```bash
curl -s -H "Authorization: Bearer sk_your_token" \
  "https://zapini.app/api/v1/calendar/appointments?start=2026-05-01&end=2026-05-31"
```

---

### Crear Cita
`POST /api/v1/calendar/appointments`

| Campo | Tipo | Requerido | Descripción |
|-------|------|-----------|-------------|
| title | string | Sí | Título de la cita |
| description | string | No | Detalles |
| client_name | string | No | Nombre del cliente |
| client_phone | string | No | Teléfono del cliente |
| client_email | string | No | Email del cliente |
| starts_at | datetime | Sí | Hora de inicio (ISO 8601) |
| ends_at | datetime | Sí | Hora de fin (debe ser después de starts_at) |
| all_day | boolean | No | Evento de todo el día |
| location | string | No | Ubicación o URL de reunión |
| color | string | No | Código de color hexadecimal |
| reminder_minutes | integer | No | Minutos antes para enviar recordatorio (0–10080) |

```bash
curl -s -X POST \
  -H "Authorization: Bearer sk_your_token" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Consultation with John Doe",
    "client_name": "John Doe",
    "client_phone": "5511999999999",
    "starts_at": "2026-05-01T10:00:00",
    "ends_at": "2026-05-01T11:00:00",
    "location": "Online - Google Meet",
    "reminder_minutes": 30
  }' \
  "https://zapini.app/api/v1/calendar/appointments"
```

**Respuesta:**
```json
{
  "success": true,
  "data": {
    "uuid": "appt-uuid",
    "title": "Consultation with John Doe",
    "client_name": "John Doe",
    "client_phone": "5511999999999",
    "starts_at": "2026-05-01T10:00:00+00:00",
    "ends_at": "2026-05-01T11:00:00+00:00",
    "all_day": false,
    "duration_minutes": 60,
    "location": "Online - Google Meet",
    "status": "scheduled",
    "color": "#3b82f6",
    "reminder_minutes": 30,
    "created_at": "2026-01-01T00:00:00+00:00"
  }
}
```

---

### Obtener Cita
`GET /api/v1/calendar/appointments/{uuid}`

Retorna detalles de la cita incluyendo el usuario `created_by`.

---

### Actualizar Cita
`PUT /api/v1/calendar/appointments/{uuid}`

Mismos campos que Crear. Adicionalmente admite el campo `status`.

---

### Eliminar Cita
`DELETE /api/v1/calendar/appointments/{uuid}`

---

### Confirmar Cita
`POST /api/v1/calendar/appointments/{uuid}/confirm`

Transiciona el estado de `scheduled` a `confirmed`.

```bash
curl -s -X POST \
  -H "Authorization: Bearer sk_your_token" \
  "https://zapini.app/api/v1/calendar/appointments/appt-uuid/confirm"
```

---

### Completar Cita
`POST /api/v1/calendar/appointments/{uuid}/complete`

Transiciona el estado a `completed` y establece `completed_at`.

---

### Cancelar Cita
`POST /api/v1/calendar/appointments/{uuid}/cancel`

Retorna `422 CANNOT_CANCEL` si la cita ya está completada o cancelada.

---

### Convertir a Lead de Kanban
`POST /api/v1/calendar/appointments/{uuid}/to-kanban`

Crea un lead de Kanban a partir de esta cita. Requiere `kanban_enabled` en tu tenant.

| Campo | Tipo | Requerido | Descripción |
|-------|------|-----------|-------------|
| board_uuid | string | No | UUID del tablero destino (usa el tablero predeterminado si se omite) |

```bash
curl -s -X POST \
  -H "Authorization: Bearer sk_your_token" \
  -H "Content-Type: application/json" \
  -d '{"board_uuid": "optional-board-uuid"}' \
  "https://zapini.app/api/v1/calendar/appointments/appt-uuid/to-kanban"
```

**Respuesta:**
```json
{
  "success": true,
  "data": {
    "lead_uuid": "new-lead-uuid",
    "board_uuid": "board-uuid",
    "board_name": "Sales Pipeline"
  }
}
```

---

## Códigos de Error

| Código | HTTP | Descripción |
|--------|------|-------------|
| `NOT_FOUND` | 404 | Recurso no encontrado |
| `VALIDATION_ERROR` | 422 | Error de validación — verifica `error.details` |
| `CANNOT_CANCEL` | 422 | La cita no puede cancelarse |
| `NO_BOARD` | 422 | No se encontró tablero Kanban para el tenant |
| `UNAUTHORIZED` | 401 | Token inválido o faltante |
| `SERVER_ERROR` | 500 | Error interno del servidor |

---

*Generado por Zapini — https://zapini.app*
