REST API Reference
Active Development
New endpoints are added frequently. Endpoint signatures and response formats may change between releases. Check the changelog before upgrading.
Base URL & Format
http://localhost:8000All responses use JSON. Successful responses return 200 OK (or 201 Created) with a JSON body. Error responses return an appropriate HTTP status with:
{
"error": "description of what went wrong"
}Health
GET /health
Returns the health status of the backend.
curl http://localhost:8000/health{
"status": "ok",
"timestamp": "2026-02-18T10:00:00Z"
}Agents
Agents are AI personas with roles, system prompts, and capabilities.
GET /api/agents
List all agents.
curl http://localhost:8000/api/agents[
{
"id": "pm_sarah",
"name": "Sarah (PM)",
"role_id": "pm",
"description": "Product Manager for requirements analysis",
"prompt": "You are Sarah...",
"created_at": "2026-01-01T00:00:00Z"
}
]GET /api/agents/:id
Get a single agent by ID.
curl http://localhost:8000/api/agents/pm_sarahPOST /api/agents
Create a new agent.
curl -X POST http://localhost:8000/api/agents \
-H "Content-Type: application/json" \
-d '{
"id": "pm_sarah",
"name": "Sarah (PM)",
"role_id": "pm",
"description": "Product Manager for requirements analysis",
"prompt": "You are Sarah, an experienced Product Manager. Analyze issues..."
}'Body fields:
| Field | Required | Description |
|---|---|---|
id | Yes | Unique identifier (snake_case, e.g., pm_sarah) |
name | Yes | Display name |
role_id | Yes | One of: pm, ta, qa, dev, hub |
description | No | Short description |
prompt | Yes | System prompt defining the agent's behavior |
context | No | Background context prepended to the prompt |
identity | No | Personality traits |
responsibilities | No | List of responsibilities |
constraints | No | List of constraint rules (things the agent must never do) |
communication_style | No | Communication style description |
PUT /api/agents/:id
Update an existing agent.
curl -X PUT http://localhost:8000/api/agents/pm_sarah \
-H "Content-Type: application/json" \
-d '{
"prompt": "Updated system prompt..."
}'DELETE /api/agents/:id
Delete an agent.
curl -X DELETE http://localhost:8000/api/agents/pm_sarahPOST /api/agents/seed
Seed default agents from goway/seeding/agents.yaml. Skips existing agents.
curl -X POST http://localhost:8000/api/agents/seed{ "created": 5, "skipped": 0 }Default agents seeded: pm_sarah, ta_leo, qa_quinn, hub_system, dev_alex.
Agent Capabilities
Capabilities are labels that agents declare (e.g., code_review, security) used by the capability-based routing system to select the best agent for a task.
GET /api/agents/:id/capabilities
List an agent's capabilities.
curl http://localhost:8000/api/agents/ta_leo/capabilitiesPOST /api/agents/:id/capabilities
Add a capability to an agent.
curl -X POST http://localhost:8000/api/agents/ta_leo/capabilities \
-H "Content-Type: application/json" \
-d '{ "capability": "code_review" }'DELETE /api/agents/:id/capabilities/:capabilityId
Remove a capability from an agent.
POST /api/agents/capabilities/seed
Seed agent capabilities from goway/seeding/capabilities.yaml.
curl -X POST http://localhost:8000/api/agents/capabilities/seedAgent Audit Log
GET /api/agents/:id/audit
Get the audit log for an agent — all actions, task executions, and tool calls.
curl "http://localhost:8000/api/agents/ta_leo/audit?limit=50"Projects
Projects group configuration for a specific source repository or project.
GET /api/projects
List all projects.
GET /api/projects/:id
Get a single project.
POST /api/projects
Create a project.
curl -X POST http://localhost:8000/api/projects \
-H "Content-Type: application/json" \
-d '{
"name": "My API Service",
"description": "Backend API project",
"source": "github",
"source_project_id": "myorg/api-service"
}'Body fields:
| Field | Required | Description |
|---|---|---|
name | Yes | Project name |
description | No | Project description |
source | Yes | Source platform: github, gitlab, jira, plane |
source_project_id | Yes | External project identifier (e.g., owner/repo for GitHub) |
PUT /api/projects/:id
Update a project.
DELETE /api/projects/:id
Delete a project.
Tasks
Tasks define units of work triggered by canonical events.
GET /api/tasks
List all task definitions.
GET /api/tasks/:id
Get a single task.
POST /api/tasks
Create a task definition.
curl -X POST http://localhost:8000/api/tasks \
-H "Content-Type: application/json" \
-d '{
"id": "pm_analyze",
"name": "PM: Analyze Issue",
"description": "Product Manager analyzes the issue for requirements",
"actor_id": "pm_sarah",
"actor_fallback": "You are a Product Manager. Analyze this issue."
}'Body fields:
| Field | Required | Description |
|---|---|---|
id | Yes | Unique task identifier |
name | Yes | Display name |
description | Yes | What the task does |
actor_id | Yes | ID of the agent to execute this task |
actor_fallback | No | Fallback system prompt if the assigned agent is not found |
POST /api/tasks/seed
Seed task definitions from goway/seeding/tasks.yaml.
curl -X POST http://localhost:8000/api/tasks/seed{ "created": 9, "skipped": 0 }Default tasks seeded: triage_initial_intent, tech_discovery_review, intent_interpretation, technical_grooming, dev_environment_setup, feature_implementation, code_quality_audit, quality_verification, customer_uat_sync.
POST /api/tasks/:id/restart
Restart a failed task execution.
Trigger-Task Mappings
Maps canonical triggers to tasks. Multiple tasks can map to one trigger, causing all of them to fire.
GET /api/tasks/triggers
List all trigger → task mappings.
POST /api/tasks/triggers
Create a mapping.
curl -X POST http://localhost:8000/api/tasks/triggers \
-H "Content-Type: application/json" \
-d '{
"canonical_trigger": "issue.created",
"task_id": "pm_analyze"
}'POST /api/tasks/triggers/seed
Seed trigger mappings from goway/seeding/trigger_task_mappings.yaml.
curl -X POST http://localhost:8000/api/tasks/triggers/seedSource Event Mappings
Maps source-specific events to canonical triggers.
GET /api/tasks/sources
List all source event mappings.
POST /api/tasks/sources
Create a mapping.
curl -X POST http://localhost:8000/api/tasks/sources \
-H "Content-Type: application/json" \
-d '{
"source": "github",
"event_name": "issues",
"action": "opened",
"canonical_trigger": "issue.created"
}'Body fields:
| Field | Required | Description |
|---|---|---|
source | Yes | Source platform: github, gitlab, jira, plane |
event_name | Yes | Platform-specific event name (e.g., issues, Issue Hook) |
action | No | Event action filter (e.g., opened, closed). Null matches any action. |
canonical_trigger | Yes | The normalized trigger name |
POST /api/tasks/sources/seed
Seed source mappings from goway/seeding/source_event_mappings.yaml.
curl -X POST http://localhost:8000/api/tasks/sources/seedWebhooks
POST /webhook/:slug
The unified webhook endpoint. Receives webhooks from external services.
See the Webhooks Reference for payload formats and security verification.
Webhook Mappings
Advanced webhook routing rules with custom field extraction using jq-style filters.
GET /api/webhook-mappings
List all webhook mappings.
POST /api/webhook-mappings
Create a webhook mapping.
curl -X POST http://localhost:8000/api/webhook-mappings \
-H "Content-Type: application/json" \
-d '{
"source": "github",
"event_type": "issues",
"jq_filter": ".action == \"opened\"",
"canonical_trigger": "issue.created"
}'POST /api/webhook-mappings/seed
Seed webhook mappings from configuration.
Dynamic Integrations
Agent-specific integration credentials. Useful when different agents or projects need different tokens for the same platform.
INFO
Dynamic integrations require ENCRYPTION_KEY to be set in your environment — credentials are stored encrypted.
GET /api/integrations
List all configured integrations.
POST /api/integrations
Add a dynamic integration.
curl -X POST http://localhost:8000/api/integrations \
-H "Content-Type: application/json" \
-d '{
"source": "github",
"name": "Project A GitHub Integration",
"credentials": {
"token": "ghp_..."
}
}'PUT /api/integrations/:id
Update an integration.
DELETE /api/integrations/:id
Delete an integration.
GET /api/integrations/:source/test
Test a static integration connection (uses environment variable credentials).
curl http://localhost:8000/api/integrations/github/test{ "status": "ok", "source": "github" }Tools
Tool definitions describe the actions agents can invoke through the LLM tool-calling mechanism (e.g., add_comment, update_issue).
GET /api/tools
List all tool definitions.
POST /api/tools
Create a tool definition.
POST /api/tools/seed
Seed tool definitions from configuration.
GET /api/tool-executions
List tool execution history, including token usage and timing.
curl "http://localhost:8000/api/tool-executions?agent_id=ta_leo&limit=50"Memory
Agent memory with semantic search via pgvector embeddings.
POST /api/memory/search
Semantic search over agent memories using natural language queries.
curl -X POST http://localhost:8000/api/memory/search \
-H "Content-Type: application/json" \
-d '{
"query": "authentication implementation decisions",
"project_id": 42,
"agent_id": "ta_leo",
"scope": "project",
"limit": 10
}'Body fields:
| Field | Required | Description |
|---|---|---|
query | Yes | Natural language search query |
agent_id | No | Filter to a specific agent's memories |
project_id | No | Filter to a specific project's memories |
scope | No | task, agent, project, organizational |
limit | No | Maximum results (default: 10) |
Response (200):
[
{
"key": "auth-decision-feb-2026",
"content": "Team decided to use JWT...",
"scope": "project",
"agent_id": "ta_leo",
"project_id": 42,
"similarity": 0.92,
"created_at": "2026-02-18T10:00:00Z"
}
]GET /api/memory
List memories with optional filters.
curl "http://localhost:8000/api/memory?project_id=42&scope=project&limit=20"Query params:
| Param | Description |
|---|---|
agent_id | Filter by agent |
project_id | Filter by project |
scope | task, agent, project, organizational |
limit | Max records (default 50) |
offset | Pagination offset |
Response (200): array of memories with key, content, scope, agent_id, project_id, created_at, updated_at.
GET /api/memory/:key
Retrieve a memory by key.
curl http://localhost:8000/api/memory/auth-decision-feb-2026Response (200): memory object. 404 if not found.
POST /api/memory
Store a memory manually.
curl -X POST http://localhost:8000/api/memory \
-H "Content-Type: application/json" \
-d '{
"key": "auth-decision-feb-2026",
"content": "Team decided to use JWT with 15-minute expiry and refresh tokens stored in HttpOnly cookies",
"agent_id": "ta_leo",
"project_id": 42,
"scope": "project",
"ttl_seconds": 3600
}'Body fields:
| Field | Required | Description |
|---|---|---|
key | Yes | Unique memory key |
content | Yes | Memory content (string) |
scope | Yes | task, agent, project, organizational |
agent_id | No | Associate to an agent |
project_id | No | Associate to a project |
ttl_seconds | No | Optional TTL; applied for short-term/ephemeral memories |
Response (201): memory object. 409 if key already exists.
DELETE /api/memory/:key
Delete a memory by key (idempotent).
Response codes: 204 on success, 404 if not found.
Scope & TTL notes
taskscope defaults to short-term storage with TTL if provided.- Other scopes persist in Postgres/pgvector; TTL respected when
ttl_secondsis set. - Semantic search runs against pgvector; keyword search uses Postgres full-text index.
Polling Sources
Configure Aether to poll sources that don't support webhooks, on a schedule.
GET /api/poll-sources
List polling source configurations.
POST /api/poll-sources
Create a polling source.
curl -X POST http://localhost:8000/api/poll-sources \
-H "Content-Type: application/json" \
-d '{
"source": "jira",
"project_id": "PROJ",
"interval_minutes": 5,
"enabled": true
}'PUT /api/poll-sources/:id
Update a polling source.
DELETE /api/poll-sources/:id
Delete a polling source.
POST /api/poll-sources/:id/poll
Trigger an immediate poll, bypassing the schedule.
curl -X POST http://localhost:8000/api/poll-sources/1/pollLLM
Direct LLM access through LiteLLM proxy (useful for testing agent prompts).
POST /api/llm/chat
Send a chat completion request.
curl -X POST http://localhost:8000/api/llm/chat \
-H "Content-Type: application/json" \
-d '{
"agent_id": "ta_leo",
"messages": [
{ "role": "user", "content": "What are the security risks of storing JWTs in localStorage?" }
]
}'MCP Servers
MCP (Model Context Protocol) servers provide additional tools to agents at runtime.
GET /api/mcp-servers
List configured MCP servers.
POST /api/mcp-servers
Register an MCP server.
curl -X POST http://localhost:8000/api/mcp-servers \
-H "Content-Type: application/json" \
-d '{
"name": "My MCP Server",
"url": "http://mcp-server:8080",
"agent_id": "ta_leo"
}'POST /api/mcp-servers/discover
Discover and register tools from a registered MCP server.
Monitoring & Logs
GET /api/watchdog
Retrieve watchdog logs with filtering. Requires WATCHDOG_ENABLED=true in your environment.
curl "http://localhost:8000/api/watchdog?level=error&limit=100"Query parameters:
| Param | Description |
|---|---|
level | Filter: info, warn, error |
limit | Max results |
offset | Pagination offset |
search | Full-text search in the message |
GET /api/usage
Get agent usage statistics — token counts, task counts, tool calls.
curl http://localhost:8000/api/usageCanonical Triggers Reference
Built-in canonical triggers seeded by default. You can define additional triggers via the API.
| Canonical Trigger | Description |
|---|---|
issue.created | A new issue was created |
issue.updated | An issue was modified |
issue.closed | An issue was closed |
issue.commented | A comment was added to an issue |
pr.opened | A pull request was opened |
pr.updated | A pull request was modified |
pr.closed | A pull request was closed |
pr.merged | A pull request was merged |
pr.reviewed | A review was submitted |
deployment.completed | A deployment finished |
Error Responses
| HTTP Status | Meaning |
|---|---|
400 | Bad request — check your JSON body or query parameters |
404 | Resource not found |
409 | Conflict — resource already exists |
500 | Internal server error — check backend logs |
Seeding endpoints do not return 409 for duplicates — they return {"created": 0, "skipped": N}.
