Naming#
JSON fields: camelCase (matches Zod schemas)
URL paths: kebab-case for multi-word segments
Collections: plural nouns (/rooms, /problems)
Actions: nested under resource when RPC-style is clearer than CRUD (/rooms/:id/run)
Content-Type#
All requests and responses use application/json unless otherwise noted.
SSE endpoints use text/event-stream.
Authentication#
Bearer JWT in Authorization header for all protected endpoints
Access token: short-lived (15m), stored in JavaScript memory
Refresh token: long-lived (7d), HTTP-only Set-Cookie (SameSite=Strict; Secure; HttpOnly; Path=/auth)
On page refresh, call POST /auth/refresh to get a fresh access token
Admin endpoints require role: 'admin' in JWT claims
All collection endpoints use cursor-based pagination:{
"data": [],
"pagination": {
"nextCursor": "eyJpZCI6MTAwfQ==",
"hasMore": true
}
}
Query parameters: cursor (string), limit (integer, default 20, max 100).Standard Query Parameters for Collections#
| Parameter | Type | Description | Used By |
|---|
sortBy | string | Field to sort by | Problems, Sessions, Admin Users, Admin Rooms |
sortOrder | 'asc' | 'desc' | Sort direction | All sortable endpoints |
search | string | Full-text search | Problems, Admin Users |
fromDate | ISO 8601 | Lower bound date filter | Sessions, Admin Audit Logs |
toDate | ISO 8601 | Upper bound date filter | Sessions, Admin Audit Logs |
HTTP Status Codes#
| Code | Meaning |
|---|
200 | Success (GET, PATCH, action endpoints) |
201 | Created (POST that creates a resource) |
202 | Accepted (async job queued, e.g. run, submit, AI, analysis) |
204 | No content (DELETE, logout, action POST with no response body) |
400 | Validation error / malformed request |
401 | Missing or invalid authentication |
403 | Authenticated but insufficient permissions |
404 | Resource not found |
409 | Conflict (duplicate resource, invalid state transition) |
429 | Rate limit exceeded |
503 | Service unavailable (circuit breaker open) |
500 | Internal server error |
504 | Gateway timeout (circuit breaker timeout) |
Idempotency#
| Verb | Behavior |
|---|
GET | Always idempotent |
PUT | Always idempotent |
DELETE | Always idempotent (204 or 404) |
POST + Idempotency-Key | 24h dedup in Redis (room creation, AI messages) |
POST naturally idempotent via 409 | Feedback, matchmaking, room join |
POST intentionally non-idempotent | run, submit, analyze (each creates a new job) |
Modified at 2026-03-12 05:26:10