# API Base: `/api`. Signed media: `/media/…`. Health: `GET /api/health` (outside the rate-limited mux). ## Response contract ### Success Ordinary JSON; standard 2xx codes. ### Error ```json { "error": "user-facing message", "code": "unauthorized", "requestId": "…" } ``` Response header: `X-Request-ID` (generated by the server if the client did not send one). The frontend maps these via `toUserError` and `ApiError`. ## Authentication | Method | Use | |--------|-----| | Cookie `pargar_access` | Same-origin browser | | `Authorization: Bearer ` | Tests, tools, in-memory token frontends | | Cookie / body `refreshToken` | `POST /api/auth/refresh` | WS: Bearer → subprotocol `bearer` + token → access cookie. Query string is forbidden. ## Public (no login) | Method | Path | Notes | |--------|------|--------| | GET | `/api/auth/captcha` | Image challenge | | POST | `/api/auth/login` | Login | | POST | `/api/auth/refresh` | Session rotation | | POST | `/api/auth/recovery/challenge` | Disabled (404) — public student recovery is off | | POST | `/api/auth/recovery/reset` | Disabled (404) | | GET | `/api/auth/register-status` | Whether public registration is on | | POST | `/api/auth/register` | Public registration | | GET/POST | `/api/auth/register-invite/{token}` | Invite status / consume | | GET | `/api/certificates/{publicId}` | Public certificate | | GET | `/api/community` | Donation / support | | GET | `/api/sponsors` | Landing sponsors | | GET | `/api/exports/chats/{token}` | Single-use chat archive download | ## Authenticated (student+) Key examples: - `GET /api/auth/me` · `POST /api/auth/logout` - Tree and lessons: `/api/tree` · `/api/lessons/{id}` · heartbeat · quiz - `GET /api/leaderboard/weekly` · `GET /api/challenges` - Events and RSVP: `/api/events…` - Chat: `/api/chats/…` · upload `/api/chats/upload` - Notifications, unlock/reset requests - My certificate: `/api/me/certificate` · issue · physical - Avatar: `PUT /api/me/avatar` · `POST /api/me/avatar-photo` - `GET /api/ws` Full handler list: [`backend/internal/api/router.go`](../backend/internal/api/router.go). ## Staff / admin Prefix `/api/admin/…`: - **admin:** stats, users (CRUD, lock, role, reset-password), challenges, announcements, settings, sponsors, physical orders, invites, phone whitelist/blacklist, chat-export (+ tokens) - **staff (admin + mentor):** learning overview/students, student unlock, chapters / lessons / questions / videos, events - `GET /api/media/sign` staff only Mentors do not manage accounts, registration, challenges, announcements, or site settings; they handle learning status and teaching content. ## Versioning No version prefix for now; call out breaking changes in CHANGELOG/PR. External clients should prefer same-origin cookies or short-lived Bearer tokens.