54 KiB
Veritas Kanban — API Reference
Version: 3.4.0
Last Updated: 2026-03-08
Base URL: http://localhost:3001/api
Canonical prefix: /api/v1 (alias: /api)
This is the source-of-truth companion to the Swagger/OpenAPI spec. For workflow-engine-specific endpoints, see API-WORKFLOWS.md.
Table of Contents
- Authentication
- Base URLs & Environments
- Error Model
- Tasks
- Time Tracking
- Observations
- Analytics
- Configuration
- Settings
- Lifecycle Hooks
- Chat & Squad
- Agent Status
- Auth & Diagnostics
- Telemetry
- Health
- WebSocket
- Task Verification
- Task Comments
- Task Subtasks
- Task Deliverables
- Task Archive
- Attachments
- Agent Permissions
- Agent Routing
- Shared Resources
- Doc Freshness
- Cost Prediction
- Error Learning
- Tool Policies
- Traces
- Audit
- Common Workflows
- Versioning & Deprecation
- Rate Limits
- Additional Endpoint Groups
Authentication
VK supports three authentication methods. All are optional when running locally with VERITAS_AUTH_ENABLED=false.
Methods
| Method | Header / Param | Use Case |
|---|---|---|
| Bearer Token (JWT) | Authorization: Bearer <token> |
Browser sessions, UI login |
| API Key | X-API-Key: <key> |
Agent integrations, scripts |
| WS Query Param | ws://host:port/ws?token=<key> |
WebSocket connections |
Roles
| Role | Permissions |
|---|---|
admin |
Full access — all endpoints, destructive operations, deep health |
agent |
Read/write tasks, time tracking, observations, chat, telemetry |
read-only |
Read-only access to all GET endpoints |
Localhost Bypass
When VERITAS_AUTH_LOCALHOST_BYPASS=true, requests from 127.0.0.1 / ::1 are authenticated automatically with the role set by VERITAS_AUTH_LOCALHOST_ROLE (default: read-only).
API Key Configuration
Set via environment:
# Admin key
VERITAS_ADMIN_KEY=your-admin-key
# Additional keys (format: name:key:role, comma-separated)
VERITAS_API_KEYS=agent1:key123:agent,readonly:key456:read-only
Base URLs & Environments
| Environment | Base URL | Notes |
|---|---|---|
| Local dev | http://localhost:3001/api |
Default port |
| Production | Deploy behind reverse proxy with TLS | Add rate limiting externally |
Both /api/v1/... and /api/... resolve to the same handlers. Use /api for brevity.
Error Model
All errors return a consistent JSON envelope:
{
"error": "Human-readable message",
"code": "OPTIONAL_ERROR_CODE",
"details": {}
}
Status Codes
| Code | Meaning |
|---|---|
200 |
Success |
201 |
Created |
400 |
Bad request — invalid body, missing fields |
401 |
Not authenticated |
403 |
Forbidden — insufficient role |
404 |
Resource not found |
409 |
Conflict — duplicate, state violation |
429 |
Rate limited |
503 |
Service degraded (health checks) |
Tasks
All task routes are mounted at /api/tasks.
List Tasks
GET /api/tasks
Returns all active tasks. Supports query filters.
Response 200:
{
"tasks": [
{
"id": "TASK-001",
"title": "Implement login",
"status": "in-progress",
"priority": "high",
"project": "rubicon",
"assignee": "agent-1",
"createdAt": "2026-03-01T10:00:00Z"
}
]
}
Get Task Counts
GET /api/tasks/counts
Returns task counts grouped by status.
Create Task
POST /api/tasks
Body:
{
"title": "Fix auth bug",
"description": "Session tokens not refreshing",
"priority": "high",
"project": "rubicon",
"type": "bug"
}
Response 201: The created task object.
Get Task
GET /api/tasks/:id
Update Task
PATCH /api/tasks/:id
Body: Partial task fields to update (title, description, status, priority, assignee, etc.).
Delete Task
DELETE /api/tasks/:id
Reorder Tasks
POST /api/tasks/reorder
Body: { "taskIds": ["TASK-003", "TASK-001", "TASK-002"] }
Bulk Update
POST /api/tasks/bulk-update
Body: { "taskIds": ["TASK-001", "TASK-002"], "updates": { "status": "done" } }
Bulk Archive
POST /api/tasks/bulk-archive-by-ids
Body: { "taskIds": ["TASK-001", "TASK-002"] }
Blocking Status
GET /api/tasks/:id/blocking-status
Returns whether a task is blocked by unresolved dependencies.
Dependencies
POST /api/tasks/:id/dependencies # Add dependency
DELETE /api/tasks/:id/dependencies/:targetId # Remove dependency
GET /api/tasks/:id/dependencies # List dependencies
GET /api/tasks/:id/dependency-graph # Full dependency graph
Progress & Checkpointing
GET /api/tasks/:id/progress # Get progress
PUT /api/tasks/:id/progress # Set progress
POST /api/tasks/:id/progress/append # Append progress entry
POST /api/tasks/:id/checkpoint # Save checkpoint
GET /api/tasks/:id/checkpoint # Get checkpoint
DELETE /api/tasks/:id/checkpoint # Clear checkpoint
Context
GET /api/tasks/:id/context
Returns enriched context for agent consumption (task + dependencies + observations).
Worktree (Git)
POST /api/tasks/:id/worktree # Create worktree branch
GET /api/tasks/:id/worktree # Get worktree status
DELETE /api/tasks/:id/worktree # Remove worktree
POST /api/tasks/:id/worktree/rebase # Rebase worktree
POST /api/tasks/:id/worktree/merge # Merge worktree
GET /api/tasks/:id/worktree/open # Open in editor
Apply Template
POST /api/tasks/:id/apply-template
Demote Task
POST /api/tasks/:id/demote
Moves a task back to backlog.
Time Tracking
Mounted at /api/tasks.
Summary
GET /api/tasks/time/summary
Returns aggregate time tracking data across all tasks.
Start Timer
POST /api/tasks/:id/time/start
Stop Timer
POST /api/tasks/:id/time/stop
Add Manual Entry
POST /api/tasks/:id/time/entry
Body:
{
"durationMs": 3600000,
"description": "Code review"
}
Delete Entry
DELETE /api/tasks/:id/time/entry/:entryId
Observations
Observational memory for tasks — agents record learnings, blockers, and notes.
Add Observation
POST /api/tasks/:id/observations
Body:
{
"content": "Rate limiter needs Redis for distributed deployments",
"type": "insight",
"agent": "codex-1"
}
List Observations
GET /api/tasks/:id/observations
Delete Observation
DELETE /api/tasks/:id/observations/:obsId
Search Observations (cross-task)
GET /api/observations?q=redis&type=insight
Analytics
GET /api/analytics/timeline # Task completion timeline
GET /api/analytics/metrics # Throughput, cycle time, WIP
GET /api/analytics/health # Board health indicators
Configuration
Mounted at /api/config.
Get Config
GET /api/config
Repository Management
GET /api/config/repos # List repos
POST /api/config/repos # Add repo
PATCH /api/config/repos/:name # Update repo
DELETE /api/config/repos/:name # Remove repo
POST /api/config/repos/validate # Validate repo config
GET /api/config/repos/:name/branches # List branches
Agent Configuration
GET /api/config/agents # List configured agents
PUT /api/config/agents # Update agent config
PUT /api/config/default-agent # Set default agent
Settings
GET /api/settings/features # Get feature flags
PATCH /api/settings/features # Toggle feature flags
Body (PATCH):
{
"darkMode": true,
"squadChat": true,
"analyticsEnabled": true
}
Lifecycle Hooks
Event-driven hooks that fire on task state transitions.
GET /api/hooks # List hooks
GET /api/hooks/executions # List recent executions
POST /api/hooks # Create hook
PATCH /api/hooks/:id # Update hook
DELETE /api/hooks/:id # Delete hook
POST /api/hooks/fire # Manually fire a hook
Create Hook Body:
{
"name": "notify-on-done",
"event": "task.status.changed",
"filter": { "newStatus": "done" },
"action": {
"type": "webhook",
"url": "https://example.com/webhook"
}
}
Chat & Squad
Squad Chat
Post messages to the squad chat channel (agent coordination).
POST /api/chat/squad
Body:
{
"agent": "VERITAS",
"message": "Starting cleanup — 14 steps",
"model": "claude-opus-4.6",
"tags": ["cleanup"]
}
GET /api/chat/squad
Returns recent squad messages. Supports ?limit=N.
Chat Sessions
POST /api/chat/send # Send message to a session
GET /api/chat/sessions # List sessions
GET /api/chat/sessions/:id # Get session
GET /api/chat/sessions/:id/history # Get session history
DELETE /api/chat/sessions/:id # Delete session
Agent Status
Real-time agent activity indicator for the board.
GET /api/agent/status # Current status
POST /api/agent/status # Update status
Update Body:
{
"status": "working",
"subAgentCount": 2,
"activeAgents": [
{ "agent": "TARS", "status": "working", "taskTitle": "Fix auth" },
{ "agent": "CASE", "status": "working", "taskTitle": "Add tests" }
]
}
Delegation Violation
POST /api/agent/status/delegation-violation
Reports when an agent violates delegation rules.
Auth & Diagnostics
GET /api/auth/status # Check auth status & current role
POST /api/auth/setup # Initial admin setup
POST /api/auth/login # Login (returns JWT)
POST /api/auth/logout # Logout / invalidate token
POST /api/auth/recover # Account recovery
POST /api/auth/change-password # Change password
POST /api/auth/rotate-secret # Rotate JWT secret
GET /api/auth/rotation-status # JWT rotation status
Login Example
POST /api/auth/login
Body: { "password": "admin-password" }
Response 200:
{
"token": "eyJhbGciOiJIUzI1NiIs...",
"role": "admin",
"expiresIn": "24h"
}
Telemetry
Run events, token usage, and metrics — powers the dashboard graphs.
Post Event
POST /api/telemetry/events
Body (run started):
{
"type": "run.started",
"taskId": "TASK-001",
"agent": "veritas"
}
Body (run completed):
{
"type": "run.completed",
"taskId": "TASK-001",
"agent": "veritas",
"durationMs": 45000,
"success": true
}
Body (token usage):
{
"type": "run.tokens",
"taskId": "TASK-001",
"agent": "veritas",
"model": "claude-opus-4.6",
"inputTokens": 12000,
"outputTokens": 3500,
"cacheTokens": 8000,
"cost": 0.15
}
Bulk Events
POST /api/telemetry/events/bulk
Body: { "events": [ ... ] }
Query Events
GET /api/telemetry/events # All events (?type=, ?limit=, ?taskId=)
GET /api/telemetry/events/task/:taskId # Events for a specific task
GET /api/telemetry/status # Telemetry subsystem status
GET /api/telemetry/count # Event counts
GET /api/telemetry/export # Export events (CSV/JSON)
Health
Three-tier health check system for container orchestration.
| Endpoint | Auth | Purpose |
|---|---|---|
GET /health |
None | Alias for /health/live |
GET /health/live |
None | Liveness probe — process running |
GET /health/ready |
None | Readiness probe — storage, disk, memory |
GET /health/deep |
Admin | Full diagnostics — version, WS count, circuit breakers |
GET /api/health |
None | Lightweight API liveness signal |
GET /api/health/deep |
Admin | Same as /health/deep, under /api |
Readiness Response:
{
"status": "ok",
"checks": { "storage": "ok", "memory": "ok", "disk": "ok" },
"timestamp": "2026-03-02T07:00:00Z"
}
WebSocket
Endpoint: ws://localhost:3001/ws
Connection
const ws = new WebSocket('ws://localhost:3001/ws?token=YOUR_API_KEY');
- Max connections: 50
- Heartbeat: server pings every 30s; clients must pong within 10s
- Origin validation enforced (CSWSH protection)
Authentication
Pass API key as token query parameter, or rely on localhost bypass if enabled.
Client → Server Messages
Subscribe to task output:
{ "type": "subscribe", "taskId": "TASK-001" }
Subscribe to chat session:
{ "type": "chat:subscribe", "sessionId": "session-abc" }
Server → Client Messages
Task change broadcast:
{ "type": "task:updated", "task": { "id": "TASK-001", "status": "done" } }
Agent output:
{
"type": "agent:output",
"taskId": "TASK-001",
"outputType": "stdout",
"data": "Running tests..."
}
Chat message:
{ "type": "chat:message", "sessionId": "session-abc", "message": { ... } }
Agent status change:
{ "type": "agent:status", "status": "working", "activeAgents": [ ... ] }
Task Verification
Verification step checklists for tasks — define acceptance criteria that must be checked off before a task is considered truly complete.
Mounted at /api/tasks.
Add Verification Step
POST /api/tasks/:id/verification
Body:
{
"description": "All unit tests passing"
}
Response 201: The updated task object with the new verification step added.
Update Verification Step
PATCH /api/tasks/:id/verification/:stepId
Body (partial):
{
"checked": true
}
When checked changes, checkedAt is automatically set (or cleared).
Response 200: The updated task object.
Delete Verification Step
DELETE /api/tasks/:id/verification/:stepId
Response 200: The updated task object with the step removed.
Task Comments
Comment threads on tasks — supports adding, editing, and deleting comments. Comments auto-sync to linked GitHub issues.
Mounted at /api/tasks.
Add Comment
POST /api/tasks/:id/comments
Body:
{
"author": "veritas",
"text": "Root cause identified — auth middleware skips token refresh"
}
Response 201: The updated task object with the new comment.
Edit Comment
PATCH /api/tasks/:id/comments/:commentId
Body:
{
"text": "Updated analysis — the issue is in the session store"
}
Delete Comment
DELETE /api/tasks/:id/comments/:commentId
Task Subtasks
Break tasks into smaller work items with optional acceptance criteria per subtask.
Mounted at /api/tasks.
Add Subtask
POST /api/tasks/:id/subtasks
Body:
{
"title": "Add input validation",
"acceptanceCriteria": ["Rejects empty strings", "Returns 400 on invalid input"]
}
Response 201: The updated task object.
Update Subtask
PATCH /api/tasks/:id/subtasks/:subtaskId
Body (partial):
{
"completed": true
}
Delete Subtask
DELETE /api/tasks/:id/subtasks/:subtaskId
Toggle Acceptance Criterion
PATCH /api/tasks/:id/subtasks/:subtaskId/criteria
Body:
{
"criteriaIndex": 0
}
Toggles the checked state of a specific acceptance criterion on a subtask.
Task Deliverables
Track deliverable artifacts (files, PRs, docs) produced by agents working on a task.
Mounted at /api/tasks.
List Deliverables
GET /api/tasks/:id/deliverables
Add Deliverable
POST /api/tasks/:id/deliverables
Body:
{
"title": "API endpoint implementation",
"type": "code",
"path": "server/src/routes/new-feature.ts",
"agent": "codex-1",
"description": "REST endpoints for the new feature"
}
Response 201: The updated task object.
Update Deliverable
PATCH /api/tasks/:id/deliverables/:deliverableId
Body (partial): Any of title, type, path, status, description.
Delete Deliverable
DELETE /api/tasks/:id/deliverables/:deliverableId
Task Archive
Archive completed tasks (by sprint or individually) and restore them. Archived tasks are removed from the active board.
Mounted at /api/tasks.
| Method | Path | Description |
|---|---|---|
GET |
/api/tasks/archived |
List all archived tasks |
GET |
/api/tasks/archive/suggestions |
Get sprints ready for archival |
POST |
/api/tasks/archive/sprint/:sprint |
Archive all done tasks in a sprint |
POST |
/api/tasks/bulk-archive |
Archive by sprint name |
POST |
/api/tasks/bulk-archive-by-ids |
Archive specific task IDs |
POST |
/api/tasks/:id/archive |
Archive a single task |
POST |
/api/tasks/:id/restore |
Restore a task from archive |
Archive by Sprint
POST /api/tasks/archive/sprint/:sprint
Archives all completed tasks in the given sprint.
Response 200:
{
"archived": 5
}
Archive Single Task
POST /api/tasks/:id/archive
Auth: Requires admin or agent role. Emits audit log entry.
Restore Task
POST /api/tasks/:id/restore
Restores an archived task back to active status (done).
Attachments
File upload/download for task attachments with automatic text extraction (PDF, DOCX, etc.).
Mounted at /api/tasks.
| Method | Path | Description |
|---|---|---|
POST |
/api/tasks/:id/attachments |
Upload files (multipart, max 20) |
GET |
/api/tasks/:id/attachments |
List all attachments |
GET |
/api/tasks/:id/attachments/:attId |
Get attachment metadata |
GET |
/api/tasks/:id/attachments/:attId/download |
Download file |
GET |
/api/tasks/:id/attachments/:attId/text |
Get extracted text |
DELETE |
/api/tasks/:id/attachments/:attId |
Delete attachment |
Upload Attachments
POST /api/tasks/:id/attachments
Content-Type: multipart/form-data
Field: files — one or more files (max 20 per request).
Files undergo MIME validation via magic bytes. Text is automatically extracted from supported formats.
Response 200:
{
"attachments": [
{
"id": "att_abc123",
"filename": "design-spec.pdf",
"originalName": "design-spec.pdf",
"mimeType": "application/pdf",
"size": 245000
}
],
"task": { "..." },
"rejected": []
}
Get Extracted Text
GET /api/tasks/:id/attachments/:attId/text
Response 200:
{
"attachmentId": "att_abc123",
"text": "Extracted document content...",
"hasText": true
}
Agent Permissions
Role-based permission levels for agents: intern, specialist, lead. Interns require approval for certain actions.
Mounted at /api/agents/permissions.
| Method | Path | Description |
|---|---|---|
GET |
/api/agents/permissions |
List all agent permissions |
GET |
/api/agents/permissions/:id |
Get agent permission config |
PUT |
/api/agents/permissions/:id/level |
Set permission level |
PATCH |
/api/agents/permissions/:id |
Update permission fields |
POST |
/api/agents/permissions/check |
Check if agent can perform action |
POST |
/api/agents/permissions/approvals |
Request approval (intern) |
GET |
/api/agents/permissions/approvals |
List pending approvals |
POST |
/api/agents/permissions/approvals/:id |
Review approval request |
Set Permission Level
PUT /api/agents/permissions/:id/level
Body:
{
"level": "specialist"
}
Valid levels: intern, specialist, lead.
Check Permission
POST /api/agents/permissions/check
Body:
{
"agentId": "codex-1",
"action": "deploy"
}
Response 200:
{
"allowed": true,
"level": "specialist",
"requiresApproval": false
}
Update Permission Fields
PATCH /api/agents/permissions/:id
Body (partial):
{
"trustedDomains": ["github.com"],
"canCreateTasks": true,
"canDelegate": false,
"canApprove": false,
"restrictions": ["no-deploy"]
}
Request Approval
POST /api/agents/permissions/approvals
Used by intern-level agents to request approval for restricted actions.
Review Approval
POST /api/agents/permissions/approvals/:id
Approve or reject a pending approval request.
Agent Routing
Automatic agent resolution — determines the best agent for a task based on configurable routing rules.
Mounted at /api/agents.
| Method | Path | Description |
|---|---|---|
POST |
/api/agents/route |
Resolve best agent for a task |
GET |
/api/agents/routing |
Get routing configuration |
PUT |
/api/agents/routing |
Update routing configuration |
Resolve Agent
POST /api/agents/route
Accepts either a task ID or ad-hoc metadata:
By task ID:
{
"taskId": "TASK-001"
}
By metadata:
{
"type": "bug",
"priority": "high",
"project": "rubicon",
"subtaskCount": 3
}
Response 200:
{
"agent": "codex-1",
"model": "claude-sonnet-4.5",
"rule": "high-priority-bugs",
"confidence": 0.95
}
Get/Update Routing Configuration
GET /api/agents/routing
PUT /api/agents/routing
PUT Body:
{
"enabled": true,
"rules": [
{
"id": "high-bugs",
"name": "High priority bugs",
"match": { "type": "bug", "priority": "high" },
"agent": "codex-1",
"model": "claude-sonnet-4.5",
"enabled": true
}
],
"defaultAgent": "veritas",
"fallbackOnFailure": true,
"maxRetries": 2
}
Shared Resources
Registry for shared resources (credentials, config files, API keys, docs) that can be mounted to projects.
Mounted at /api/shared-resources.
| Method | Path | Description |
|---|---|---|
GET |
/api/shared-resources |
List all (filters: type, project, tag, name) |
GET |
/api/shared-resources/:id |
Get one resource |
POST |
/api/shared-resources |
Create resource |
PATCH |
/api/shared-resources/:id |
Update resource |
DELETE |
/api/shared-resources/:id |
Delete resource |
POST |
/api/shared-resources/:id/mount |
Mount to project(s) |
POST |
/api/shared-resources/:id/unmount |
Unmount from project(s) |
Create Resource
POST /api/shared-resources
Body:
{
"name": "Production DB Config",
"type": "config",
"content": "host=db.example.com\nport=5432",
"tags": ["database", "production"],
"projectIds": ["rubicon"]
}
Mount/Unmount
POST /api/shared-resources/:id/mount
POST /api/shared-resources/:id/unmount
Body:
{
"projectIds": ["rubicon", "brainmeld"]
}
Doc Freshness
Track documentation freshness — monitor when docs were last reviewed and alert when they go stale.
Mounted at /api/doc-freshness.
| Method | Path | Description |
|---|---|---|
GET |
/api/doc-freshness |
List tracked documents (filters: project, type, stale) |
GET |
/api/doc-freshness/:id |
Get one tracked document |
POST |
/api/doc-freshness |
Track a new document |
PATCH |
/api/doc-freshness/:id |
Update document metadata |
DELETE |
/api/doc-freshness/:id |
Stop tracking |
POST |
/api/doc-freshness/:id/review |
Mark as freshly reviewed |
GET |
/api/doc-freshness/alerts |
List freshness alerts (filters: severity, acknowledged) |
POST |
/api/doc-freshness/alerts/:id/acknowledge |
Acknowledge an alert |
GET |
/api/doc-freshness/summary |
Freshness health summary |
Track a Document
POST /api/doc-freshness
Body:
{
"path": "docs/API-REFERENCE.md",
"type": "api-reference",
"project": "veritas-kanban",
"maxAgeDays": 30
}
Mark as Reviewed
POST /api/doc-freshness/:id/review
Body (optional):
{
"reviewer": "brad",
"reviewedAt": "2026-03-08T10:00:00Z"
}
Get Freshness Summary
GET /api/doc-freshness/summary
Response 200:
{
"total": 15,
"fresh": 12,
"stale": 2,
"critical": 1,
"alertCount": 3
}
Cost Prediction
Predict token costs for tasks before execution — uses historical telemetry data to estimate.
Mounted at /api/cost-prediction.
| Method | Path | Description |
|---|---|---|
POST |
/api/cost-prediction/predict |
Predict cost for a task |
GET |
/api/cost-prediction/accuracy |
Prediction accuracy for completed tasks |
GET |
/api/cost-prediction/accuracy/stats |
Aggregate accuracy statistics |
Predict Cost
POST /api/cost-prediction/predict
By task ID:
{
"taskId": "TASK-001"
}
By metadata:
{
"type": "feature",
"priority": "high",
"project": "rubicon",
"description": "Implement OAuth2 flow",
"subtaskCount": 5
}
Response 200:
{
"estimatedTokens": 45000,
"estimatedCost": 0.85,
"estimatedDurationMs": 120000,
"confidence": 0.78,
"basedOn": 12
}
Get Accuracy Stats
GET /api/cost-prediction/accuracy/stats
Returns aggregate statistics on prediction accuracy across all completed tasks.
Error Learning
Structured failure analysis — submit errors, record root causes, and search for similar past errors to avoid repeating mistakes.
Mounted at /api/errors.
| Method | Path | Description |
|---|---|---|
POST |
/api/errors/submit |
Submit an error for analysis |
GET |
/api/errors |
List analyses (filters: taskId, errorType, severity, agent, limit) |
GET |
/api/errors/:id |
Get specific analysis |
PATCH |
/api/errors/:id |
Update with root cause & fix |
GET |
/api/errors/stats |
Aggregate error pattern stats |
GET |
/api/errors/search |
Search similar past errors (?q=<query>) |
Submit Error
POST /api/errors/submit
Body:
{
"taskId": "TASK-001",
"agent": "codex-1",
"errorMessage": "ECONNREFUSED 127.0.0.1:5432",
"errorType": "resource",
"rawDetails": "Full stack trace...",
"attemptDescription": "Trying to connect to PostgreSQL"
}
Valid error types: runtime, api, validation, timeout, permission, resource, model, git, build, test, configuration, unknown.
Response 201: The created error analysis object.
Update Analysis
PATCH /api/errors/:id
Body (partial):
{
"rootCause": "PostgreSQL service not running",
"severity": "medium",
"chosenFix": "Add health check before DB operations",
"preventionSteps": ["Add connection retry logic", "Check service status on startup"],
"tags": ["database", "connectivity"]
}
Search Similar Errors
GET /api/errors/search?q=ECONNREFUSED&limit=5
Returns past errors similar to the query string — useful for avoiding repeated mistakes.
Search
QMD-ready retrieval across task markdown and docs. The endpoint uses the configured backend and gracefully falls back to keyword search when QMD is unavailable.
Mounted at /api/search.
| Method | Path | Description |
|---|---|---|
POST |
/api/search |
Search task and docs collections with one query |
POST |
/api/search/index/refresh |
Refresh QMD collections and embeddings |
Search Collections
POST /api/search
Body:
{
"query": "semantic search duplicate detection",
"limit": 10,
"collections": ["tasks-active", "tasks-archive", "docs"],
"backend": "auto"
}
backend may be keyword, qmd, or auto. QMD is opt-in via VERITAS_SEARCH_BACKEND=qmd or per-request backend: "qmd".
Response 200:
{
"query": "semantic search duplicate detection",
"backend": "keyword",
"degraded": false,
"elapsedMs": 12,
"results": [
{
"id": "tasks/active/task_20260504_example.md",
"title": "Add semantic search",
"path": "tasks/active/task_20260504_example.md",
"collection": "tasks-active",
"snippet": "Wire QMD retrieval into Veritas.",
"score": 4
}
]
}
QMD Setup
npm install -g @tobilu/qmd
pnpm qmd:setup
VERITAS_SEARCH_BACKEND=qmd pnpm dev
QMD Index Refresh
POST /api/search/index/refresh
Body:
{
"embed": true
}
Set embed to false to run only qmd update.
Response 200:
{
"backend": "qmd",
"updated": true,
"embedded": true,
"elapsedMs": 982,
"commands": ["update", "embed"]
}
Tool Policies
Role-based tool access restrictions — control which tools each agent role can use.
Mounted at /api/tool-policies.
| Method | Path | Description |
|---|---|---|
GET |
/api/tool-policies |
List all policies |
GET |
/api/tool-policies/:role |
Get policy for a role |
POST |
/api/tool-policies |
Create a new policy |
PUT |
/api/tool-policies/:role |
Update an existing policy |
DELETE |
/api/tool-policies/:role |
Delete a custom policy |
POST |
/api/tool-policies/:role/validate |
Check if a tool is allowed for a role |
Create Policy
POST /api/tool-policies
Body:
{
"role": "intern",
"allowed": ["read", "search", "analyze"],
"denied": ["deploy", "delete", "admin"],
"description": "Restricted access for intern agents"
}
Validate Tool Access
POST /api/tool-policies/:role/validate
Body:
{
"tool": "deploy"
}
Response 200:
{
"role": "intern",
"tool": "deploy",
"allowed": false
}
Traces
Distributed execution tracing — record and query traces for agent task attempts.
Mounted at /api/traces.
| Method | Path | Description |
|---|---|---|
GET |
/api/traces/status |
Check if tracing is enabled |
POST |
/api/traces/enable |
Enable tracing |
POST |
/api/traces/disable |
Disable tracing |
GET |
/api/traces/:attemptId |
Get a trace by attempt ID |
GET |
/api/traces/task/:taskId |
List all traces for a task |
Check Tracing Status
GET /api/traces/status
Response 200:
{
"enabled": true
}
Get Task Traces
GET /api/traces/task/TASK-001
Returns all execution traces associated with the given task.
Audit
Immutable, hash-chained audit log. Admin only.
Mounted at /api/audit.
| Method | Path | Description |
|---|---|---|
GET |
/api/audit |
Recent audit entries (?limit=N, default 100, max 1000) |
GET |
/api/audit/verify |
Verify hash chain integrity of current month's log |
Auth: Requires admin role.
Query Audit Log
GET /api/audit?limit=50
Response 200:
{
"entries": [
{
"timestamp": "2026-03-08T07:00:00Z",
"action": "task.archive",
"actor": "admin-key",
"resource": "TASK-001",
"details": { "title": "Fix auth bug" },
"hash": "sha256:..."
}
],
"count": 50
}
Verify Integrity
GET /api/audit/verify
Verifies the hash chain of the current month's audit log file. Returns chain validity and any broken links.
Common Workflows
Agent Task Lifecycle
# 1. Create task
TASK=$(curl -s -X POST http://localhost:3001/api/tasks \
-H 'Content-Type: application/json' \
-H 'X-API-Key: YOUR_KEY' \
-d '{"title":"Fix bug","priority":"high"}' | jq -r '.id')
# 2. Start time tracking
curl -s -X POST http://localhost:3001/api/tasks/$TASK/time/start
# 3. Emit telemetry
curl -s -X POST http://localhost:3001/api/telemetry/events \
-H 'Content-Type: application/json' \
-d "{\"type\":\"run.started\",\"taskId\":\"$TASK\",\"agent\":\"veritas\"}"
# 4. Update status to in-progress
curl -s -X PATCH http://localhost:3001/api/tasks/$TASK \
-H 'Content-Type: application/json' \
-d '{"status":"in-progress"}'
# 5. Save checkpoint mid-work
curl -s -X POST http://localhost:3001/api/tasks/$TASK/checkpoint \
-H 'Content-Type: application/json' \
-d '{"state":{"step":3,"context":"halfway done"}}'
# 6. Add observation
curl -s -X POST http://localhost:3001/api/tasks/$TASK/observations \
-H 'Content-Type: application/json' \
-d '{"content":"Found root cause in auth middleware","type":"insight","agent":"veritas"}'
# 7. Complete
curl -s -X PATCH http://localhost:3001/api/tasks/$TASK \
-H 'Content-Type: application/json' \
-d '{"status":"done"}'
# 8. Stop timer + emit completion telemetry
curl -s -X POST http://localhost:3001/api/tasks/$TASK/time/stop
curl -s -X POST http://localhost:3001/api/telemetry/events \
-H 'Content-Type: application/json' \
-d "{\"type\":\"run.completed\",\"taskId\":\"$TASK\",\"agent\":\"veritas\",\"durationMs\":45000,\"success\":true}"
Agent Loop (Poll for Work)
# Get next available task
NEXT=$(curl -s http://localhost:3001/api/tasks?status=todo&limit=1 | jq -r '.tasks[0].id')
if [ "$NEXT" != "null" ]; then
# Claim it
curl -s -X PATCH http://localhost:3001/api/tasks/$NEXT \
-H 'Content-Type: application/json' \
-d '{"status":"in-progress","assignee":"agent-1"}'
fi
Blocker Tracking
# Add a blocker observation
curl -s -X POST http://localhost:3001/api/tasks/TASK-001/observations \
-H 'Content-Type: application/json' \
-d '{"content":"Blocked: waiting on API key from vendor","type":"blocker","agent":"veritas"}'
# Add a dependency
curl -s -X POST http://localhost:3001/api/tasks/TASK-001/dependencies \
-H 'Content-Type: application/json' \
-d '{"targetId":"TASK-002","type":"blocked-by"}'
Webhook Hook Setup
# Fire a webhook when any task moves to "done"
curl -s -X POST http://localhost:3001/api/hooks \
-H 'Content-Type: application/json' \
-d '{
"name": "done-notify",
"event": "task.status.changed",
"filter": {"newStatus":"done"},
"action": {"type":"webhook","url":"https://example.com/hook"}
}'
Versioning & Deprecation
- Current version: v1 (mounted at
/api/v1, aliased at/api) - No breaking changes within a major version
- Deprecations will be announced via:
Deprecationresponse header- Changelog entry
- Minimum 2 minor releases before removal
- When v2 ships, v1 will remain available for at least 6 months
Rate Limits
| Tier | Limit | Applies To |
|---|---|---|
| Global | 300 req/min | All endpoints (localhost exempt) |
| Read | 300 req/min | GET endpoints |
| Write | 60 req/min | POST/PUT/PATCH/DELETE |
| Upload | 20 req/min | File upload endpoints |
Rate limit headers: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset.
Additional Endpoint Groups
These endpoints follow the same auth/error patterns documented above:
| Mount | Purpose |
|---|---|
/api/projects |
Project CRUD |
/api/sprints |
Sprint management |
/api/backlog |
Backlog operations |
/api/agents |
Agent CRUD, routing |
/api/agents/register |
Agent self-registration |
/api/agents/permissions |
Agent permission management |
/api/templates |
Task templates |
/api/task-types |
Custom task type definitions |
/api/activity |
Activity feed |
/api/notifications |
User notifications |
/api/broadcasts |
Broadcast messages |
/api/changes |
Efficient agent polling (change feed) |
/api/diff |
Task diff comparisons |
/api/automation |
Automation rules |
/api/summary |
Board summaries |
/api/github |
GitHub integration |
/api/conflicts |
Merge conflict detection |
/api/metrics |
Prometheus-style metrics |
/api/traces |
Distributed tracing |
/api/cost-prediction |
Token cost forecasting |
/api/error-learning |
Error pattern learning |
/api/reports |
Generated reports |
/api/deliverables |
Scheduled deliverables |
/api/doc-freshness |
Documentation freshness tracking |
/api/docs |
Docs endpoint |
/api/shared-resources |
Shared resource management |
/api/status-history |
Task status history |
/api/digest |
Digest generation |
/api/audit |
Audit log |
/api/lessons |
Lessons learned |
/api/delegation |
Task delegation |
/api/workflows |
Workflow engine (details) |
/api/tool-policies |
Tool access policies |
/api/integrations |
External integrations |
/api/settings/transition-hooks |
Status transition hooks |
| /api/feedback | User feedback & sentiment analytics |
| /api/decisions | Decision audit trail |
| /api/drift | Behavioral drift detection |
| /api/policies | Agent policy & guard engine |
| /api/scoring/profiles | Output evaluation profiles |
| /api/scoring/evaluate | Run an output evaluation |
| /api/scoring/history | Evaluation history |
| /api/prompt-registry | Prompt template registry |
| /api/v1/system/health | Global system health |
v4.0 API Reference
User Feedback (/api/feedback)
Collect feedback on agent outputs and query aggregate sentiment analytics.
List Feedback
GET /api/feedback
Query params: agent, taskId, sentiment (positive | neutral | negative), since (ISO timestamp), limit (default 50), offset.
Response: Array of feedback objects.
[
{
"id": "fb_abc123",
"content": "The summary was concise and accurate.",
"sentiment": "positive",
"category": "output-quality",
"agent": "TARS",
"taskId": "task_20260321_abc",
"createdAt": "2026-03-21T14:00:00.000Z"
}
]
Submit Feedback
POST /api/feedback
{
"content": "The response missed the key point.",
"sentiment": "negative",
"category": "accuracy",
"agent": "CASE",
"taskId": "task_20260321_xyz"
}
Response: 201 with created feedback object.
Get Feedback Item
GET /api/feedback/:id
Response: Single feedback object.
Delete Feedback
DELETE /api/feedback/:id
Response: 204 No Content.
Feedback Analytics
GET /api/feedback/analytics
Query params: agent, since, until.
Response:
{
"total": 42,
"sentimentBreakdown": {
"positive": 30,
"neutral": 8,
"negative": 4
},
"topCategories": [
{ "category": "output-quality", "count": 18 },
{ "category": "accuracy", "count": 12 }
],
"trend": [{ "date": "2026-03-21", "positive": 5, "neutral": 1, "negative": 0 }]
}
Decision Audit Trail (/api/decisions)
Log agent decisions with assumptions and record outcomes.
List Decisions
GET /api/decisions
Query params: agent, taskId, minConfidence (0–1), maxConfidence (0–1), since, until, limit, offset.
Response: Array of decision objects.
[
{
"id": "dec_abc123",
"decision": "Use Redis for session caching",
"confidence": 0.85,
"reasoning": "Redis has sub-ms latency and supports TTL natively.",
"evidence": ["benchmark results", "existing infra"],
"assumptions": ["Redis cluster is available", "TTL of 1h is sufficient"],
"agent": "VERITAS",
"taskId": "task_20260321_abc",
"createdAt": "2026-03-21T14:00:00.000Z",
"outcome": null
}
]
Log a Decision
POST /api/decisions
{
"decision": "Refactor auth to use JWT instead of sessions",
"confidence": 0.9,
"reasoning": "Sessions require sticky routing; JWT is stateless.",
"evidence": ["architecture review notes"],
"assumptions": ["Clients will store tokens securely"],
"agent": "VERITAS",
"taskId": "task_20260321_abc"
}
Response: 201 with created decision object.
Get Decision
GET /api/decisions/:id
Update an Assumption
PATCH /api/decisions/:id/assumptions/:idx
Update a specific assumption by its zero-based index.
{
"text": "Clients will store tokens securely (confirmed via security review)",
"held": true
}
Response: Updated decision object with the assumption patched.
Behavioral Drift Detection (/api/drift)
Track agent metric baselines and detect behavioral deviations.
List Drift Alerts
GET /api/drift/alerts
Query params: agent, acknowledged (boolean), since, limit.
Response: Array of drift alert objects.
[
{
"id": "drift_abc123",
"agent": "TARS",
"metric": "task_completion_rate",
"baseline": 0.92,
"current": 0.71,
"deviation": 0.21,
"threshold": 0.1,
"severity": "high",
"acknowledged": false,
"detectedAt": "2026-03-21T14:00:00.000Z"
}
]
Acknowledge Drift Alert
POST /api/drift/alerts/:id/acknowledge
{
"notes": "Agent was rate-limited by upstream API — not a behavior change."
}
Response: Updated alert with acknowledged: true.
List Baselines
GET /api/drift/baselines
Query params: agent, metric.
Response: Array of baseline records showing current metric norms per agent.
Reset Baselines
POST /api/drift/baselines/reset
{
"agent": "TARS",
"metric": "task_completion_rate"
}
Response: 200 with updated baseline record.
Run Drift Analysis
POST /api/drift/analyze
{
"agent": "TARS"
}
Compares current metrics against baselines and creates alerts for any out-of-threshold deviations.
Response: 200 with analysis summary including number of alerts created.
Agent Policy Engine (/api/policies)
Define configurable guard rules for agent tool and action access.
List Policies
GET /api/policies
Query params: agent, project, enabled (boolean).
Response: Array of policy objects.
[
{
"id": "pol_abc123",
"name": "No web access for Intern agents",
"description": "Intern-level agents cannot use browser or fetch tools.",
"enabled": true,
"scope": { "agentLevel": "intern" },
"rules": [
{
"tool": "browser",
"action": "*",
"effect": "deny"
}
],
"precedence": "deny-first",
"createdAt": "2026-03-21T14:00:00.000Z"
}
]
Create Policy
POST /api/policies
{
"name": "Require approval for file deletion",
"enabled": true,
"scope": { "global": true },
"rules": [
{
"tool": "exec",
"action": "rm",
"effect": "require-approval"
}
],
"precedence": "deny-first"
}
Response: 201 with created policy object.
Get Policy
GET /api/policies/:id
Update Policy
PUT /api/policies/:id
Delete Policy
DELETE /api/policies/:id
Response: 204 No Content.
Evaluate Policy
POST /api/policies/:id/evaluate
{
"agent": "TARS",
"tool": "browser",
"action": "navigate",
"metadata": { "url": "https://example.com" }
}
Response:
{
"allowed": false,
"effect": "deny",
"matchedRule": { "tool": "browser", "action": "*", "effect": "deny" },
"policyId": "pol_abc123",
"auditId": "audit_xyz789"
}
Output Evaluation & Scoring (/api/scoring)
Create scoring profiles and evaluate agent outputs against weighted criteria.
List Scoring Profiles
GET /api/scoring/profiles
Query params: limit, offset.
Response: Array of scoring profile objects.
Create Scoring Profile
POST /api/scoring/profiles
{
"name": "Code Quality Baseline",
"description": "Checks for common quality indicators in generated code.",
"compositeMethod": "weightedAvg",
"scorers": [
{
"id": "s1",
"name": "No hardcoded secrets",
"type": "RegexMatch",
"pattern": "(password|secret|api_key)\\s*=\\s*['\"][^'\"]+['\"]",
"flags": "i",
"invert": true,
"weight": 2,
"scoreOnMatch": 0,
"scoreOnMiss": 1
},
{
"id": "s2",
"name": "Has error handling",
"type": "KeywordContains",
"keywords": ["try", "catch", "error"],
"matchMode": "any",
"weight": 1
}
]
}
Response: 201 with created profile.
Get Scoring Profile
GET /api/scoring/profiles/:id
Update Scoring Profile
PUT /api/scoring/profiles/:id
Delete Scoring Profile
DELETE /api/scoring/profiles/:id
Response: 204 No Content.
Evaluate Output
POST /api/scoring/evaluate
{
"profileId": "prof_abc123",
"output": "function getUser(id) {\n try {\n return db.find(id);\n } catch (e) {\n throw e;\n }\n}",
"action": "generate_function",
"agent": "TARS",
"taskId": "task_20260321_abc"
}
Response:
{
"id": "eval_xyz789",
"profileId": "prof_abc123",
"score": 0.88,
"compositeMethod": "weightedAvg",
"scorerResults": [
{ "id": "s1", "name": "No hardcoded secrets", "score": 1.0, "weight": 2 },
{ "id": "s2", "name": "Has error handling", "score": 1.0, "weight": 1 }
],
"agent": "TARS",
"taskId": "task_20260321_abc",
"evaluatedAt": "2026-03-21T14:00:00.000Z"
}
Evaluation History
GET /api/scoring/history
Query params: profileId, agent, taskId, since, limit, offset.
Response: Array of past evaluation results.
Prompt Template Registry (/api/prompt-registry)
Manage version-controlled prompt templates with variable extraction and usage tracking.
List Templates
GET /api/prompt-registry
Query params: tag, search, limit, offset.
Response: Array of template summaries (without full content for performance).
Create Template
POST /api/prompt-registry
{
"name": "Task Completion Summary",
"description": "Generates a completion summary for a finished task.",
"content": "You completed task {{task_title}}. Summarize what was done in 2-3 sentences, referencing the acceptance criteria: {{acceptance_criteria}}",
"tags": ["completion", "summary"],
"changelog": "Initial version"
}
Response: 201 with created template including auto-extracted variables (task_title, acceptance_criteria).
Get Template
GET /api/prompt-registry/:id
Response: Full template with current content, version number, variables list, and metadata.
Update Template
PATCH /api/prompt-registry/:id
Body: Partial template fields. Triggers automatic version creation.
{
"content": "You completed task {{task_title}} (ID: {{task_id}}). Summarize...",
"changelog": "Added task_id variable"
}
Delete Template
DELETE /api/prompt-registry/:id
Response: 204 No Content.
List Versions
GET /api/prompt-registry/:id/versions
Response: Array of version objects (id, versionNumber, changelog, createdAt). Does not include full content for performance.
Get Usage History
GET /api/prompt-registry/:id/usage
Query params: limit, offset.
Response: Array of usage records with model, token counts, and timestamps.
Template Stats
GET /api/prompt-registry/:id/stats
Response:
{
"totalUses": 42,
"averageInputTokens": 312,
"averageOutputTokens": 128,
"lastUsedAt": "2026-03-21T14:00:00.000Z"
}
Aggregate Stats (All Templates)
GET /api/prompt-registry/stats/all
Response: Aggregate usage stats across all templates.
Preview Template
POST /api/prompt-registry/:id/render-preview
{
"variables": {
"task_title": "Add OAuth login",
"acceptance_criteria": "Users can log in with Google."
}
}
Response: { "rendered": "You completed task Add OAuth login. Summarize..." }
Record Usage
POST /api/prompt-registry/:id/record-usage
{
"model": "anthropic/claude-sonnet-4-6",
"inputTokens": 320,
"outputTokens": 145,
"renderedOutput": "You completed task Add OAuth login...",
"variables": { "task_title": "Add OAuth login" }
}
Response: 201 with logged usage record.
System Health (/api/v1/system/health)
Get a real-time snapshot of system health across resources, agents, and operations.
GET /api/v1/system/health
No query params required.
Response:
{
"status": "stable",
"level": 0,
"signals": {
"system": {
"status": "stable",
"storageUsedPercent": 42,
"diskFreeGb": 120,
"memoryUsedPercent": 58
},
"agents": {
"status": "stable",
"online": 3,
"offline": 0,
"total": 3
},
"operations": {
"status": "stable",
"successRate": 0.97,
"recentRuns": 50,
"recentFailures": 1
}
},
"timestamp": "2026-03-21T14:00:00.000Z"
}
Health levels: stable (0) · reviewing (1) · drifting (2) · elevated (3) · alert (4)
For workflow engine endpoints, see API-WORKFLOWS.md.
For MCP server tools, see MCP Server Guide.
For agent workflow SOPs, see SOP-agent-task-workflow.md.