/api, desplegada en Vercel como parte del mismo despliegue que el dashboard.
El orden en que se atiende una petición
Todo pasa primero por tres middlewares globales:logger, requestId y secureHeaders. El requestId es el que verás en cada error y el que debes citar al pedir soporte.
Después, cada superficie tiene su propia cadena:
/api/v1/* — dashboard
/api/v1/* — dashboard
sessionMiddleware resuelve la sesión de Better Auth · tenantMiddleware carga el tenant desde el header x-tenant-slug que inyecta el middleware de Next · tenantAccessMiddleware verifica que ese usuario pertenezca a ese tenant.A partir de ahí el handler tiene c.get('tenant') y c.get('session'), y toda consulta debe filtrar por tenantId./api/v1/portal/* — portal de familias
/api/v1/portal/* — portal de familias
Lo anterior más
portalMiddleware. Quien entra es el responsable de la cuenta financiera; finance_account_members decide de qué estudiantes ve información. Cambiar de hijo no divide la cuenta: es la misma sesión mirando otro estudiante./api/client/v1/* — integraciones
/api/client/v1/* — integraciones
clientApiAuthMiddleware valida el token de servicio, resuelve el tenant, comprueba scopes, IP allowlist, rate limit y módulos habilitados. No hay sesión ni cookies: es server-to-server puro./api/public/* — internet
/api/public/* — internet
Sin sesión. Algunos endpoints reciben
tenantMiddleware (los del portal público), y cada uno se defiende por su cuenta: token de un solo uso, firma del proveedor, o tope de peticiones por IP./api/internal/* — Trigger.dev
/api/internal/* — Trigger.dev
internalApiAuthMiddleware exige el header con INTERNAL_API_SHARED_SECRET. Es el camino de vuelta que usan las tareas en segundo plano para entrar a la app.Qué hay alrededor
OpenAPI, y por qué solo una capa lo tiene
El Client API se declara con@hono/zod-openapi: cada endpoint lleva su esquema de Zod, y de ahí sale el documento OpenAPI 3.1 que alimenta la pestaña Referencia, el Swagger en /api/client/swagger y la colección de Postman en /api/client/postman.json.
El resto de la API usa Hono a secas. Hay un app.doc('/openapi.json') para /api/v1, pero solo se monta cuando NODE_ENV !== 'production': existe para desarrollo, no como contrato público. Por eso las superficies internas se documentan como catálogos extraídos del código y no como referencia de esquemas.