Convenciones API
La API v1 sigue un modelo consistente en toda la superficie: cada recurso lleva un campoobject, las listas se entregan con cursor pagination, los errores siempre tienen el mismo shape, y los headers de rate limit están en cada respuesta.
Algunas rutas legacy (chat, surveys, sync) mantienen sus shapes históricos para no romper la app mobile y los webhooks de Windmill. Las nuevas rutas viven bajo
/v1/ y siguen 100% estas convenciones. Las cross-cutting (request_id, headers de rate limit, errores estructurados) aplican a todas las rutas.Resource envelope
Cada recurso lleva un campoobject que identifica su tipo:
object permite a los consumidores discriminar tipos sin parsear el path o leer headers.
Listas paginadas
Las listas envuelven los items en un objeto conobject: "list" y campos de paginación cursor:
Request ID
Toda respuesta incluye el headerX-Request-ID. Si el cliente envía uno, el servidor lo respeta y lo propaga (a logs, errores, etc.). Si no, el servidor genera uno (req_<random>).
request_id cuando reportes un problema.
Errores estructurados
Todos los errores siguen el envelope:statusCode, timestamp, path, method, message. Los nuevos clientes deben leer sólo el envelope error.
Catálogo completo en Códigos de error.
Idempotency-Key
Mutaciones sensibles aceptan el headerIdempotency-Key (string arbitrario, máx 255 chars). Repetir el mismo POST con la misma key devuelve la misma respuesta sin re-ejecutar la lógica.
Rate limits
Cada respuesta a una ruta con throttling expone:
El default global es 100 req/min por IP. Algunos endpoints específicos tienen overrides (ej.
/public/events/ingest permite 200/min).
Cuando se excede el límite, la API devuelve 429 Too Many Requests con el envelope de error:
Versioning
Endpoints legacy viven directamente bajo/api/... y mantienen su shape histórico.
Endpoints nuevos o migrados viven bajo /api/v1/... y siguen 100% estas convenciones (envelope object, paginación cursor, etc.).
Ejemplos:
/v1/ correspondiente y deprecan la legacy.
Headers que el servidor siempre setea
Headers que el cliente puede enviar
Próximos pasos
- Códigos de error — catálogo completo de
error.type/error.code - Paginación — usar cursores correctamente
- Idempotencia — patrones de retry seguros
- Endpoints — referencia exhaustiva
- Eventos (notifications) — payload-by-payload del catálogo