The HTTP surface activity-api serves on its own port. Every vessel and the agent-facing cockpit call it, which makes it the one contract in the fleet whose shape is felt everywhere; discovery resolves the address, so treat the paths below as the contract and the port as a convenience.
The Activity API provides backend services for:
- Activity Template Management - Store, retrieve, and version activity templates
- Thompson Sampling - Probabilistic template selection based on execution history
- Impulse Resolution - Resolve all impulse pointer types (memo, file, executionTrace, etc.)
- Execution Trace Storage - Persist complete execution state with snapshots
- Learning Loop - Track composition, tool usage, impulse relevance, sequences
- Boredom Activities - Queue and manage autonomous improvement tasks
- Vessel Registry - Track active vessels and health status
- Ribosome - Extract successful executions into reusable templates
- Ingress:
http://localhost:18080(host-mapped; resolve the live address through discovery)
All /v2/* endpoints require authentication via:
Option 1: Session-based (for dashboard)
Authorization: Bearer <session_token>Option 2: Internal service API key (vessel-to-vessel)
X-Internal-Api-Key: <api_key>Health endpoint exception:
GET /health- No authentication required
GET /health
Deep health check verifying Redis and SurrealDB connectivity.
Response 200:
{
"service": "activity-api",
"version": "1.0.0",
"timestamp": "2026-03-23T17:30:00Z",
"status": "healthy",
"checks": {
"redis": {
"status": "healthy",
"latency_ms": 2
},
"surrealdb": {
"status": "healthy",
"latency_ms": 15
}
}
}Response 503: (Service Unavailable)
{
"service": "activity-api",
"status": "unhealthy",
"checks": {
"redis": { "status": "unhealthy", "error": "Connection refused" },
"surrealdb": { "status": "healthy", "latency_ms": 12 }
}
}List all activity templates with Thompson Sampling scores.
Query Parameters:
limit(optional): Max templates to return (default: 100)offset(optional): Pagination offset (default: 0)scope(optional): Filter by scope (user,project,org,global)category(optional): Filter by category (feature,bugfix,refactor,tool,infrastructure)
Response 200:
{
"templates": [
{
"variant_id": "uuid-v4",
"activity_id": "fix-boredom-trace-storage",
"variant_name": "v1",
"description": "Fix execution trace storage for boredom activities",
"category": "bugfix",
"scope": "project",
"org_id": "acme",
"project_id": "my-project",
"task_steps": [...],
"genealogy": {
"parent_variant_id": null,
"generation": 1,
"mutation_type": "original"
},
"metrics": {
"total_executions": 5,
"successful_executions": 4,
"failed_executions": 1,
"success_rate": 0.8,
"avg_duration_ms": 45000,
"avg_cost_usd": 0.15,
"thompson_alpha": 5.0,
"thompson_beta": 2.0,
"total_selections": 7,
"last_executed_at": "2026-03-23T16:45:00Z"
},
"created_at": "2026-03-20T10:00:00Z",
"updated_at": "2026-03-23T16:45:00Z"
}
],
"total": 1,
"limit": 100,
"offset": 0
}Caching:
- Redis cache-aside pattern (1 hour TTL)
- Invalidated on template creation/update
Create new activity template.
Request Body:
{
"activity_id": "add-feature-x",
"variant_name": "v1",
"description": "Add feature X to codebase",
"category": "feature",
"task_steps": [
{
"task_id": "1",
"description": "Read existing code structure",
"prompt": {
"template": "Read {{file_path}} and understand structure",
"variables": [{"name": "file_path", "type": "string"}]
}
}
],
"scope": "project",
"org_id": "acme",
"project_id": "my-project",
"genealogy": {
"parent_variant_id": null,
"generation": 1,
"mutation_type": "original"
}
}Response 201:
{
"variant_id": "uuid-v4",
"activity_id": "add-feature-x",
"variant_name": "v1",
"created_at": "2026-03-23T17:30:00Z"
}Get Thompson Sampling recommendation for activity selection.
Request Body:
{
"goal_description": "Fix boredom activity execution traces",
"context": {
"recent_failures": ["fix-trace-v1"],
"available_impulses": ["execution:123", "file:src/boredom.ts"]
},
"filters": {
"category": ["bugfix"],
"scope": "project"
}
}Response 200:
{
"recommended_variant_id": "uuid-v4",
"activity_id": "fix-boredom-trace-storage",
"variant_name": "v2",
"thompson_score": 0.85,
"confidence": 0.92,
"reasoning": "Highest Thompson score among bugfix templates",
"alternatives": [
{
"variant_id": "uuid-v5",
"activity_id": "fix-boredom-trace-storage",
"variant_name": "v1",
"thompson_score": 0.72,
"reason": "Lower success rate"
}
]
}Store impulse data with project-scoped isolation.
Request Body:
{
"impulse_id": "errorFile",
"project_id": "my-project",
"impulse_data": {
"type": "file",
"path": "src/tool/bash.ts",
"offset": 40,
"limit": 20,
"budget": 2000,
"priority": "high",
"loaded": false,
"content": null
}
}Response 201:
{
"impulse_id": "errorFile",
"project_id": "my-project",
"api_key": "...",
"created_at": "2026-03-23T17:30:00Z"
}Error 400: (Impulse already exists)
{
"error": "Impulse errorFile already exists for project my-project"
}Resolve impulse pointer to actual content.
Request Body:
{
"impulse_id": "errorFile",
"project_id": "my-project",
"impulse_data": {
"type": "file",
"path": "repos/local-tools-vessel/src/index.ts",
"offset": 40,
"limit": 20
}
}Response 200:
{
"impulse_id": "errorFile",
"loaded": true,
"content": "... file content lines 40-60 ...",
"tokens_used": 850,
"budget_remaining": 1150,
"metadata": {
"file_path": "repos/local-tools-vessel/src/index.ts",
"lines": "40-60",
"size_bytes": 3200
}
}Supported Impulse Types:
memo: Embedded content (no resolution needed)file: File pointer with offset/limitactivityExecutionTrace: Full execution trace with stateactivityTemplate: Template structure and metadataactivityMetrics: Performance data- Custom types: Backend can add new types without vessel changes
Retrieve stored impulse by ID.
Response 200:
{
"impulse_id": "errorFile",
"project_id": "my-project",
"impulse_data": {
"type": "file",
"path": "src/tool/bash.ts",
"offset": 40,
"limit": 20,
"budget": 2000
},
"created_at": "2026-03-23T17:30:00Z"
}List impulses with pagination.
Query Parameters:
limit(optional): Max impulses to return (default: 50)offset(optional): Pagination offset (default: 0)project_id(optional): Filter by project
Response 200:
{
"impulses": [...],
"total": 42,
"limit": 50,
"offset": 0
}Store complete execution trace with state snapshots.
Request Body:
{
"execution_id": "exec-uuid",
"variant_id": "variant-uuid",
"activity_id": "fix-boredom-trace-storage",
"success": true,
"duration_ms": 45000,
"cost": 0.15,
"tokens": {
"input": 5000,
"output": 2000,
"cache": 1000
},
"impulses_used": ["errorFile", "executionTrace:123"],
"tasks": [
{
"task_id": "1",
"description": "Read error logs",
"status": "completed",
"duration_ms": 5000,
"tool_calls": [
{ "tool": "read", "duration_ms": 100, "success": true }
]
}
],
"state_snapshot": {
"input_state": {
"filesAvailable": ["src/boredom.ts"],
"environment": { "NODE_ENV": "development" },
"impulses": ["errorFile"],
"variables": { "goal": "fix trace storage" }
},
"output_state": {
"filesModified": ["src/routes/boredom.ts"],
"filesCreated": [],
"filesDeleted": [],
"exitCode": 0
},
"stateTransition": {
"before": { "src/routes/boredom.ts": "hash-abc" },
"after": { "src/routes/boredom.ts": "hash-def" },
"workingDirectory": "/repos/activity-api"
}
},
"component_changes": [
{
"file_path": "src/routes/boredom.ts",
"component_name": "boredomQueueRoute",
"component_type": "function",
"change_type": "modified",
"reason": "Added execution trace storage"
}
]
}Response 201:
{
"execution_id": "exec-uuid",
"created_at": "2026-03-23T17:30:00Z",
"stored": true
}Triggers:
- Updates Thompson Sampling metrics (alpha/beta)
- Invalidates template cache
- Broadcasts event via WebSocket
Retrieve execution traces with pagination.
Query Parameters:
limit(optional): Max traces to return (default: 50)offset(optional): Pagination offset (default: 0)variant_id(optional): Filter by variantactivity_id(optional): Filter by activitysuccess(optional): Filter by success status (true/false)since(optional): ISO timestamp for recent traces
Response 200:
{
"executions": [
{
"execution_id": "exec-uuid",
"variant_id": "variant-uuid",
"activity_id": "fix-boredom-trace-storage",
"success": true,
"duration_ms": 45000,
"cost": 0.15,
"tokens": { "input": 5000, "output": 2000, "cache": 1000 },
"executed_at": "2026-03-23T17:30:00Z",
"tasks": [...],
"state_snapshot": {...}
}
],
"total": 120,
"limit": 50,
"offset": 0
}Retrieve single execution trace by ID.
Response 200:
{
"execution_id": "exec-uuid",
"variant_id": "variant-uuid",
"activity_id": "fix-boredom-trace-storage",
"success": true,
"duration_ms": 45000,
"cost": 0.15,
"tokens": { "input": 5000, "output": 2000, "cache": 1000 },
"impulses_used": ["errorFile"],
"tasks": [...],
"state_snapshot": {...},
"component_changes": [...],
"executed_at": "2026-03-23T17:30:00Z",
"created_at": "2026-03-23T17:30:00Z"
}Record activity composition (dependencies between activities).
Request Body:
{
"from_variant_id": "variant-uuid-1",
"to_variant_id": "variant-uuid-2",
"relationship_type": "depends_on",
"weight": 1.0,
"context": {
"reason": "Template A always follows Template B in successful executions"
}
}Response 201:
{
"composition_id": "comp-uuid",
"created_at": "2026-03-23T17:30:00Z"
}Retrieve composition dependency graph.
Query Parameters:
variant_id(optional): Start from specific variantdepth(optional): Max graph depth (default: 3)limit(optional): Max nodes to return (default: 100)
Response 200:
{
"nodes": [
{
"variant_id": "variant-uuid-1",
"activity_id": "setup-env",
"variant_name": "v1"
},
{
"variant_id": "variant-uuid-2",
"activity_id": "run-tests",
"variant_name": "v2"
}
],
"edges": [
{
"from_variant_id": "variant-uuid-1",
"to_variant_id": "variant-uuid-2",
"relationship_type": "depends_on",
"weight": 0.95
}
],
"total_nodes": 2,
"total_edges": 1
}Track impulse relevance for learning which impulses help which activities.
Request Body:
{
"variant_id": "variant-uuid",
"impulse_type": "activityExecutionTrace",
"relevance_score": 0.92,
"tokens_used": 1200,
"task_id": "3",
"contributed_to_success": true
}Response 201:
{
"metric_id": "metric-uuid",
"created_at": "2026-03-23T17:30:00Z"
}Query impulse relevance patterns.
Query Parameters:
variant_id(optional): Filter by variantimpulse_type(optional): Filter by impulse typemin_score(optional): Minimum relevance score (0.0-1.0)limit(optional): Max results (default: 50)
Response 200:
{
"metrics": [
{
"variant_id": "variant-uuid",
"impulse_type": "activityExecutionTrace",
"avg_relevance_score": 0.88,
"total_uses": 15,
"success_rate": 0.93,
"avg_tokens_used": 1100
}
],
"total": 1
}Record tool usage patterns during execution.
Request Body:
{
"variant_id": "variant-uuid",
"tool_name": "bash",
"task_id": "2",
"success": true,
"duration_ms": 500,
"args_pattern": {
"command_type": "git",
"flags": ["--no-pager", "diff"]
}
}Response 201:
{
"usage_id": "usage-uuid",
"created_at": "2026-03-23T17:30:00Z"
}Query tool usage patterns.
Query Parameters:
variant_id(optional): Filter by varianttool_name(optional): Filter by toolsuccess(optional): Filter by success statuslimit(optional): Max results (default: 50)
Response 200:
{
"patterns": [
{
"variant_id": "variant-uuid",
"tool_name": "bash",
"total_uses": 42,
"success_count": 40,
"failure_count": 2,
"avg_duration_ms": 450,
"common_patterns": [
{ "command_type": "git", "frequency": 25 },
{ "command_type": "bun", "frequency": 17 }
]
}
],
"total": 1
}Record sequences of activities executed together.
Request Body:
{
"sequence": [
{
"variant_id": "variant-uuid-1",
"position": 0,
"execution_id": "exec-uuid-1",
"success": true
},
{
"variant_id": "variant-uuid-2",
"position": 1,
"execution_id": "exec-uuid-2",
"success": true
}
],
"sequence_success": true,
"total_duration_ms": 90000
}Response 201:
{
"sequence_id": "seq-uuid",
"created_at": "2026-03-23T17:30:00Z"
}Query execution sequence patterns.
Query Parameters:
variant_id(optional): Filter sequences containing variantmin_length(optional): Minimum sequence lengthsuccess_only(optional): Only successful sequences (true/false)limit(optional): Max results (default: 50)
Response 200:
{
"sequences": [
{
"sequence_id": "seq-uuid",
"sequence": [
{ "variant_id": "variant-uuid-1", "position": 0 },
{ "variant_id": "variant-uuid-2", "position": 1 }
],
"sequence_success": true,
"total_duration_ms": 90000,
"frequency": 5,
"created_at": "2026-03-23T17:30:00Z"
}
],
"total": 1
}Enqueue autonomous improvement task.
Request Body:
{
"task_description": "Optimize database query performance",
"priority": "medium",
"estimated_duration_minutes": 30,
"context": {
"recent_slow_queries": ["SELECT * FROM execution_traces"]
}
}Response 201:
{
"task_id": "boredom-uuid",
"status": "queued",
"position": 3,
"created_at": "2026-03-23T17:30:00Z"
}List queued boredom tasks.
Response 200:
{
"tasks": [
{
"task_id": "boredom-uuid",
"task_description": "Optimize database query performance",
"priority": "medium",
"status": "queued",
"created_at": "2026-03-23T17:30:00Z"
}
],
"total": 1
}Store boredom activity execution result.
Request Body:
{
"task_id": "boredom-uuid",
"success": true,
"execution_id": "exec-uuid",
"improvements": ["Reduced query time by 60%"],
"files_modified": ["src/db/queries.ts"]
}Response 201:
{
"result_id": "result-uuid",
"created_at": "2026-03-23T17:30:00Z"
}Retrieve boredom activity results.
Query Parameters:
limit(optional): Max results (default: 50)success(optional): Filter by success status
Response 200:
{
"results": [
{
"result_id": "result-uuid",
"task_id": "boredom-uuid",
"success": true,
"improvements": ["Reduced query time by 60%"],
"created_at": "2026-03-23T17:30:00Z"
}
],
"total": 1
}Get boredom activity statistics.
Response 200:
{
"total_tasks": 42,
"completed_tasks": 38,
"success_rate": 0.90,
"avg_duration_minutes": 25,
"top_improvements": [
{ "type": "performance", "count": 15 },
{ "type": "bug_fix", "count": 12 }
]
}Register vessel in active vessels registry.
Request Body:
{
"vessel_id": "local-tools-vessel-1",
"vessel_type": "local-tools-vessel",
"capabilities": ["activity-execution", "local-impulse-resolution"],
"version": "1.0.0",
"namespace": "activity-system",
"unit_name": "local-tools-vessel.service"
}Response 201:
{
"vessel_id": "local-tools-vessel-1",
"registered_at": "2026-03-23T17:30:00Z",
"heartbeat_interval_seconds": 30
}Send heartbeat to maintain vessel liveness.
Request Body:
{
"vessel_id": "local-tools-vessel-1",
"status": "active",
"current_activity": "fix-boredom-trace-storage",
"metrics": {
"cpu_percent": 45,
"memory_mb": 256,
"active_sessions": 2
}
}Response 200:
{
"vessel_id": "local-tools-vessel-1",
"acknowledged": true,
"next_heartbeat_due": "2026-03-23T17:31:00Z"
}List active vessels and their status.
Response 200:
{
"vessels": [
{
"vessel_id": "local-tools-vessel-1",
"vessel_type": "local-tools-vessel",
"status": "active",
"last_heartbeat": "2026-03-23T17:30:00Z",
"current_activity": "fix-boredom-trace-storage",
"uptime_seconds": 3600
}
],
"total": 1
}Extract successful execution into reusable template.
Request Body:
{
"execution_id": "exec-uuid",
"template_name": "fix-common-error-pattern",
"generalization_level": "high",
"extract_impulses": true
}Response 201:
{
"variant_id": "new-variant-uuid",
"activity_id": "fix-common-error-pattern",
"variant_name": "v1-extracted",
"extraction_quality_score": 0.88,
"created_at": "2026-03-23T17:30:00Z"
}Extract multiple executions from a session into template sequence.
Request Body:
{
"session_id": "session-uuid",
"sequence_name": "complete-feature-workflow",
"min_success_rate": 0.8
}Response 201:
{
"sequence_template_id": "seq-template-uuid",
"templates_extracted": 3,
"quality_score": 0.85,
"created_at": "2026-03-23T17:30:00Z"
}Standard Error Format:
{
"error": "Human-readable error message",
"code": "ERROR_CODE",
"details": {
"field": "Additional context"
},
"timestamp": "2026-03-23T17:30:00Z"
}Common Error Codes:
401 Unauthorized- Missing or invalid authentication400 Bad Request- Invalid request body/parameters404 Not Found- Resource not found409 Conflict- Resource already exists422 Unprocessable Entity- Validation error500 Internal Server Error- Unexpected server error503 Service Unavailable- Dependency unhealthy
Connection: ws://localhost:18080/ws
Events Broadcast:
{
"event": "execution_completed",
"data": {
"execution_id": "exec-uuid",
"variant_id": "variant-uuid",
"success": true,
"duration_ms": 45000
},
"timestamp": "2026-03-23T17:30:00Z"
}Event Types:
execution_startedexecution_completedexecution_failedtemplate_createdtemplate_updatedboredom_task_completed
See: SCHEMA_OWNERSHIP.md for which vessel owns which tables and where their schema files live
activity-api runs as a unit inside the substrate container; setup, configuration and the port table live in README § Installation.