API Usage
Spectral exposes a REST API via FastAPI. All routes are versioned under /api/v1/.
This guide covers authentication, common workflows, required headers, and error handling.
For the full endpoint reference, start the API server and visit /docs (Swagger UI).
See ADR-006 for the versioning strategy rationale.
Interactive API docs
Section titled “Interactive API docs”uv run --package spectral-api python -m spectral_apiopen http://localhost:8000/docs # Swagger UIopen http://localhost:8000/redoc # ReDoc (alternative)All request/response schemas are auto-generated from Pydantic models.
API versioning
Section titled “API versioning”All endpoints are prefixed with /api/v1/. The OTLP trace ingestion endpoint
follows the OpenTelemetry standard and lives at /otel/v1/traces.
/api/v1/auth/login # Auth (non-workspace)/api/v1/account/... # Account-scoped/api/v1/workspaces/{workspace_id}/... # Workspace-scoped via URL path/api/v1/operations/... # Platform-only operations/otel/v1/traces # OTLP standard endpointAuthentication
Section titled “Authentication”Every /api/* route requires authentication except:
POST /api/v1/auth/registerPOST /api/v1/auth/loginPOST /api/v1/auth/callbackPOST /api/v1/auth/reset-passwordGET /api/v1/auth/oauth/{provider}GET /api/v1/health(also/api/health)
JWT (browser / human users)
Section titled “JWT (browser / human users)”# Registercurl -X POST http://localhost:8000/api/v1/auth/register \ -H "Content-Type: application/json" \ -d '{"email": "dev@test.com", "password": "devpass", "tenant_name": "Dev"}'
# Logincurl -X POST http://localhost:8000/api/v1/auth/login \ -H "Content-Type: application/json" \ -d '{"email": "dev@test.com", "password": "devpass"}'# -> { "access_token": "eyJ...", "user_id": "...", ... }Pass the token as Authorization: Bearer <token> on subsequent requests.
API keys (programmatic access)
Section titled “API keys (programmatic access)”API keys are scoped to a workspace and grant two scopes: read:agents (fetch agent config)
and write:traces (push OTEL traces).
# Create a key (requires admin:workspace scope)curl -X POST http://localhost:8000/api/v1/workspaces/<workspace_id>/keys \ -H "Authorization: Bearer <token>" \ -H "Content-Type: application/json" \ -d '{"name": "CI Pipeline"}'# -> { "key": "sk_live_...", "key_id": "..." } (plaintext shown once)
# Use the keycurl http://localhost:8000/api/v1/workspaces/<workspace_id>/agents \ -H "Authorization: Bearer sk_live_..."Required headers
Section titled “Required headers”| Header | When | Example |
|---|---|---|
Authorization | Always (except public paths) | Bearer eyJ... or Bearer sk_live_... |
X-Workspace-Id | Workspace-scoped routes | X-Workspace-Id: 550e8400-... |
Content-Type | POST/PUT with JSON body | application/json |
Scopes
Section titled “Scopes”Authorization uses 11 action:resource scopes:
| Scope | Description |
|---|---|
read:workspace | Read workspace data (scans, changesets, traces) |
write:workspace | Create/update workspace data |
approve:agents | Accept changesets, promote agent configs |
admin:workspace | Workspace settings, API keys, invites |
admin:account | Account-level management |
read:agents | Fetch agent configuration (API key scope) |
write:traces | Push OTEL traces (API key scope) |
read:operations | Read operations-staff data |
write:operations | Write operations-staff data |
admin:operations | Administrative operations-staff actions |
delete:operations | Destructive operations-staff actions |
Common workflows
Section titled “Common workflows”1. Onboarding
Section titled “1. Onboarding”POST /api/v1/auth/register -> account + first workspaceGET /api/v1/auth/me -> user profile + workspace listPOST /api/v1/workspaces/{workspace_id}/keys -> API key for programmatic access2. Setting up agents and evaluations
Section titled “2. Setting up agents and evaluations”POST /api/v1/workspaces/{id}/agents -> create workspace agentPOST /api/v1/workspaces/{id}/evaluations/rubrics -> create rubric with scoring dimensionsPOST /api/v1/workspaces/{id}/evaluations/objectives -> create objective functionPOST /api/v1/workspaces/{id}/traces -> ingest traces or /otel/v1/traces -> OTLP trace ingestion3. Running an optimization scan
Section titled “3. Running an optimization scan”POST /api/v1/workspaces/{id}/scans -> start scan (202 Accepted, async)GET /api/v1/workspaces/{id}/scans/{scan_id} -> poll for status, resultsGET /api/v1/workspaces/{id}/scans/{scan_id}/events -> structured event logGET /api/v1/workspaces/{id}/scans/{scan_id}/cost -> cost breakdown by model4. Reviewing and promoting results
Section titled “4. Reviewing and promoting results”GET /api/v1/workspaces/{id}/changesets -> list proposed Change SetsGET /api/v1/workspaces/{id}/changesets/{id} -> detail with explainabilityPOST /api/v1/workspaces/{id}/changesets/{id}/accept -> accept and promotePOST /api/v1/workspaces/{id}/changesets/{id}/apply -> apply to managed templates5. Monitoring and dashboards
Section titled “5. Monitoring and dashboards”GET /api/v1/workspaces/{id}/control-plane -> cross-workflow KPIsGET /api/v1/workspaces/{id}/morning-briefing -> daily snapshotGET /api/v1/workspaces/{id}/workflow-overview -> workflow health overviewError responses
Section titled “Error responses”All errors follow RFC 9457 Problem Details format:
{ "type": "https://spectral.dev/errors/not-found", "title": "Resource Not Found", "status": 404, "detail": "Scan abc123 not found"}| Status | Meaning |
|---|---|
| 400 | Bad request — invalid parameters or business rule violation |
| 401 | Not authenticated — missing or invalid token |
| 403 | Forbidden — authenticated but lacks required scope |
| 404 | Not found — resource doesn’t exist or not in tenant |
| 422 | Validation error — request body failed Pydantic validation |
| 429 | Rate limited |
| 500 | Server error |
Domain errors from spectral.platform.shared.errors map automatically:
NotFoundError -> 404, InvalidTransitionError -> 400, BusinessRuleViolationError -> 400.
Response envelope
Section titled “Response envelope”Collections return a paginated wrapper:
{"results": [...], "pagination": {"total": 42, "limit": 20, "offset": 0}}Single items return the object directly (flat, no wrapper).
Errors use RFC 9457 Problem Details (see above).
Endpoint groups
Section titled “Endpoint groups”The API is organized into 20 resource-based router modules:
| Group | Prefix | Description |
|---|---|---|
| Auth | /api/v1/auth/* | Registration, login, logout, OAuth, password reset, profile |
| Accounts | /api/v1/account/* | Account management, members, invites |
| Workspaces | /api/v1/workspaces/{workspace_id}/* | Workspace CRUD, members, autonomy settings, health |
| Keys | .../keys | API key lifecycle (create, list, revoke) |
| Agents | .../agents/* | Agent CRUD, configuration, templates |
| Agent | .../agent/* | Agent chat, conversations, approvals |
| Scans | .../scans/* | Scan lifecycle, events, cost, reports, scheduling |
| Changesets | .../changesets/* | Changeset lifecycle (accept, apply, reject, rollback) |
| Changeset Clusters | .../changesets/{id}/clusters/* | Failure cluster browsing and curation |
| Changeset Experiments | .../changesets/experiments/* | Experiment tracking |
| Changeset Validation | .../changesets/{id}/validation/* | Holdout validation runs |
| Rubrics | .../evaluations/rubrics/* | Rubric CRUD, generation, suggestions |
| Objectives | .../evaluations/objectives/* | Objective function CRUD |
| Samples | .../samples/* | Sample set management |
| Traces | .../traces/* | Trace browsing, feedback |
| Inference | .../agents/{id}/infer-template | Template inference from scan context |
| Dashboard | /api/v1/workspaces/{workspace_id}/... | Control plane, morning briefing, workflow overview |
| Supervisor | .../supervisor/* | State, next-action, nightly plan, frontier report, failures |
| OTEL | /otel/v1/traces | OTLP trace ingestion and stats |
| Operations | /api/v1/operations/* | Model health, model config (requires operations account role) |
For the complete list of endpoints with request/response schemas, see the Swagger UI at /docs.