Auth routes
| Route | Method | Auth | Purpose |
|---|---|---|---|
/api/auth/start | GET | none | Begin OAuth — create state JWT + CSRF cookie, redirect to GitHub |
/api/auth | GET | none (callback) | Exchange code, encrypt token, create session |
/api/auth/session | GET | session | Return SessionView (no token) |
/api/auth/logout | POST | session | Delete session, clear cookies |
Install routes
| Route | Method | Auth | Purpose |
|---|---|---|---|
/api/install/start | GET | session | Begin install, create install state JWT |
/api/install/callback | GET | session (via state JWT) | Validate install, merge session_installations |
/api/install/complete | POST | session | Programmatic install completion |
/api/install/status | GET | session | Installation snapshots + repo lists |
/api/install/webhook | POST | HMAC-SHA256 | GitHub App events |
Organization routes
| Route | Method | Auth | Purpose |
|---|---|---|---|
/api/organizations | GET | session | User’s orgs + install status |
/api/organizations/[login] | GET | session + access | Single org detail |
/api/organizations/[login]/mass-invite | POST | session + admin + installation | Bulk invite (synchronous) |
Org-scoped routes
| Route | Method | Auth | Purpose |
|---|---|---|---|
/api/[org]/organization/summary | GET | session + access | Repo/team/member counts |
/api/[org]/installation/access | GET | session + access | App install + missing-permission status |
/api/[org]/teams/members | GET | session + access | Team → member count |
/api/[org]/repository/analytics | GET | session + access | Per-day commits/additions/deletions from signals |
/api/[org]/leaderboard/score | GET, POST | session | Primary leaderboard (serve / recompute) |
/api/[org]/leaderboard/sync | POST | session | Manual sync; 429 if within 24 h cooldown |
/api/[org]/leaderboard/recompute | POST | session (dev-only, 403 in prod) | Destructive wipe + full recompute |
/api/[org]/leaderboard/repository | GET | session | Repo-scoped leaderboard |
/api/[org]/leaderboard/rules | GET, PUT | GET = session; PUT = admin | Read/update scoring rules |
/api/[org]/leaderboard/rules/presets | GET/POST/PATCH/DELETE | mutations = admin | Preset CRUD + activation |
GraphQL proxy
| Route | Method | Auth | Purpose |
|---|---|---|---|
/api/github/graphql | POST | session | Allowlisted GraphQL proxy |
Debug routes
All debug routes are gated by requireDebugAccess. See authorization for gate behavior.
| Route | Method | Auth | Purpose |
|---|---|---|---|
/api/debug/presets | GET | requireDebugAccess | List presets for an org |
/api/debug/recompute | POST | requireDebugAccess | Destructive recompute with optional re-ingest |
/api/debug/computed-scores | GET | requireDebugAccess | Raw computed_scores rows |
/api/debug/preset-by-id | GET | requireDebugAccess | Single preset by ID |
Common error codes
| Status | Meaning |
|---|---|
| 400 | Bad request — missing or malformed parameter |
| 401 | No valid session |
| 403 | Session valid but insufficient permissions (or production gate) |
| 413 | Payload too large (mass-invite: > 50 logins) |
| 429 | Rate limited (leaderboard sync: within 24 h cooldown) |
| 500 | Upstream GitHub error or unhandled exception |
Auth summary
Every protected route calls requireApiSession which checks either an Authorization: Bearer <sessionId> header or the gh_session cookie. Org-access routes additionally call requireOrganizationAccess. Admin mutations call requireOrganizationAdmin. See authentication and authorization for full detail.
Last updated on