Skip to main content

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’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.
MCP is the canonical agent interface. If you’re connecting an AI agent, use 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.

OpenAPI

The public docs publish a static source-derived schema at /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.
URL (default install)What it serves
https://docs.oktolabs.ai/openapi.jsonStatic OpenAPI 3.1 schema for the docs release.
http://127.0.0.1:8100/openapi.jsonOpenAPI 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/docsSwagger UI — try-it-now console with auth, request building, response inspection.
http://127.0.0.1:8100/redocReDoc — 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.
okto-pulse serve --accept-terms
# Then in another terminal:
curl http://127.0.0.1:8100/openapi.json | jq '.info, .paths | keys | length'
{
  "title":   "Okto Pulse",
  "version": "0.1.14"
}
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.
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 methodHeaderNotes
Bearer token (recommended)Authorization: Bearer dash_...Same key as MCP. Use this for all script/CI access.
X-API-Key headerX-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.
{
  "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.
ClusterPath prefixSource fileWhat lives here
Boards/api/v1/boardsapi/boards.pyBoard CRUD, columns, share links, archive/restore tree, top-level card create.
Cards/api/v1/cardsapi/cards.pyCard 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.pyCreate / list / get / update / move / evaluate / derive-spec / Q&A / snapshots / history.
Refinements/api/v1/ideations/{id}/refinements, /api/v1/refinements/{id}api/refinements.pySame shape as ideations + knowledge sub-routes.
Specs/api/v1/boards/{board_id}/specs, /api/v1/specs/{id}api/specs.pySpec CRUD, link/unlink card, scenarios linkage, knowledge, Q&A, validation gate.
Sprints/api/v1/boards/{board_id}/sprints, /api/v1/sprints/{id}api/sprints.pySprint CRUD, move, evaluations, assign / unassign tasks, suggest sprint slices.
Agents/api/v1/agentsapi/agents.pyAgent CRUD, regenerate API key, board-scoped permission edits.
Analytics/api/v1/analytics, /api/v1/boards/{board_id}/analytics/*api/analytics.pyCross-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}.pyCross-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.pyGraph reads, similarity, supersedence chains, contradictions, queue + tick admin, global search, dead-letter inspection.
Discovery/api/v1/discovery/*api/discovery.pySaved searches, intent execution, history.
Settings / presets / me/api/v1/{settings,presets,me}/*api/{settings,presets,me}.pyHot-reload settings, permission presets CRUD, current-agent permission inspection.
Traceability/api/v1/{board_id}/lineage-graphapi/traceability.pyFull lineage graph (spec → BRs → TRs → scenarios → cards → validations).
Health/health (unprefixed)core/app.pyLiveness 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.

Curated examples

Five flows that cover most day-one integrations.

List your boards

curl http://127.0.0.1:8100/api/v1/boards \
  -H "Authorization: Bearer dash_..."
[
  {
    "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

curl http://127.0.0.1:8100/api/v1/cards/card_001 \
  -H "Authorization: Bearer dash_..."
{
  "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.
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"}'
{
  "id":         "card_001",
  "status":     "done",
  "moved_at":   "2026-05-07T18:45:02Z",
  "moved_by":   "agent_validator"
}
A missing validation returns 409 Conflict:
{
  "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.
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"
  }'
{
  "validation_id": "tv_91f2",
  "card_id":       "card_001",
  "outcome":       "success",
  "submitted_at":  "2026-05-07T18:43:51Z"
}

Read a board’s analytics

curl http://127.0.0.1:8100/api/v1/boards/brd_abc123/analytics/velocity?from_date=2026-04-01 \
  -H "Authorization: Bearer dash_..."
{
  "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:
# 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
# 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 is a popular alternative:
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:
HTTPCodeWhen
400VALIDATION_ERRORRequired field missing or value out of range.
401UNAUTHORIZEDMissing or invalid Bearer token.
403FORBIDDENToken is valid but the agent’s preset blocks the action.
404NOT_FOUNDEntity ID is incorrect or belongs to a different board.
409CONFLICTStatus transition gate not satisfied (e.g. VALIDATION_REQUIRED, SPEC_LOCKED).
429RATE_LIMITEDKG 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.
{
  "detail": {
    "error":   "NOT_FOUND",
    "message": "Card 'card_999' not found or agent does not have access.",
    "detail":  {}
  }
}

Versioning

Routes follow semantic versioning. 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.1.14 at time of writing). Pin your generated clients to the exact version you tested against.

Next steps

MCP reference

The same surface, exposed as 198 typed tools for AI agents.

CLI reference

okto-pulse init, serve, status, and the rest.

Connect an agent

Auto-generate .mcp.json for Claude Code, Cursor, Cline, Windsurf, Goose, Codex.

ADLC pipeline

The six pipeline stages and how routes map to each one.
Last modified on May 8, 2026