API Reference
This page documents the key API endpoints across Nova’s services. All services also expose interactive Swagger docs at /docs on their respective ports.
Authentication
Section titled “Authentication”Nova supports two authentication methods:
Admin secret
Section titled “Admin secret”Used for privileged operations (key management, service configuration, pod management). Pass via header:
X-Admin-Secret: your-admin-secretAPI key
Section titled “API key”Used for standard operations (task submission, agent interaction, memory queries). Pass via header:
Authorization: Bearer sk-nova-...or:
X-API-Key: sk-nova-...When REQUIRE_AUTH=false (the default for development), API key authentication is bypassed.
Orchestrator (port 8000)
Section titled “Orchestrator (port 8000)”Agents
Section titled “Agents”# List all agentscurl http://localhost:8000/api/v1/agents \ -H "Authorization: Bearer sk-nova-..."
# Create an agentcurl -X POST http://localhost:8000/api/v1/agents \ -H "Authorization: Bearer sk-nova-..." \ -H "Content-Type: application/json" \ -d '{"config": {"model": "qwen2.5:7b"}}'
# Update agent config (admin)curl -X PATCH http://localhost:8000/api/v1/agents/{agent_id}/config \ -H "X-Admin-Secret: your-secret" \ -H "Content-Type: application/json" \ -d '{"model": "hermes3:8b"}'Tasks (interactive)
Section titled “Tasks (interactive)”# Submit a task (synchronous)curl -X POST http://localhost:8000/api/v1/tasks \ -H "Authorization: Bearer sk-nova-..." \ -H "Content-Type: application/json" \ -d '{ "agent_id": "...", "messages": [{"role": "user", "content": "Explain the auth flow"}] }'
# Submit a task (SSE streaming)curl -X POST http://localhost:8000/api/v1/tasks/stream \ -H "Authorization: Bearer sk-nova-..." \ -H "Content-Type: application/json" \ -d '{ "agent_id": "...", "messages": [{"role": "user", "content": "Explain the auth flow"}] }'Pipeline tasks (async queue)
Section titled “Pipeline tasks (async queue)”# Submit to pipeline queuecurl -X POST http://localhost:8000/api/v1/pipeline/tasks \ -H "Authorization: Bearer sk-nova-..." \ -H "Content-Type: application/json" \ -d '{"user_input": "Fix the login bug in auth.py"}'
# List recent taskscurl "http://localhost:8000/api/v1/pipeline/tasks?status=running&limit=10" \ -H "Authorization: Bearer sk-nova-..."
# Get task statuscurl http://localhost:8000/api/v1/pipeline/tasks/{task_id} \ -H "Authorization: Bearer sk-nova-..."
# Cancel a taskcurl -X POST http://localhost:8000/api/v1/pipeline/tasks/{task_id}/cancel \ -H "Authorization: Bearer sk-nova-..."
# Get guardrail findingscurl http://localhost:8000/api/v1/pipeline/tasks/{task_id}/findings \ -H "Authorization: Bearer sk-nova-..."
# Get code review verdictscurl http://localhost:8000/api/v1/pipeline/tasks/{task_id}/reviews \ -H "Authorization: Bearer sk-nova-..."
# Get artifactscurl http://localhost:8000/api/v1/pipeline/tasks/{task_id}/artifacts \ -H "Authorization: Bearer sk-nova-..."
# Queue statisticscurl http://localhost:8000/api/v1/pipeline/queue-stats \ -H "Authorization: Bearer sk-nova-..."Chat (admin dashboard)
Section titled “Chat (admin dashboard)”# Stream chat with the primary agent (admin only)curl -X POST http://localhost:8000/api/v1/chat/stream \ -H "X-Admin-Secret: your-secret" \ -H "Content-Type: application/json" \ -d '{ "messages": [{"role": "user", "content": "Hello Nova"}], "model": "qwen2.5:7b" }'The response is an SSE stream. Each chunk is a data: line containing a text delta. The stream ends with data: [DONE]. The X-Session-Id response header can be passed back in subsequent requests to continue the conversation.
# List all podscurl http://localhost:8000/api/v1/pods \ -H "Authorization: Bearer sk-nova-..."
# Create a pod (admin)curl -X POST http://localhost:8000/api/v1/pods \ -H "X-Admin-Secret: your-secret" \ -H "Content-Type: application/json" \ -d '{ "name": "research", "description": "Information gathering pod", "routing_keywords": ["research", "investigate"], "sandbox": "workspace" }'
# Add agent to pod (admin)curl -X POST http://localhost:8000/api/v1/pods/{pod_id}/agents \ -H "X-Admin-Secret: your-secret" \ -H "Content-Type: application/json" \ -d '{"name": "researcher", "role": "task", "model": "qwen2.5:7b"}'Model pins are validated on every pod/agent write: a concrete model,
default_model, or fallback_models entry that no provider actually serves
is rejected with 422. auto and tier:* hints always pass — they resolve
at request time.
Model assignments (admin)
Section titled “Model assignments (admin)”# Every configured model reference, checked against validated discoverycurl http://localhost:8000/api/v1/models/assignments \ -H "X-Admin-Secret: your-secret"
# Everything currently pointing at one model id (pods, agents, config knobs)curl "http://localhost:8000/api/v1/models/references?model=qwen3:4b" \ -H "X-Admin-Secret: your-secret"/references powers the delete guard: a local model can’t be deleted while
anything still points at it — the dashboard opens a repoint dialog, and the
gateway rejects the delete with 409 listing the assignments that hold it.
API keys (admin)
Section titled “API keys (admin)”# Create a key (raw key shown once in response)curl -X POST http://localhost:8000/api/v1/keys \ -H "X-Admin-Secret: your-secret" \ -H "Content-Type: application/json" \ -d '{"name": "my-app", "rate_limit_rpm": 60}'
# List keyscurl http://localhost:8000/api/v1/keys \ -H "X-Admin-Secret: your-secret"
# Revoke a keycurl -X DELETE http://localhost:8000/api/v1/keys/{key_id} \ -H "X-Admin-Secret: your-secret"MCP servers
Section titled “MCP servers”# List MCP serverscurl http://localhost:8000/api/v1/mcp-servers \ -H "Authorization: Bearer sk-nova-..."
# Register a server (admin)curl -X POST http://localhost:8000/api/v1/mcp-servers \ -H "X-Admin-Secret: your-secret" \ -H "Content-Type: application/json" \ -d '{ "name": "filesystem", "command": "npx", "args": ["-y", "@modelcontextprotocol/server-filesystem", "/workspace"], "enabled": true }'
# Reload/reconnect a servercurl -X POST http://localhost:8000/api/v1/mcp-servers/{id}/reload \ -H "X-Admin-Secret: your-secret"Approvals & Inbox (admin)
Section titled “Approvals & Inbox (admin)”# Pending approvals — genuinely decidable items only (pending AND unexpired).# The reaper flips expired pending rows to 'timeout', so nothing zombies.curl http://localhost:8000/api/v1/capabilities/approvals \ -H "X-Admin-Secret: your-secret"
# Recently resolved approvals (approved / rejected / timeout / superseded),# newest first — context for an empty pending listcurl "http://localhost:8000/api/v1/capabilities/approvals/recent?limit=20" \ -H "X-Admin-Secret: your-secret"
# Inbox — messages carry the referenced item's LIVE statuscurl "http://localhost:8000/api/v1/notify/inbox?limit=50" \ -H "X-Admin-Secret: your-secret"Inbox items about an approval or task include approval_id / task_id plus
approval_status / task_status resolved at read time, so a message written
as “waiting for your decision” reports approved, timeout, or complete
once the item is resolved. Messages about nothing in particular (briefings,
agent pushes) carry null for all four fields.
Identity (public)
Section titled “Identity (public)”# Get the AI's display name and greeting (no auth required)curl http://localhost:8000/api/v1/identityReturns:
{ "name": "Nova", "greeting": "Hello! I'm Nova. I have access to your workspace..."}The greeting supports a {name} placeholder that is automatically resolved to the current name. Configure the name, greeting, and persona from Settings > Nova Identity.
Health
Section titled “Health”curl http://localhost:8000/health/live # Livenesscurl http://localhost:8000/health/ready # Readiness (checks DB + Redis)LLM Gateway (port 8001)
Section titled “LLM Gateway (port 8001)”OpenAI-compatible endpoints
Section titled “OpenAI-compatible endpoints”# Chat completion (non-streaming)curl http://localhost:8001/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "model": "qwen2.5:7b", "messages": [{"role": "user", "content": "Hello"}] }'
# Chat completion (streaming)curl http://localhost:8001/v1/chat/completions \ -H "Content-Type: application/json" \ -d '{ "model": "qwen2.5:7b", "messages": [{"role": "user", "content": "Hello"}], "stream": true }'
# List available modelscurl http://localhost:8001/v1/modelsNova internal endpoints
Section titled “Nova internal endpoints”# Non-streaming completioncurl -X POST http://localhost:8001/complete \ -H "Content-Type: application/json" \ -d '{ "model": "qwen2.5:7b", "messages": [{"role": "user", "content": "Hello"}] }'
# SSE streaming completioncurl -X POST http://localhost:8001/stream \ -H "Content-Type: application/json" \ -d '{ "model": "qwen2.5:7b", "messages": [{"role": "user", "content": "Hello"}] }'
# Generate embeddingscurl -X POST http://localhost:8001/embed \ -H "Content-Type: application/json" \ -d '{"text": "Some text to embed"}'Health
Section titled “Health”curl http://localhost:8001/health/livecurl http://localhost:8001/health/readyMemory Service (port 8002)
Section titled “Memory Service (port 8002)”The backend-agnostic surface is /api/v1/memory/* (backed by the OKF markdown bundle — see memory-service). Memory ids are bundle-relative paths, e.g. topics/gpu-setup.md.
# Retrieve formatted context for a query (main read path; empty query -> root index)curl -X POST http://localhost:8002/api/v1/memory/context \ -H "Content-Type: application/json" \ -d '{"query": "authentication patterns"}'
# Write a durable memory (the `remember` tool path — okf metadata routes the file)curl -X POST http://localhost:8002/api/v1/memory/ingest \ -H "Content-Type: application/json" \ -d '{"raw_text": "The auth module uses bcrypt.", "source_type": "chat", "metadata": {"okf": {"type": "topic", "title": "auth-hashing"}}}'
# Read / edit / delete one item (id is a bundle path)curl http://localhost:8002/api/v1/memory/item/topics/auth-hashing.mdcurl -X DELETE http://localhost:8002/api/v1/memory/item/topics/auth-hashing.md
# Provenance and store statscurl http://localhost:8002/api/v1/memory/provenance/topics/auth-hashing.mdcurl http://localhost:8002/api/v1/memory/statsThe dashboard Brain page (/brain) is powered by three more endpoints on the same API:
# Whole-bundle graph: nodes + wiki-link edges (the Brain page's dataset)curl http://localhost:8002/api/v1/memory/graph
# Edit one memory in place (frontmatter shallow-merge; type is fixed)curl -X PUT http://localhost:8002/api/v1/memory/item/topics/gpu-setup.md \ -H "Content-Type: application/json" \ -d '{"frontmatter": {"tags": ["gpu","wsl"]}, "content": "..."}'
# SSE stream of retrieval events — powers the Brain page's live glowcurl -N http://localhost:8002/api/v1/memory/eventsHealth
Section titled “Health”curl http://localhost:8002/health/livecurl http://localhost:8002/health/readyChat API (port 8080)
Section titled “Chat API (port 8080)”WebSocket
Section titled “WebSocket”Connect to ws://localhost:8080/ws/chat for real-time streaming chat.
With authentication: ws://localhost:8080/ws/chat?token=sk-nova-...
Send a message:
{"type": "user", "content": "Hello Nova", "session_id": "optional"}Receive messages:
{"type": "system", "session_id": "abc-123"}{"type": "stream_chunk", "delta": "Hello"}{"type": "stream_chunk", "delta": "! How"}{"type": "stream_chunk", "delta": " can I help?"}{"type": "stream_end"}Health
Section titled “Health”curl http://localhost:8080/health/livecurl http://localhost:8080/health/readyRecovery Service (port 8888)
Section titled “Recovery Service (port 8888)”# System status overviewcurl http://localhost:8888/api/v1/recovery/status
# List service containerscurl http://localhost:8888/api/v1/recovery/services
# Restart a service (admin)curl -X POST http://localhost:8888/api/v1/recovery/services/orchestrator/restart \ -H "X-Admin-Secret: your-secret"
# Create a backup (admin)curl -X POST http://localhost:8888/api/v1/recovery/backups \ -H "X-Admin-Secret: your-secret"
# List backupscurl http://localhost:8888/api/v1/recovery/backups
# Restore from backup (admin)curl -X POST http://localhost:8888/api/v1/recovery/backups/{filename}/restore \ -H "X-Admin-Secret: your-secret"
# Recommended local models (admin) — curated file or live ollama.com rankingcurl "http://localhost:8888/api/v1/recovery/inference/models/recommended?backend=ollama&source=popular" \ -H "X-Admin-Secret: your-secret"
# Recommended cloud models with per-Mtok pricing (admin)curl http://localhost:8888/api/v1/recovery/inference/models/recommended-cloud \ -H "X-Admin-Secret: your-secret"
# Read env vars (admin, secrets masked)curl http://localhost:8888/api/v1/recovery/env \ -H "X-Admin-Secret: your-secret"
# Update env vars (admin)curl -X PATCH http://localhost:8888/api/v1/recovery/env \ -H "X-Admin-Secret: your-secret" \ -H "Content-Type: application/json" \ -d '{"updates": {"DEFAULT_CHAT_MODEL": "qwen2.5:7b"}}'Health
Section titled “Health”curl http://localhost:8888/health/livecurl http://localhost:8888/health/readyResponse format
Section titled “Response format”All services return raw JSON responses (no { data: ... } wrapper). Error responses use standard HTTP status codes with a detail field:
{"detail": "Agent not found"}Streaming endpoints use Server-Sent Events (SSE) with JSON-encoded data lines:
data: {"delta": "Hello"}
data: {"delta": " world"}
data: [DONE]