API y OpenAPI
API y OpenAPI
Sección titulada «API y OpenAPI»Asientra expone una API REST versionada (/api/v1/...) consumida por la SPA y disponible para integraciones externas. Usa JWT bearer auth con aislamiento multi-tenant garantizado por RLS.
Spec OpenAPI
Sección titulada «Spec OpenAPI»La spec viva está en asientra-api/openapi.yaml, generada desde rswag y actualizada en cada cambio de contrato. Importala en Postman, Insomnia o cualquier cliente OpenAPI 3.
Autenticación
Sección titulada «Autenticación»| Endpoint | Descripción |
|---|---|
| POST /api/v1/auth/login | Retorna access_token (15 min) + refresh_token (7 días) |
| POST /api/v1/auth/refresh | Rota el refresh y emite nuevo par de tokens |
| DELETE /api/v1/auth/logout | Revoca el refresh token |
Incluí el access token en cada request:
Authorization: Bearer <access_token>Los roles owner, admin y contador_senior requieren 2FA en el login. El campo two_factor_code va en el mismo body que email y password.
Tenant context
Sección titulada «Tenant context»Todo request a recursos tenant-scoped requiere el header:
X-Despacho-Id: <despacho_id>El middleware verifica que el usuario tenga membresía activa en ese despacho, luego ejecuta SET LOCAL app.current_despacho_id = <id> en la conexión Postgres. RLS filtra automáticamente todas las queries subsiguientes.
Versionado
Sección titulada «Versionado»- Cambios breaking → nueva versión
/api/v2/. La v1 se mantiene activa durante el periodo de migración. - Cambios aditivos →
/api/v1/con nuevos campos opcionales. No rompen clientes existentes.
Paginación
Sección titulada «Paginación»Todos los endpoints de colección aceptan:
GET /api/v1/clientes?page=2&per_page=25La respuesta incluye un objeto meta:
{ "data": [...], "meta": { "total": 120, "page": 2, "per_page": 25, "total_pages": 5 }}Filtros y ordenamiento
Sección titulada «Filtros y ordenamiento»GET /api/v1/facturas?filter[estado]=aceptado&sort=-fecha_emision,consecutivo-campo = orden descendente. Múltiples campos separados por coma.
Errores
Sección titulada «Errores»Formato JSON:API:
{ "errors": [ { "status": "422", "code": "partida_doble_violation", "title": "Error de validación", "detail": "La suma de débitos (₡1.000) no coincide con la suma de créditos (₡900)." } ]}Códigos HTTP estándar: 400 (bad request), 401 (sin token / token vencido), 403 (sin permiso), 404 (recurso no encontrado), 422 (validación de negocio), 429 (rate limit), 500 (error interno).
Rate limiting
Sección titulada «Rate limiting»Rack::Attack limita requests por IP y por token. Al superar el límite, la respuesta es 429 Too Many Requests con el header Retry-After: <segundos>.