API reference
Base URL: http://localhost:8080/api/v1 (port from Configuration).
All bodies are JSON. Auth: Authentication and roles.
Flagship flow with runnable examples: REST API.
Field values for evidence_mode, equivalence status, fix status and finding kinds:
Evidence and status vocabulary. Error codes: API errors.
This page tracks the Goa design (api/design/*.go) and the generated OpenAPI 3 spec
(api/gen/http/openapi3.yaml); make docs-contract-check fails if they diverge.
Investigations
| Method |
Path |
Description |
| POST |
/investigations |
Body: title, sql, optional connection_id, analyze. Creates an investigation and runs plan analysis |
| POST |
/investigations/from-regression |
Body: regression_alert_id (uuid). Opens, or reuses, an investigation from a regression alert |
| POST |
/investigations/from-postgrest |
Body: postgres_log, optional title, connection_id, analyze, server_timing, http_duration_ms. Imports one captured GET/HEAD request (table, view or RPC, including failed requests); see capture requirements |
| GET |
/investigations |
Query: limit (default 20, max 100), offset |
| GET |
/investigations/{id} |
Full investigation: evidence, candidate, comparison |
| POST |
/investigations/{id}/suggest-rewrite |
AST-based rewrite suggestions. Returns candidates[] (sql, rationale, category). No SQL executes |
| POST |
/investigations/{id}/rank-candidates |
Query param analyze (default false, not a body field). Dry-EXPLAINs rewrites and index DDL; returns baseline, candidates[], recommendation |
| POST |
/investigations/{id}/candidate |
Body: candidate_sql, analyze, verify_results, binds. Attaches a candidate, runs compare, optionally verifies results (needs the query permission) |
| POST |
/investigations/{id}/fix |
Body: fix_status ∈ proposed|verified|applied|abandoned (never confirmed/regressed, those are system-only), fix_reference |
| POST |
/investigations/{id}/report |
Query param accept_sample_match (not a body field). Generates a deterministic engineering report; gated by equivalence, see Verify result equivalence |
Workspace
| Method |
Path |
Description |
| GET |
/workspace/overview |
Landing summary (stats / attention counts) |
| GET |
/workspace/regressions |
Query: limit (default 10, max 50), include_acknowledged. Regression inbox |
| POST |
/workspace/regressions/{id}/acknowledge |
Acknowledge one alert (204) |
| GET |
/demo/scenarios |
Guided demo scenarios with date literals computed from the live seed, problem SQL only, no answer-key rewrite |
| GET |
/trust |
Query: connection_id. Security & Trust snapshot for the UI |
Queries
| Method |
Path |
Description |
| POST |
/queries/run |
Body: sql, limit (default 100, max 1000), connection_id. Executes read-only SQL |
| POST |
/queries/explain |
Body: sql, analyze, connection_id. EXPLAIN (FORMAT JSON), or EXPLAIN (ANALYZE, ...) when allowed |
| POST |
/queries/explain/compare |
Body: before_sql, after_sql, analyze, verify_results, timing_runs (1–5, default 1), connection_id, binds. Standalone plan/result compare |
| GET |
/queries/stats |
Query: order_by ∈ total_time|mean_time|calls, limit (default 20, max 100), connection_id. pg_stat_statements view |
| POST |
/queries/saved |
Body: name, sql, description, tags, connection_id. Save a query |
| GET |
/queries/saved |
Query: limit, offset, tags, connection_id |
| GET |
/queries/saved/{id} |
Get one saved query |
| DELETE |
/queries/saved/{id} |
Delete (204) |
Connections
| Method |
Path |
Description |
| GET |
/connections |
{"items":[{"id","name"}]}. No secrets returned |
Schema
| Method |
Path |
Description |
| GET |
/schema |
Query: connection_id. Allowed schemas, tables, columns |
Suggestions
| Method |
Path |
Description |
| GET |
/suggestions/queries |
Query: intent, limit. Curated/intent-matched SQL |
| GET |
/suggestions/questions |
Query: connection_id, limit (default 8). Suggested natural-language questions |
| GET |
/suggestions/similar |
Query: text, limit. Semantic search over saved queries (needs embeddings) |
| POST |
/suggestions/ask |
Body: question, connection_id. NL → SQL → narrative (needs LLM) |
| POST |
/suggestions/chat |
Body: question, session_id, connection_id. Returns history, follow_ups (needs LLM) |
| POST |
/suggestions/explain |
Body: sql. Plain-English explanation (needs LLM) |
Reports
| Method |
Path |
Description |
| POST |
/reports/generate |
Body: sql, saved_query_id, connection_id. Workbench LLM narrative report, with a deterministic fallback |
| GET |
/reports/{id} |
Get a report |
| GET |
/reports |
Query: limit, offset, saved_query_id, connection_id |
| GET |
/reports/similar |
Query: text (required), connection_id, limit (≤20) |
| POST |
/reports/rewrite |
Body: report_id, instruction. LLM-assisted narrative revision |
| POST |
/reports/share |
Body: report_id, expires_in_hours (1–720). Requires SECURITY_SHARE_LINKS_ENABLED=true |
| GET |
/reports/shared/{token} |
Public, unauthenticated. View a shared report |
| GET |
/reports/{report_id}/shares |
List active share links for a report |
| POST |
/reports/shares/{id}/revoke |
Revoke a share link |
Schedules
| Method |
Path |
Description |
| GET |
/schedules |
List |
| POST |
/schedules |
Body: name, saved_query_id or sql, connection_id, interval_expr (@every <duration>), timezone, destination_type (webhook|log), destination_target, enabled |
| PUT |
/schedules/{id} |
Update the same fields |
| DELETE |
/schedules/{id} |
Delete (204) |
| POST |
/schedules/{id}/run |
Run now |
| GET |
/schedules/{id}/runs |
List runs |
| POST |
/schedule-runs/{run_id}/retry |
Retry a failed run |
| GET |
/webhook-deliveries |
List webhook delivery attempts |
Dashboards
| Method |
Path |
Description |
| GET |
/dashboards |
List |
| POST |
/dashboards |
Body: name |
| GET |
/dashboards/{id} |
Get |
| PUT |
/dashboards/{id} |
Body: name, widgets[] |
| DELETE |
/dashboards/{id} |
Delete (204) |
| GET |
/dashboards/{id}/resolve |
Get with each widget's data resolved |
Manual routes (not part of Goa/OpenAPI)
Hand-registered in cmd/server/*.go. Classified by who they're for:
Public: never require authentication
| Path |
Purpose |
GET /health |
Liveness |
GET /ready, GET /ready/connections |
Readiness, see Health and monitoring |
GET /version |
Build version |
GET|POST /auth/login, /callback, /logout, /refresh, /auth/session |
Browser OIDC, registered only when OIDC is configured |
GET /reports/shared/{token}, GET /web/reports/export/shared/pdf |
Shared-report view (Goa route + web export) |
Authenticated: any signed-in user
| Path |
Purpose |
GET /api/v1/settings |
LLM, embedding, analytics and auth flags for the UI |
GET /api/v1/me, /me/organizations |
Current user and their memberships |
POST /api/v1/me/organization |
Switch active organization |
GET /web/reports/export, /export/pdf, /export/md, /export/json, /export/sql |
Report export in various formats |
GET /metrics |
Requires auth when SECURITY_AUTH_ENABLED=true |
| Path |
Purpose |
GET|POST /api/v1/admin/api-keys, POST .../{id}/revoke |
Managed API keys. role is required and must be recognised, scopes may only hold admin, write, read (400 otherwise) |
GET|POST /api/v1/admin/organizations |
Platform admin only |
GET|POST|DELETE /api/v1/admin/memberships |
Organization membership. role must be recognised (400 otherwise) |
GET|POST|DELETE /api/v1/admin/connection-assignments |
Which connections an org may use |
POST|DELETE /api/v1/admin/connection-permissions |
Per-connection actions granted to an org |
GET|POST|DELETE /api/v1/admin/connection-secrets |
Per-organization connection credentials |
Internal: diagnostics, not a stable contract
| Path |
Purpose |
GET /api/v1/diagnostics/db-privileges |
Database security-boundary audit |
GET /api/v1/diagnostics/webhook-policy |
Webhook allowlist snapshot |
Full auth-boundary rules: Authentication and roles.
See also
REST API · API errors ·
Evidence and status vocabulary · Embedded Go ·
Configuration reference