The Pipefort API exposes eleven endpoints underDocumentation Index
Fetch the complete documentation index at: https://docs.pipefort.com/llms.txt
Use this file to discover all available pages before exploring further.
/api/*.
All non-health endpoints require a Supabase JWT in the Authorization header:
SUPABASE_JWT_SECRET) and extracts user_id for downstream queries.
GET /api/health
Unauthenticated health check. Returns { "status": "ok" }.
GET /api/repos
Refreshes the user’s repositories from GitHub (across all their installations) and persists them. Returns the stored rows.
Response
{ "connected": false, "repositories": [] }.
POST /api/scan
Scans a single repository. The client loops this across repos client-side for org-wide scans, keeping each request short.
Request
ruleset defaults to "all" if omitted.
Response
findings array uses the same shape as the CLI’s JSON output — they share scanner.Finding. The rule_id field is the stable per-check identifier the Rule settings page toggles on; category is the coarser OWASP / best-practice group several rules can share.
The findings returned and the severity counts both reflect any rule preferences the user has set — filtering happens server-side before persistence, so findings and counts always agree.
GET /api/github/callback
Links a freshly-created GitHub App installation to the signed-in user. GitHub redirects here with ?installation_id=...; the SPA forwards it with the user’s bearer token so the API can associate the two.
Query params
| Param | Required | Description |
|---|---|---|
installation_id | yes | The numeric installation ID GitHub provides on the redirect. |
Rule settings
The seven endpoints below back the Rule settings page (global toggles) and the Rule overrides card on each repository detail page (per-repo overrides). Reads return sparse rows — rules with no entry are treated as default-enabled per the catalog.GET /api/rules
Returns the canonical rule catalog (static — same data the SPA renders).
surface is "workflow" or "repo-settings".
GET /api/rule-settings
Returns the user’s sparse global preferences. Missing rule IDs are default-enabled.
PUT /api/rule-settings/{rule_id}
Upserts a global preference. Returns 204 No Content. Body:
rule_id against the catalog; unknown slugs return 400.
DELETE /api/rule-settings/{rule_id}
Clears the global row, reverting the rule to default-enabled. Idempotent (204 even if no row existed).
GET /api/repositories/{repo_id}/rule-overrides
Returns the sparse list of override rows for one repo. The user must own the repo (verified via the same path POST /api/scan uses) — 404 otherwise.
PUT /api/repositories/{repo_id}/rule-overrides/{rule_id}
Upserts an override for (user, repo, rule). Body { "enabled": bool }. Returns 204.
DELETE /api/repositories/{repo_id}/rule-overrides/{rule_id}
Clears the override, reverting the rule to inherit from the global setting. Idempotent.
Reading data directly (no API call)
Reading scans, findings, repositories, installations, andrule_settings does not go through the Go API — the SPA queries Postgres directly via supabase-js. Row-level security (auth.uid() = user_id) scopes every result to the signed-in user.
The API only handles writes (persisting scan results and rule preferences), GitHub-side reads (which need an installation token), and the installation link callback.