Skip to main content

Convenciones API

La API v1 sigue un modelo consistente en toda la superficie: cada recurso lleva un campo object, 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 campo object que identifica su tipo:
El campo object permite a los consumidores discriminar tipos sin parsear el path o leer headers.

Listas paginadas

Las listas envuelven los items en un objeto con object: "list" y campos de paginación cursor:
Detalle completo en Paginación.

Request ID

Toda respuesta incluye el header X-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>).
Útil para soporte: incluye el request_id cuando reportes un problema.

Errores estructurados

Todos los errores siguen el envelope:
Para no romper consumers existentes, la respuesta también incluye los campos legacy 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 header Idempotency-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.
Detalle en Idempotencia.

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:
Para migrar, los nuevos PRs cambian el frontend o el integrador a la ruta /v1/ correspondiente y deprecan la legacy.

Headers que el servidor siempre setea

Headers que el cliente puede enviar

Próximos pasos