Guía de la API
Autenticación
Toda petición se autentica con el header X-API-Key. Las keys se crean en el panel (Configuración → Integraciones), pertenecen a una cuenta y requieren el plan Premium. La clave (fxp_…) se muestra una sola vez al crearla.
curl https://api.turno0.com/api/v1/queues \ -H "X-API-Key: fxp_tu_clave"
- Sin key o con key revocada →
401. - Si la cuenta pierde el plan Premium, las keys responden
402. - Las keys no expiran; para rotarlas crea una nueva y revoca la anterior.
Permisos por módulo (scopes)
Cada key lleva scopes con el formato modulo:accion. La escritura incluye la lectura del mismo módulo. Si falta el scope, la respuesta es 403 indicando el scope requerido.
| Scope | Módulo | Niveles |
|---|---|---|
queues | Filas | lectura y escritura |
turns | Turnos | lectura y escritura |
dispatch | Despacho | solo escritura (las lecturas usan turns:read) |
appointments | Citas | lectura y escritura |
access-codes | Códigos de acceso | lectura y escritura |
workflow | Filas conectadas | lectura y escritura |
entities | Sucursales | lectura y escritura |
analytics | Analítica | solo lectura |
webhooks | Webhooks | lectura y escritura |
La gestión del equipo, la facturación y la marca solo están disponibles desde el panel, no por API.
Formato de errores
Todas las respuestas de error usan el mismo envelope, con un código estable:
{
"error": {
"code": "QUEUE_CLOSED",
"message": "No se pudo tomar turno porque la fila se ha cerrado.",
"details": { },
"requestId": "req_..."
}
}| HTTP | Significado |
|---|---|
| 400 | Entrada inválida (VALIDATION_ERROR incluye el detalle por campo). |
| 401 | Key ausente, inválida o revocada. |
| 402 | Límites del plan (Premium requerido, créditos insuficientes). |
| 403 | Scope faltante o recurso de otra cuenta. |
| 404 | Recurso inexistente. |
| 409 / 422 | Conflicto de negocio (fila cerrada, turno duplicado, transición inválida…). El code indica la causa exacta. |
| 429 | Límite de peticiones excedido (RATE_LIMITED). |
Paginación
Las listas usan cursor: pide con ?limit= (1–200, default 50) y avanza con ?cursor= usando el nextCursor de la página anterior (null cuando ya no hay más).
GET /api/v1/queue-runs/{runId}/turns?limit=50
{
"data": [ ... ],
"pagination": { "nextCursor": "cm...", "limit": 50 }
}Idempotencia
Al crear turnos o citas envía idempotencyKey (8–120 caracteres, único por operación). Si la petición se repite — por un timeout o reintento — recibirás el MISMO recurso en lugar de un duplicado. Recomendado para toda integración.
Límites de uso
Cada key puede hacer 120 peticiones por minuto. Toda respuesta incluye los headers X-RateLimit-Limit, X-RateLimit-Remaining y X-RateLimit-Reset (epoch en segundos). Al exceder el límite recibirás 429 RATE_LIMITED; espera al reset y reintenta.
Versionado
La superficie estable vive bajo /api/v1. Los cambios compatibles (campos nuevos, endpoints nuevos) pueden llegar sin aviso; los cambios incompatibles se publicarán como /api/v2 manteniendo v1 en operación durante la transición.