Convenciones
Formatos, idempotencia, paginación, errores y límites de uso de la API v1.
Actualizado:
Lo básico
- URL base
https://api.fiuit.com/v1. Los cambios incompatibles salen como una nueva versión; los cambios aditivos (campos nuevos) pueden llegar en cualquier momento, así que ignorá los campos que no conozcas. - JSON de entrada y de salida (
Content-Type: application/json). - Fechas en ISO 8601 con offset (
2026-10-15T09:45:00-03:00). Se guardan en UTC. - Montos en centavos enteros más
currency(BRL,ARS,PYG,USD). - Los IDs son strings opacos. Los campos sin valor llegan como
nullexplícito. - El contrato legible por máquina es
packages/openapi/openapi.yaml(OpenAPI 3.1) y el historial de cambios resume lo nuevo.
Idempotencia
POST /holds, POST /holds/{id}/confirm, POST /bookings, POST /bookings/{id}/reschedule y POST /bookings/{id}/actions/{key} llevan el header Idempotency-Key (por ejemplo un UUID). Repetir un request con la misma clave dentro de 24 horas devuelve la respuesta original. Reusar la clave con otro body devuelve 422 con code: "idempotency_conflict".
POST /customers acepta Idempotency-Key de forma opcional. POST /webhook-endpoints no lo admite, porque su respuesta contiene el secreto.
Paginación
Los endpoints de listado usan cursores:
curl "https://api.fiuit.com/v1/bookings?limit=50" -H "Authorization: Bearer $WAGEND_KEY"
# → { "data": [...], "next_cursor": "eyJpZCI6..." }
curl "https://api.fiuit.com/v1/bookings?limit=50&cursor=eyJpZCI6..." -H "Authorization: Bearer $WAGEND_KEY"
Cuando next_cursor es null, no hay más páginas.
Errores
Los errores siguen la RFC 9457 (application/problem+json):
{
"type": "https://fiuit.com/docs/api/conventions#errors",
"title": "Slot no longer available",
"status": 409,
"code": "slot_taken",
"alternatives": [{ "start": "2026-10-15T10:15:00-03:00", "end": "2026-10-15T10:45:00-03:00" }]
}
code | Estado | Cuándo |
|---|---|---|
validation_error | 422 | Falló la validación del body o de los parámetros |
invalid_api_key | 401 | Clave ausente, inválida o revocada |
idempotency_key_required | 400 | Falta el header Idempotency-Key en una operación que lo exige |
version_conflict | 409 | Alguien editó antes el mismo recurso (versión desactualizada) |
insufficient_scope | 403 | La clave no tiene el scope |
not_found | 404 | Id desconocido (o de otro proyecto) |
slot_taken | 409 | Otra persona tomó el horario |
already_claimed | 409 | Otra persona del equipo tomó antes la tarea de cola |
customer_exists | 409 | Ya hay un cliente con ese teléfono |
invalid_transition | 409 | Por ejemplo confirmar una reserva cancelada |
hold_expired | 410 | La pre-reserva venció antes de confirmar |
idempotency_conflict | 422 | Misma clave, distinto body |
rate_limited | 429 | Demasiados requests |
Cada respuesta de error trae code: usalo para decidir qué hacer, no el texto del title.
Límites de uso
Los límites aplican por clave y por proyecto (un cubo con ráfaga de 120 requests y recarga de 2 por segundo). Cada respuesta trae RateLimit-Limit, RateLimit-Remaining y RateLimit-Reset. Ante un 429, esperá Retry-After segundos.