API overview
Purpose and authority
apps/api is the hand-written Fastify and TypeScript HTTP API for Wits Quest.
It is the protected boundary between the untrusted browser and authoritative
identity, content, eligibility, challenge, reward, collection, deck, and CPU
match state.
The browser sends player intent and renders responses. It does not determine authenticated identity, location eligibility, answer correctness, scores, rewards, ownership, deck legality, legal match actions, or outcomes. Those decisions remain in the API, shared server-consumed rules, and PostgreSQL/PostGIS.
Addresses and versioning
Local development uses:
| Boundary | Address |
|---|---|
| API origin | http://127.0.0.1:3000 |
| Health | http://127.0.0.1:3000/health |
| Versioned root | http://127.0.0.1:3000/api/v1/ |
| Interactive OpenAPI | http://127.0.0.1:3000/documentation/ |
| OpenAPI JSON | http://127.0.0.1:3000/documentation/json |
The repository's recorded production API origin is
https://witsworld-api-a4awdtdahbbkh8g4.southafricanorth-01.azurewebsites.net.
The deployed boundary review
records public health, versioned-root, authentication, and CORS checks against
that origin on 22 August 2026. The generated
interactive reference
and OpenAPI JSON
use the same deployed application.
Application routes are placed beneath /api/v1. New backward-incompatible
contracts require a new version boundary rather than a silent change to the
existing prefix. /health and /documentation/ are operational or reference
routes outside the application prefix.
The API is externally reachable, but that does not make protected game data anonymous or public. Health, the versioned root, and OpenAPI are public; gameplay, account, and author operations declare bearer authentication and enforce their own role and ownership rules.
Authentication and authorisation
Protected operations expect an Auth0 access token:
Authorization: Bearer <access-token>
The API validates the token signature, issuer, audience, and expiry through the
configured Auth0 issuer/JWKS boundary. It then resolves the exact validated
issuer-and-subject pair to a local player. The local database record supplies
the application lifecycle and player or author role; a browser-supplied
player ID or role is not authoritative.
Authentication answers who the principal is. Route pre-handlers and services separately enforce active-account, role, ownership, publication, and object permissions. CORS permits the configured exact Web origin but is not an authentication mechanism.
Resource areas
The generated OpenAPI groups the current contract into these areas:
| Area | Responsibility |
|---|---|
| System | Health and API version information |
| Authentication and account | Local identity, Player Name setup, and implemented account-lifecycle API boundaries |
| Events | Player-safe published-event discovery and server-authoritative location eligibility |
| Challenges | Timed attempt start/resume, answer locking, completion, marking, and completed-only review |
| Cards | Starter grant, catalogue-safe data, rewards, and the authenticated player's collection |
| Decks | Saved-deck CRUD, ownership validation, and active selection |
| Matches | Server-created CPU matches, legal action submission, recovery, and private history |
| Authoring | Author-only event, challenge, question, and card lifecycle operations plus audit boundaries |
The OpenAPI document is the endpoint-level reference for parameters, bodies, status codes, and response shapes. Narrative documents explain domain contracts that need more context, including the challenge-attempt contract, saved-deck design, and CPU match persistence.
Validation and errors
Fastify route schemas validate untrusted parameters, query values, and request bodies at runtime. Response schemas also define the player-safe data boundary used to generate OpenAPI.
Errors use a stable problem-style JSON envelope:
{
"type": "https://wits.world/problems/validation-error",
"title": "Request validation failed",
"status": 400,
"code": "VALIDATION_ERROR",
"detail": "One or more request values are invalid.",
"requestId": "server-generated-request-id"
}
Validation failures may additionally contain a validation array with safe
field and message values. Expected domain failures use explicit codes and HTTP
statuses. Unknown failures are logged server-side and returned as a generic
500 INTERNAL_ERROR; stack traces and internal exception details are not sent
to the client. JSON success bodies and all problem responses include the server
request identifier used for safe correlation; intentionally empty 204
responses have no body.
Bearer-protected active-player operations also document the implemented
per-process 429 RATE_LIMITED response and rate-limit headers. This does not
claim edge throttling for invalid-token traffic or aggregation across multiple
API processes.
OpenAPI generation and maintenance
The API registers @fastify/swagger before its routes and generates OpenAPI
3.0.3 from the route schemas at runtime. @fastify/swagger-ui serves the
interactive reference at /documentation/; the machine-readable document is
available at /documentation/json.
The repository deliberately does not maintain a second hand-written endpoint catalogue. Route integration tests inspect generated operations, bearer security declarations, safe responses, and important exposure boundaries. When an API contract changes, its route schema, implementation, tests, typed Web client, and any affected narrative contract must change together.
External publication evidence still needed
The repository supports a public generated reference and records one deployed boundary review. Future milestone evidence should retain the deployed commit, timestamp, public OpenAPI URL, successful retrieval of the JSON document, and a sanitised screenshot or artifact when the rubric requires it. That evidence must distinguish reference availability from successful authenticated use of a protected operation.
Related documentation
- Trust boundaries
- High-level data flow
- External integrations
- API application guide
- Azure deployment setup
AI declaration
This API overview was generated, edited, and reviewed with the assistance of Codex[GPT-5]. It summarises current repository schemas and recorded deployment evidence rather than replacing the generated OpenAPI contract.