REST reference for the helPRs API. All endpoints under /api/v1/* require auth unless noted. Pydantic schemas are defined in apps/api/src/helprs/modules/*/schemas.py; see data-models-api.md for the field details.
Conventions
- Base path:
/api/v1 - Unauthenticated endpoints return
401 Unauthorizedwhen a bearer token is missing or invalid. Installation/session access failures return403 Forbidden. - Rate limiting is applied per route (via
slowapi). Limits are shown inline below. {installation_id}in paths is the GitHub installation ID (integer), not the internal UUID.- Session IDs are UUIDs.
Unauthenticated liveness probe that also checks DB reachability.
- 200
{"status": "ok", "db": "ok"}— API + DB healthy. - 503
{"status": "degraded", "db": "unreachable"}— API up, DB unreachable.
Redirects to GitHub OAuth (github.com/login/oauth/authorize). Sets an httpOnly oauth_state cookie for CSRF (10 min TTL). Scopes requested: read:user user:email read:org.
- 302 redirect to GitHub.
- Rate limit: 10/min.
Handles two entry flows: OAuth login (with state) and GitHub App install (with installation_id + setup_action, no state).
Query params: code (required), state (OAuth flow), installation_id + setup_action (install flow).
On success: creates/updates the user, issues an access token, sets an httpOnly refresh_token cookie (7 days), and redirects to {APP_BASE_URL}/auth/callback?access_token=....
- 302 redirect on success.
- 401 on missing/invalid
state. - Rate limit: 10/min.
Rotates the access token using the refresh_token httpOnly cookie. Writes a new refresh_token cookie on the response.
- 200
TokenResponse { access_token, token_type: "bearer" }. - 401 if the refresh cookie is missing or invalid.
- Rate limit: 10/min.
Requires auth. Returns the authenticated user.
- 200
UserResponse. - Rate limit: 30/min.
Requires auth. Returns aggregated session statistics for the user.
- 200
UserStatsResponse { daily_counts: [...], totals: {...} }. - Rate limit: 30/min.
Clears the refresh_token cookie.
- 200
{"status": "ok"}.
All endpoints require auth. Admin endpoints additionally call verify_admin_permission.
List installations the user has access to (owns, or org member).
- 200
InstallationListResponse { items: InstallationResponse[], total }. Each item includessession_count, BYOK status, suppression labels, andpost_results_to_pr. - Rate limit: 30/min.
Installation detail — requires admin permission on the installation.
- 200
InstallationDetailResponse. - 404 if unknown.
- Rate limit: 30/min.
Configure the BYOK Claude credential. Accepts API keys (sk-ant-api03-...) and OAuth tokens (sk-ant-oat...). OAuth tokens skip server-side validation.
- Request:
BYOKConfigureRequest { api_key }. - 200
BYOKConfigResponse. - 404 if installation unknown.
- Rate limit: 10/min.
Remove the BYOK credential.
- 204 No Content.
- 404 if installation unknown.
- Rate limit: 10/min.
Update the list of PR labels that cause helPRs to skip session creation (matched case-insensitively when a PR is opened).
- Request:
SuppressionLabelsRequest { labels: string[] }. - 200
SuppressionLabelsResponse { labels }. - Rate limit: 10/min.
Paginated session history for an installation.
- Query params:
page(default 1),per_page(default 20, max 100),status(optional filter). - 200
PaginatedSessionsResponse { items, total, page, per_page, total_pages }. - Rate limit: 30/min.
Enable or disable automatic posting of challenge-me score cards to PRs.
- Request:
PostResultsSettingRequest { post_results_to_pr: boolean }. - 200
PostResultsSettingResponse { post_results_to_pr }. - Rate limit: 10/min.
Unauthenticated but HMAC-verified via the X-Hub-Signature-256 header (shared secret GITHUB_WEBHOOK_SECRET). Required header: X-GitHub-Delivery.
Flow: verify HMAC → persist raw event → return 200 → dispatch processing as a background task. Duplicate deliveries (same X-GitHub-Delivery) are idempotent.
- 200
{"status": "ok", "duplicate": false|true}. - 400 on missing
X-GitHub-Delivery, invalid JSON, or HMAC failure. - Handled events:
installation.*,pull_request.opened,pull_request.synchronize. Other events are logged and ignored (still stored for audit). - Rate limit: 100/min.
All endpoints require auth. Installation access is checked at session creation; session-level access (verify_session_access) is checked on all other routes.
Create a session record and start a Claude runner container for a given PR + skill.
- Request:
CreateSessionRequest { installation_id, pr_number, repo_full_name: "owner/repo", skill_name }. - 201
ContainerSessionResponse. - 404 if the installation is unknown or has no BYOK configured.
- Rate limit: 10/min.
Current session status and metadata.
- 200
ContainerSessionResponse. - Rate limit: 30/min.
SSE stream of live container output (while status = RUNNING).
- Query param:
offset(default 0) — number of events to skip, for client-side resume. Also read fromLast-Event-IDheader (set automatically byEventSourceon reconnect). - 200
text/event-stream. Headers:Cache-Control: no-cache,X-Accel-Buffering: no. - 404 if the container is not running.
- Each event is a line-delimited SSE message carrying a stream-json object. On stream end, a final
event: donecarries{"message": "...", "status": "completed" | "failed"}. - Rate limit: 60/min.
Persisted stream-json events (JSONB) for replay without SSE. Suitable for rendering completed sessions.
- 200
SessionEventsListResponse { session_id, events: SessionEventResponse[], total }, ordered byevent_id. - Rate limit: 30/min.
Parsed score card for a completed session (currently only emitted by the challenge-me skill).
- 200
ScorecardResponse { session_id, scorecard, xp_earned }.scorecardisnullif none was extracted. - Rate limit: 30/min.
Send a follow-up message to a running container. Delivered to the container's Claude CLI stdin via a FIFO (docker exec).
- Request:
SendMessageRequest { content }. - 200
SendMessageResponse { session_id, status: "sent", message }. - Rate limit: 30/min.
Stop a running container (graceful SIGTERM then kill). Marks the session as COMPLETED or FAILED.
- 200
StopSessionResponse { id, status, message }. - Rate limit: 10/min.
Delete a session and its persisted events.
- 200
{"status": "deleted", "id": "..."}. - Rate limit: 10/min.
SQLAdmin panel mounted at /admin. Not part of the REST contract; see admin/views.py for the exposed models. Credentials:
- Development: any password (auto-auth).
- Production: the
ADMIN_PASSWORDenv var.