API Reference

REST API · v1

Hand-written against the OpenAPI spec (packages/contracts/openapi.yaml); a CI drift gate keeps this surface 1:1 with the live app. Base URL: https://api.forumatlas.com/v1.

All endpoints

Every live route, its required scope (see Authentication), and where it's documented.

All v1 API endpoints with required scopes
EndpointScopeDocs
GET /v1/health— (public)→
GET /v1/_edge_timingany key→
POST /v1/queryquery:read→
POST /v1/causalquery:read→
POST /v1/tutorquery:read→
GET /v1/usageusage:read→
POST /v1/briefbrief:write→
GET /v1/briefsbrief:read→
GET /v1/briefs/{id}brief:read→
GET /v1/briefs/{id}/bibliographybrief:read→
GET /v1/briefs/{id}/evidencebrief:read→
POST /v1/forecastforecast:write→
GET /v1/forecastsforecast:read→
GET /v1/forecasts/{id}forecast:read→
GET /v1/forecasts/{id}/historyforecast:read→
GET /v1/entities/searchentities:read→
GET /v1/entities/by_aliasentities:read→
GET /v1/entities/cross_sector_matrixentities:read→
POST /v1/entities/resolveentities:read→
GET /v1/entities/{id}entities:read→
GET /v1/entities/{id}/relationshipsentities:read→
GET /v1/sourcessources:read→
GET /v1/sources/{id}sources:read→
GET /v1/documents/{id}sources:read→
POST /v1/anomalies/subscribeanomalies:write→
POST /v1/public/entity-requests— (public)→

Common patterns

Pagination. Offset-based via offset + limit on every endpoint that pages. Default limit 20, max 100. Endpoints that return a fixed window rather than a page — /v1/sources/{id}?recent= — take neither. The drift gate reads this sentence and asserts both numbers against every route that declares limit, so an endpoint cannot quietly disagree with it.

Errors. Problem Details (RFC 9457). { "type": "...", "title": "...", "status": 4xx, "detail": "..." }

Verbs. Every GET also answers HEAD (same status and headers, no body), so a HEAD-defaulting uptime monitor reads the API correctly.

CORS. Browser calls are allowed from any origin: Access-Control-Allow-Origin: * with credentials disabled, since /v1 authenticates with a Bearer key in a header and uses no cookies. X-Request-Id and Retry-After are the exposed response headers. Note what this does not make safe: an API key shipped to a browser is readable by anyone using the page — call /v1 from your server, or mint a key scoped to exactly what the browser needs.

Rate limits. Two layers: a per-key requests-per-second limit (set on the key) and a pre-auth per-IP limit. Exceeding either returns 429 with a Retry-After header — that is the only rate-limit header sent.

Request IDs. Every response this API generates carries X-Request-Id; include it when reporting issues. One exception, and it is a request that never reached us: a malformed request line — a NUL byte in the path, for example — is rejected by our CDN’s own HTTP parser before it reaches our edge, and what you get back is the CDN’s plain 400 with no X-Request-Id and no Problem body. Nothing we deploy or configure runs on that path, so it is documented rather than fixed.

Versioning. Path-based /v1. Additive changes only within a major version.