API Reference Overview: 56 Endpoints, Three Auth States, One Error Contract
The interface map before the docs: five endpoint partitions, master/session/scoped auth states, the universal error envelope, and the rate-and-cache rules wri
# The interface map before the docs
Treat the content layer as building blocks: **56 API endpoints, three authentication states, one error contract** — all interactively verifiable in the /docs console (every endpoint has a live try-it). This piece is the overview to read before the docs: how the surface is partitioned, which key fits which job, how to read errors, and the rate/cache rules. Endpoint count and version are always live at `GET /api/health`.
## Endpoint map: five partitions
| Partition | Prefixes | Content | Auth |
|---|---|---|---|
| Public content | /api/articles · /api/courses · /api/markets · /api/showcase | lists and details for articles/courses/markets/works | none |
| Site metadata | /api/summary · /api/taxonomy · /api/sitemap-data · /api/settings | counters, taxonomy vocabulary, sitemap data, public settings | none |
| Member & community | /api/member/* · /api/showcase submissions | profile, progress, submissions, likes | member token axm_* |
| Admin | /api/admin/* | content CRUD, review, tokens, settings, audit | master key or session axs_* (or scoped axn_*) |
| Ops probes | /api/health · /api/radar/* | version/build/latency probes, monitoring radar | health public; radar shares session |
The count 56 is the **registry-measured number**: the /docs console's endpoint registry and its prose are injected from one source, so they cannot drift (mechanism since v4.9.0). Older matrix documents quoting 73 are historic copy — deprecated.
## Three authentication states, three jobs
- **Master key:** full privilege, environment-level. Belongs only in server environment variables; suited to server-side batch jobs and ops scripts. Largest blast radius if leaked — see the token-management chapter for rotation discipline.
- **Console session (axs_*):** password-exchanged, HMAC-signed, 12-hour validity, scope `*`. What humans use in the console; the radar page shares it (no second login since v4.9.0).
- **Scoped token (axn_*):** authorized per scope vocabulary (articles / markets / courses / settings / tokens / ops / ugc …), individually revocable. **The right key for programs and agents** — least-privilege practice lives in the agent-integration piece.
```bash
# one probe per state (tokens from env, never in shell history)
curl -s $PORTAL/api/health | head -3 # public probe
curl -s -H "Authorization: Bearer $AXN_TOKEN" "$PORTAL/api/admin/articles?limit=1" # scoped token
# unauthenticated admin access -> the standard 401 error envelope below
```
## The error contract: one envelope everywhere
Every non-2xx response shares a single JSON envelope: `{ "error": human message, "code": machine code, "requestId": trace id }`. Codes come in families — 40xxx parameter/validation, 401xx/403xx auth, 404xx missing, 409xx conflict, 429xx rate — with field-level errors carrying a `field` hint. Integration rule: **programs branch on `code`, humans read `error`, tickets quote `requestId`** — the trio turns cross-system debugging from guessing into looking-up.
## Rates and caches: the rules live in response headers
- **Write rate:** admin writes are limited around 60 req/min (design batch imports to that; ≥2 s spacing is safe). Hitting the limit returns 429 with Retry-After semantics.
- **Read cache:** public lists/details ride the edge cache (maxAge 15–60 s + SWR). Freshly written data may read stale inside the window — reconcile via admin endpoints (direct DB reads) or wait out the window.
- **Observability headers:** every response carries `x-axion-latency-ms` (this request's cost) and `x-axion-d1` (q/r/w/ms counters for real D1 spend) — quote them when something looks slow.
## Versioning and deprecation
The content API is additive by discipline: new fields appear, existing fields keep type and meaning; removals go through a deprecation window announced in the docs console changelog. Clients should parse tolerantly (ignore unknown fields) and pin nothing but the envelope contract above.