> ## Documentation Index
> Fetch the complete documentation index at: https://docs.oktolabs.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# REST API

> Pulse exposes the same surface as its MCP tools over HTTP. OpenAPI is available from the running Pulse process and as the static docs schema — this page covers authentication, the major route clusters, and curated examples for the most common workflows.

# REST API

Pulse's REST API is the same surface as the MCP tools, exposed over plain HTTP under `/api/v1` (`okto-pulse-core/src/okto_pulse/core/api/router.py:29`). The MCP server is a thin adapter that wraps these routes for AI agents — anything an agent can do via MCP, a script can do via REST.

<Note>
  **MCP is the canonical agent interface.** If you're connecting an AI agent, use [MCP](/reference/mcp) — the tool surface is more compact, parameters are typed, and `okto-pulse init --agents` configures it for you. Use the REST API for human-facing scripts, CI integrations, dashboards, and anything outside the MCP transport.
</Note>

***

## OpenAPI

The public docs publish a static source-derived schema at [`/openapi.json`](/openapi.json). A running Pulse process also publishes its own schema and two interactive UIs the moment it starts. The running process reflects the **exact** surface of your installed version; the static docs schema tracks the published docs release. For a source-derived route inventory, see [REST route catalog](/reference/rest-api-catalog).

| URL (default install)                                                            | What it serves                                                                                                                      |
| -------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| [`https://docs.oktolabs.ai/openapi.json`](https://docs.oktolabs.ai/openapi.json) | Static OpenAPI 3.1 schema for the docs release.                                                                                     |
| [`http://127.0.0.1:8100/openapi.json`](http://127.0.0.1:8100/openapi.json)       | OpenAPI 3.1 schema — the source of truth. Generate clients with `openapi-generator-cli`, `oapi-codegen`, or any OpenAPI-aware tool. |
| [`http://127.0.0.1:8100/docs`](http://127.0.0.1:8100/docs)                       | **Swagger UI** — try-it-now console with auth, request building, response inspection.                                               |
| [`http://127.0.0.1:8100/redoc`](http://127.0.0.1:8100/redoc)                     | **ReDoc** — read-only, dense, three-pane reference. Best for scanning the full API.                                                 |

The API runs on port `8100` by default. If you started Pulse with a custom `--api-port`, swap it into the URL.

```bash theme={null}
okto-pulse serve --accept-terms
# Then in another terminal:
curl http://127.0.0.1:8100/openapi.json | jq '.info, .paths | keys | length'
```

```text theme={null}
{
  "title":   "Okto Pulse",
  "version": "0.2.0"
}
209
```

***

## Authentication

Every `/api/v1/*` route requires a valid agent API key, passed as an HTTP Bearer token. The key is the same `dash_<hex>` value `okto-pulse init --agents` writes into `.mcp.json`.

```bash theme={null}
curl http://127.0.0.1:8100/api/v1/boards \
  -H "Authorization: Bearer dash_..."
```

The implementation is `HTTPBearer(auto_error=False)` plugged into a provider pattern (`okto-pulse-core/src/okto_pulse/core/infra/auth.py:9`). For the community deployment that Pulse ships, the provider validates the bearer against the agent table and resolves the agent's permission preset on every request.

| Auth method                      | Header                           | Notes                                                                 |
| -------------------------------- | -------------------------------- | --------------------------------------------------------------------- |
| **Bearer token** *(recommended)* | `Authorization: Bearer dash_...` | Same key as MCP. Use this for all script/CI access.                   |
| **`X-API-Key` header**           | `X-API-Key: dash_...`            | Accepted alternative — same scoping.                                  |
| **Query parameter**              | `?api_key=dash_...`              | Discouraged for REST — keys leak into proxy logs. Use Bearer instead. |

A missing or invalid key returns `401 Unauthorized`. A valid key whose preset doesn't allow the action returns `403 Forbidden` with a JSON body naming the failing permission.

```json theme={null}
{
  "detail": {
    "error":      "FORBIDDEN",
    "message":    "Permission denied: SPECS_UPDATE required",
    "permission": "SPECS_UPDATE"
  }
}
```

To see the resolved permissions for the calling agent, hit `GET /api/v1/me/permissions`.

***

## Route clusters

The current source exposes **209 routes**: 208 under `/api/v1` plus the unprefixed `/health` liveness endpoint. They group into the same domains as the MCP tools; the exhaustive endpoint list is maintained in [REST route catalog](/reference/rest-api-catalog).

| Cluster                                                                 | Path prefix                                                                                                                                                                                         | Source file                                                                                           | What lives here                                                                                                                                               |
| ----------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Boards**                                                              | `/api/v1/boards`                                                                                                                                                                                    | `api/boards.py`                                                                                       | Board CRUD, columns, share links, archive/restore tree, top-level card create.                                                                                |
| **Cards**                                                               | `/api/v1/cards`                                                                                                                                                                                     | `api/cards.py`                                                                                        | Card CRUD, move (status transition), dependencies, activity log, knowledge inline, validation submit, test-task linking.                                      |
| **Ideations**                                                           | `/api/v1/boards/{board_id}/ideations`, `/api/v1/ideations/{id}`                                                                                                                                     | `api/ideations.py`                                                                                    | Create / list / get / update / move / evaluate / derive-spec / Q\&A / snapshots / history.                                                                    |
| **Refinements**                                                         | `/api/v1/ideations/{id}/refinements`, `/api/v1/refinements/{id}`                                                                                                                                    | `api/refinements.py`                                                                                  | Same shape as ideations + knowledge sub-routes.                                                                                                               |
| **Specs**                                                               | `/api/v1/boards/{board_id}/specs`, `/api/v1/specs/{id}`                                                                                                                                             | `api/specs.py`                                                                                        | Spec CRUD, link/unlink card, scenarios linkage, knowledge, Q\&A, validation gate.                                                                             |
| **Sprints**                                                             | `/api/v1/boards/{board_id}/sprints`, `/api/v1/sprints/{id}`                                                                                                                                         | `api/sprints.py`                                                                                      | Sprint CRUD, move, evaluations, assign / unassign tasks, suggest sprint slices.                                                                               |
| **Agents**                                                              | `/api/v1/agents`                                                                                                                                                                                    | `api/agents.py`                                                                                       | Agent CRUD, regenerate API key, board-scoped permission edits.                                                                                                |
| **Analytics**                                                           | `/api/v1/analytics`, `/api/v1/boards/{board_id}/analytics/*`                                                                                                                                        | `api/analytics.py`                                                                                    | Cross-board overview, blockers, funnel, quality, velocity, coverage, validations, sprint, per-spec, per-sprint, per-agent, per-entity, plus export endpoints. |
| **Architecture / mockups / attachments / comments / Q\&A / guidelines** | `/api/v1/{architecture,attachments,comments,qa,guidelines}/*`                                                                                                                                       | `api/{architecture,attachments,comments,qa,guidelines}.py`                                            | Cross-cutting CRUD — same surface as the matching MCP tool families.                                                                                          |
| **Knowledge Graph**                                                     | `/api/v1/kg/boards/{board_id}/{nodes,graph,similar,supersedence,contradictions,stats,metrics,audit}`, `/api/v1/kg/global/search`, `/api/v1/kg/{health,queue/health,tick/run-now,queue/dead-letter}` | `api/kg_routes.py`, `api/kg_health.py`, `api/kg_tick.py`, `api/dead_letter.py`, `api/queue_health.py` | Graph reads, similarity, supersedence chains, contradictions, queue + tick admin, global search, dead-letter inspection.                                      |
| **Discovery**                                                           | `/api/v1/discovery/*`                                                                                                                                                                               | `api/discovery.py`                                                                                    | Saved searches, intent execution, history.                                                                                                                    |
| **Settings / presets / me**                                             | `/api/v1/{settings,presets,me}/*`                                                                                                                                                                   | `api/{settings,presets,me}.py`                                                                        | Hot-reload settings, permission presets CRUD, current-agent permission inspection.                                                                            |
| **Traceability**                                                        | `/api/v1/{board_id}/lineage-graph`                                                                                                                                                                  | `api/traceability.py`                                                                                 | Full lineage graph (spec → BRs → TRs → scenarios → cards → validations).                                                                                      |
| **Health**                                                              | `/health` *(unprefixed)*                                                                                                                                                                            | `core/app.py`                                                                                         | Liveness probe. Returns `{"status": "healthy", "version": "..."}`.                                                                                            |

For the parameter shapes and response schemas, open `/docs` or `/redoc` against your running instance — that's the single source of truth.

For every route path and source line, see [REST route catalog](/reference/rest-api-catalog).

***

## Curated examples

Five flows that cover most day-one integrations.

### List your boards

```bash theme={null}
curl http://127.0.0.1:8100/api/v1/boards \
  -H "Authorization: Bearer dash_..."
```

```json theme={null}
[
  {
    "id":          "brd_abc123",
    "name":        "Customer Portal",
    "description": "Checkout + order management",
    "owner_id":    "agent_lead",
    "created_at":  "2026-04-12T09:14:00Z",
    "card_count":  47,
    "spec_count":  6
  }
]
```

### Get a card with full context

```bash theme={null}
curl http://127.0.0.1:8100/api/v1/cards/card_001 \
  -H "Authorization: Bearer dash_..."
```

```json theme={null}
{
  "id":              "card_001",
  "board_id":        "brd_abc123",
  "title":           "Wire Stripe webhook signature verification",
  "status":          "validation",
  "type":            "normal",
  "spec_id":         "spec_XYZ",
  "knowledge_bases": [...],
  "screen_mockups":  [],
  "qa_items":        [...],
  "dependencies":    ["card_000"],
  "created_at":      "2026-05-01T13:00:00Z",
  "updated_at":      "2026-05-07T18:42:11Z"
}
```

### Move a card to the next status

The `/move` endpoint enforces transition gates — moving from `validation → done` requires a previously-submitted task validation.

```bash theme={null}
curl -X POST http://127.0.0.1:8100/api/v1/cards/card_001/move \
  -H "Authorization: Bearer dash_..." \
  -H "Content-Type: application/json" \
  -d '{"target_status": "done"}'
```

```json theme={null}
{
  "id":         "card_001",
  "status":     "done",
  "moved_at":   "2026-05-07T18:45:02Z",
  "moved_by":   "agent_validator"
}
```

A missing validation returns `409 Conflict`:

```json theme={null}
{
  "detail": {
    "error":   "VALIDATION_REQUIRED",
    "message": "Card must have a successful task validation before moving to 'done'."
  }
}
```

### Submit a task validation

The independent-reviewer evidence gate. Required to graduate `validation → done`.

```bash theme={null}
curl -X POST http://127.0.0.1:8100/api/v1/cards/card_001/validate \
  -H "Authorization: Bearer dash_..." \
  -H "Content-Type: application/json" \
  -d '{
    "outcome":  "success",
    "summary":  "Webhook signature verification verified end-to-end with Stripe test events.",
    "evidence": [
      { "type": "test_run", "url": "https://ci.../jobs/4821" },
      { "type": "log",       "url": "https://logs.../trace/evt_abc" }
    ],
    "reviewer_id": "agent_security_lead"
  }'
```

```json theme={null}
{
  "validation_id": "tv_91f2",
  "card_id":       "card_001",
  "outcome":       "success",
  "submitted_at":  "2026-05-07T18:43:51Z"
}
```

### Read a board's analytics

```bash theme={null}
curl http://127.0.0.1:8100/api/v1/boards/brd_abc123/analytics/velocity?from_date=2026-04-01 \
  -H "Authorization: Bearer dash_..."
```

```json theme={null}
{
  "board_id": "brd_abc123",
  "from_date": "2026-04-01",
  "to_date":   "2026-05-07",
  "sprints":   3,
  "completed_cards":   24,
  "average_cycle_time_hours": 41.2,
  "trend": "improving"
}
```

The `/api/v1/analytics/overview` cluster is the same family — see `/redoc` for the per-metric response shapes.

***

## Generating a typed client

Because Pulse publishes a complete OpenAPI 3.1 schema, any standard generator works:

```bash theme={null}
# Install once
npm i -g @openapitools/openapi-generator-cli

# Generate a Python client into ./pulse-client
openapi-generator-cli generate \
  -i http://127.0.0.1:8100/openapi.json \
  -g python \
  -o pulse-client
```

```bash theme={null}
# Or TypeScript / fetch
openapi-generator-cli generate \
  -i http://127.0.0.1:8100/openapi.json \
  -g typescript-fetch \
  -o pulse-client-ts
```

For Go, [`oapi-codegen`](https://github.com/oapi-codegen/oapi-codegen) is a popular alternative:

```bash theme={null}
oapi-codegen \
  -package pulse \
  -generate types,client \
  http://127.0.0.1:8100/openapi.json > pulse/client.go
```

The generated client speaks the same `Authorization: Bearer dash_...` auth — pass the key as a constructor option or via your transport's middleware.

***

## Errors

REST endpoints return standard HTTP status codes. The body is a FastAPI-style envelope wrapping the same error codes the MCP layer uses:

| HTTP | Code               | When                                                                              |
| ---- | ------------------ | --------------------------------------------------------------------------------- |
| 400  | `VALIDATION_ERROR` | Required field missing or value out of range.                                     |
| 401  | `UNAUTHORIZED`     | Missing or invalid Bearer token.                                                  |
| 403  | `FORBIDDEN`        | Token is valid but the agent's preset blocks the action.                          |
| 404  | `NOT_FOUND`        | Entity ID is incorrect or belongs to a different board.                           |
| 409  | `CONFLICT`         | Status transition gate not satisfied (e.g. `VALIDATION_REQUIRED`, `SPEC_LOCKED`). |
| 429  | `RATE_LIMITED`     | KG Cypher routes are rate-limited to 30 req/min per board.                        |
| 500  | (varies)           | Server-side bug — file an issue with the request ID from the response headers.    |

```json theme={null}
{
  "detail": {
    "error":   "NOT_FOUND",
    "message": "Card 'card_999' not found or agent does not have access.",
    "detail":  {}
  }
}
```

***

## Versioning

Routes follow [semantic versioning](https://semver.org). Breaking changes ship with a major bump and a `CHANGELOG.md` entry. The path prefix `/api/v1/` is the v1 boundary — a future v2 will mount at `/api/v2/` so v1 callers keep working through the deprecation window.

The OpenAPI schema's `info.version` matches the running Pulse version (`0.2.0` at time of writing). Pin your generated clients to the exact version you tested against.

***

## Next steps

<CardGroup cols={2}>
  <Card title="MCP reference" href="/reference/mcp">
    The same surface, exposed as 216 typed tools for AI agents.
  </Card>

  <Card title="CLI reference" href="/reference/cli">
    `okto-pulse init`, `serve`, `status`, and the rest.
  </Card>

  <Card title="Connect an agent" href="/connect-agent">
    Auto-generate `.mcp.json` for Claude Code, Cursor, Cline, Windsurf, Goose, Codex.
  </Card>

  <Card title="ADLC pipeline" href="/concepts/sdlc-flow">
    The six pipeline stages and how routes map to each one.
  </Card>
</CardGroup>
