Skip to content

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:8000

All responses use JSON. Successful responses return 200 OK (or 201 Created) with a JSON body. Error responses return an appropriate HTTP status with:

json
{
  "error": "description of what went wrong"
}

Health

GET /health

Returns the health status of the backend.

bash
curl http://localhost:8000/health
json
{
  "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.

bash
curl http://localhost:8000/api/agents
json
[
  {
    "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.

bash
curl http://localhost:8000/api/agents/pm_sarah

POST /api/agents

Create a new agent.

bash
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:

FieldRequiredDescription
idYesUnique identifier (snake_case, e.g., pm_sarah)
nameYesDisplay name
role_idYesOne of: pm, ta, qa, dev, hub
descriptionNoShort description
promptYesSystem prompt defining the agent's behavior
contextNoBackground context prepended to the prompt
identityNoPersonality traits
responsibilitiesNoList of responsibilities
constraintsNoList of constraint rules (things the agent must never do)
communication_styleNoCommunication style description

PUT /api/agents/:id

Update an existing agent.

bash
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.

bash
curl -X DELETE http://localhost:8000/api/agents/pm_sarah

POST /api/agents/seed

Seed default agents from goway/seeding/agents.yaml. Skips existing agents.

bash
curl -X POST http://localhost:8000/api/agents/seed
json
{ "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.

bash
curl http://localhost:8000/api/agents/ta_leo/capabilities

POST /api/agents/:id/capabilities

Add a capability to an agent.

bash
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.

bash
curl -X POST http://localhost:8000/api/agents/capabilities/seed

Agent Audit Log

GET /api/agents/:id/audit

Get the audit log for an agent — all actions, task executions, and tool calls.

bash
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.

bash
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:

FieldRequiredDescription
nameYesProject name
descriptionNoProject description
sourceYesSource platform: github, gitlab, jira, plane
source_project_idYesExternal 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.

bash
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:

FieldRequiredDescription
idYesUnique task identifier
nameYesDisplay name
descriptionYesWhat the task does
actor_idYesID of the agent to execute this task
actor_fallbackNoFallback system prompt if the assigned agent is not found

POST /api/tasks/seed

Seed task definitions from goway/seeding/tasks.yaml.

bash
curl -X POST http://localhost:8000/api/tasks/seed
json
{ "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.

bash
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.

bash
curl -X POST http://localhost:8000/api/tasks/triggers/seed

Source 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.

bash
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:

FieldRequiredDescription
sourceYesSource platform: github, gitlab, jira, plane
event_nameYesPlatform-specific event name (e.g., issues, Issue Hook)
actionNoEvent action filter (e.g., opened, closed). Null matches any action.
canonical_triggerYesThe normalized trigger name

POST /api/tasks/sources/seed

Seed source mappings from goway/seeding/source_event_mappings.yaml.

bash
curl -X POST http://localhost:8000/api/tasks/sources/seed

Webhooks

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.

bash
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.

bash
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).

bash
curl http://localhost:8000/api/integrations/github/test
json
{ "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.

bash
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.

bash
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:

FieldRequiredDescription
queryYesNatural language search query
agent_idNoFilter to a specific agent's memories
project_idNoFilter to a specific project's memories
scopeNotask, agent, project, organizational
limitNoMaximum results (default: 10)

Response (200):

json
[
  {
    "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.

bash
curl "http://localhost:8000/api/memory?project_id=42&scope=project&limit=20"

Query params:

ParamDescription
agent_idFilter by agent
project_idFilter by project
scopetask, agent, project, organizational
limitMax records (default 50)
offsetPagination 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.

bash
curl http://localhost:8000/api/memory/auth-decision-feb-2026

Response (200): memory object. 404 if not found.

POST /api/memory

Store a memory manually.

bash
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:

FieldRequiredDescription
keyYesUnique memory key
contentYesMemory content (string)
scopeYestask, agent, project, organizational
agent_idNoAssociate to an agent
project_idNoAssociate to a project
ttl_secondsNoOptional 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

  • task scope defaults to short-term storage with TTL if provided.
  • Other scopes persist in Postgres/pgvector; TTL respected when ttl_seconds is 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.

bash
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.

bash
curl -X POST http://localhost:8000/api/poll-sources/1/poll

LLM

Direct LLM access through LiteLLM proxy (useful for testing agent prompts).

POST /api/llm/chat

Send a chat completion request.

bash
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.

bash
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.

bash
curl "http://localhost:8000/api/watchdog?level=error&limit=100"

Query parameters:

ParamDescription
levelFilter: info, warn, error
limitMax results
offsetPagination offset
searchFull-text search in the message

GET /api/usage

Get agent usage statistics — token counts, task counts, tool calls.

bash
curl http://localhost:8000/api/usage

Canonical Triggers Reference

Built-in canonical triggers seeded by default. You can define additional triggers via the API.

Canonical TriggerDescription
issue.createdA new issue was created
issue.updatedAn issue was modified
issue.closedAn issue was closed
issue.commentedA comment was added to an issue
pr.openedA pull request was opened
pr.updatedA pull request was modified
pr.closedA pull request was closed
pr.mergedA pull request was merged
pr.reviewedA review was submitted
deployment.completedA deployment finished

Error Responses

HTTP StatusMeaning
400Bad request — check your JSON body or query parameters
404Resource not found
409Conflict — resource already exists
500Internal server error — check backend logs

Seeding endpoints do not return 409 for duplicates — they return {"created": 0, "skipped": N}.

Released under the MIT License.