The AIF HTTP API is a JSON REST interface used by the frontend and available for scripted integration. All application endpoints are mounted under a single base path and share the same authentication, CSRF, and rate-limit regime.
All API endpoints are served under a configurable base path. In the default production deployment, the portal runs behind a reverse proxy that forwards to Express on this prefix:
/aif/api
The base path is exposed to clients via GET /aif/api/config (see below). It is controlled by the BASE_PATH environment variable on the server (default /aif).
The API uses a JWT session cookie named aif_token. The cookie is set by the authentication provider after a successful login and carries the user's userId, netid, role, and displayName.
| Attribute | Value |
|---|---|
| Cookie name | aif_token |
| HttpOnly | true |
| Secure | true |
| SameSite | lax |
| Path | BASE_PATH (e.g. /aif) |
| Lifetime | 24 hours |
Callers drive authentication through the /auth/* endpoints (see auth.md). A browser client redirects to /auth/login and receives the cookie via the IdP callback. Non-browser clients must either run behind a reverse proxy that forwards a valid cookie or enable header-based authentication on the server side.
Role-based access is enforced at the middleware level. The three roles are builder, reviewer, and admin. Endpoints that require a specific role respond with:
401 Unauthorized— no valid cookie was presented403 Forbidden— the user's role is insufficient, or ownership is required and the caller does not own the resource
Some endpoints use an "owner or role" policy: the tool's owner is always permitted, as are users with any of the listed roles.
CSRF protection follows the double-submit cookie pattern:
- On every request, if the cookie
aif_csrfis missing the server sets it to a random 24-byte hex token. - State-changing requests (
POST,PUT,PATCH,DELETE) must echo the cookie back, either through thex-csrf-tokenHTTP header or as a_csrfform field on multipart uploads. - If the token is missing or does not match, the server returns
403 CSRF token mismatch.
The following requests are exempt from CSRF enforcement:
- Any request with method
GET,HEAD, orOPTIONS /auth/loginand/auth/callback(redirect-based SSO flows)- Server-Sent Events streams (paths ending in
/stream) - Health check (
/health)
The CSRF cookie is not HttpOnly, so browser JavaScript can read it directly from document.cookie.
# First GET establishes the CSRF cookie
curl -c cookies.txt https://portal.example.edu/aif/api/config
# Subsequent state-changing request echoes the token
TOKEN=$(grep aif_csrf cookies.txt | awk '{print $7}')
curl -b cookies.txt \
-H "Content-Type: application/json" \
-H "x-csrf-token: $TOKEN" \
-X PATCH \
-d '{"status":"pending"}' \
https://portal.example.edu/aif/api/registry/<id>/statusTwo rate-limit policies are applied as middleware:
| Scope | Window | Limit |
|---|---|---|
/auth/* |
15 minutes | 30 requests |
All other /api/* |
1 minute | 120 requests |
Responses include the standard RateLimit-* headers. Exceeding the limit returns 429 Too many requests.
Requests with a JSON body are capped at 1 MB. Multipart codebase uploads use a separate limit of 500 MB enforced by multer.
All error responses use this shape:
{ "error": "description of what went wrong" }The HTTP status code carries the semantic meaning. Common statuses across the API:
| Status | Meaning |
|---|---|
| 400 | Request body failed validation, or the operation is not valid for the resource's current state |
| 401 | Authentication required or the session token is invalid |
| 403 | CSRF mismatch, insufficient role, or caller is not the resource owner |
| 404 | Resource not found |
| 429 | Rate limit exceeded |
| 500 | Unhandled server error |
| 503 | Health check failed (database unreachable) |
Validation errors concatenate all Zod issues into a single semicolon-separated string, for example:
{ "error": "track: Number must be less than or equal to 4; reason: reason is required" }Two endpoints are always public and require no authentication:
Returns institution-specific values the frontend reads at runtime.
{
"institutionName": "University of Montana",
"institutionDomain": "umontana.edu",
"basePath": "/aif"
}Returns server health and database connectivity. The frontend does not call this endpoint; it is intended for external monitoring.
{ "status": "ok", "database": "connected", "uptime": 1234 }On database failure the endpoint returns 503:
{ "status": "error", "database": "disconnected", "error": "..." }- Content type:
application/json; charset=utf-8for all JSON responses. File downloads use appropriate MIME types (text/csv,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet, etc.). - Character encoding: UTF-8 throughout.
- Timestamps: ISO 8601 strings in UTC.
- Identifiers: Tools and pipeline runs use UUIDs; users use integer primary keys.
- Pagination: List endpoints that paginate accept
pageandlimitquery parameters (defaultpage=1,limit=50, maxlimit=100) and return{ items, total, page, limit }. - Query parameter sanitization: Free-text filters on enumerated columns (status, entity type, action) are filtered to
[a-z_]before being placed in parameterized SQL.
- Express parses cookies and JSON body (1 MB cap).
- CSRF middleware establishes or validates the double-submit token.
- Rate-limit middleware checks the appropriate bucket.
- Auth middleware reads the
aif_tokencookie, verifies the JWT, and attachesreq.userwhen valid. Protected routes reject unauthenticated callers here. - Route handlers run role/ownership checks and Zod validation.
- State-changing handlers wrap multi-query operations in
withTransaction()and emitaudit_logentries.
- auth.md — session lifecycle and the
/auth/*surface - intake.md — draft and submission routes
- registry.md — tool registry, status state machine, sandbox flag
- pipeline.md — pipeline execution and SSE streaming
- reports.md — agent output retrieval, downloads, finding status persistence
- review.md — review decisions, track overrides, self-certification
- admin.md — dashboard, user management, audit log, retention
- analytics.md — pipeline performance analytics
- notifications.md — in-app and email notification management