API Gateway

The API Gateway is an HTTP server embedded in agentd that exposes the full agent management API over REST. It allows external services, CI pipelines, dashboards, and remote operators to interact with a running agentd instance without a direct Unix socket connection.

The gateway shares the same DaemonState as the IPC server; there is no second socket hop. Every request translates directly into an IPC command and receives the same capability enforcement and audit logging.

Starting the API Gateway

The gateway starts automatically when agentd launches. By default it binds to 127.0.0.1:8080.

# Start agentd (gateway included)
cargo run --bin agentd

# Bind to a different address
AGENTD_API_ADDR=0.0.0.0:9090 cargo run --bin agentd

Verify the gateway is up:

curl http://127.0.0.1:8080/health
# {"status":"ok","version":"...","uptime_secs":42}

Authentication

All endpoints except GET /health require a Bearer token in the Authorization header:

Authorization: Bearer <token>

Tokens are 64-character hex strings (32 random bytes). Only the SHA-256 hash is stored in SQLite; the plaintext is shown once at creation time and is never retrievable again.

Each token is bound to an agent ID at creation time. All HTTP requests made with that token are attributed to the bound agent for capability checks and audit log entries.

Creating a Token

ash api-key create --name "ci-pipeline" --agent-id 550e8400-e29b-41d4-a716-446655440000
Created API key 'ci-pipeline'
Agent: 550e8400-e29b-41d4-a716-446655440000

Token: a3f8c2e1d4b7...  (64 hex chars)

Save this token. It will not be shown again.

See ash api-key for the full CLI reference.

HTTP Endpoints

Health

GET /health

Returns daemon version and uptime. No authentication required.

curl http://127.0.0.1:8080/health
{"status":"ok","version":"0.1.0","uptime_secs":120}

Agents

GET /agents

List all running agents.

curl -H "Authorization: Bearer <token>" http://127.0.0.1:8080/agents
[
  {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "name": "report-agent",
    "state": "Plan",
    "trust_level": "sandboxed"
  }
]

POST /agents

Spawn a new agent. Accepts two body formats:

Spawn from inline manifest YAML:

curl -X POST \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"manifest_yaml": "apiVersion: scarab/v1\nkind: AgentManifest\n..."}' \
  http://127.0.0.1:8080/agents

Spawn by installed name (from agent store):

curl -X POST \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"name": "report-agent", "task_override": "Summarize Q1 results"}' \
  http://127.0.0.1:8080/agents

Returns HTTP 201 with the spawned agent's ID:

{"id": "550e8400-e29b-41d4-a716-446655440000"}

GET /agents/:id

Get details for a single agent. Returns HTTP 404 if the agent does not exist.

curl -H "Authorization: Bearer <token>" \
  http://127.0.0.1:8080/agents/550e8400-e29b-41d4-a716-446655440000

DELETE /agents/:id

Terminate a running agent.

curl -X DELETE \
  -H "Authorization: Bearer <token>" \
  http://127.0.0.1:8080/agents/550e8400-e29b-41d4-a716-446655440000

Tools

GET /agents/:id/tools

List tools available to an agent.

curl -H "Authorization: Bearer <token>" \
  http://127.0.0.1:8080/agents/550e8400-e29b-41d4-a716-446655440000/tools

POST /agents/:id/tools/:name

Invoke a tool on behalf of an agent. The request body is optional JSON input for the tool.

curl -X POST \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"message": "hello"}' \
  http://127.0.0.1:8080/agents/550e8400-e29b-41d4-a716-446655440000/tools/echo

Audit

GET /agents/:id/audit

Query the audit trail for an agent. Supports filtering by entry count and time range.

curl -H "Authorization: Bearer <token>" \
  "http://127.0.0.1:8080/agents/550e8400-e29b-41d4-a716-446655440000/audit?limit=50&since=2026-01-01T00:00:00Z&until=2026-12-31T23:59:59Z"
Query ParameterTypeDescription
limitintegerMaximum number of entries to return
sinceRFC3339Return entries at or after this timestamp
untilRFC3339Return entries at or before this timestamp

Memory

GET /agents/:id/memory/:key

Read a memory key for an agent.

curl -H "Authorization: Bearer <token>" \
  http://127.0.0.1:8080/agents/550e8400-e29b-41d4-a716-446655440000/memory/last-run-result

Observations

GET /agents/:id/observations

Query the observation log for an agent.

curl -H "Authorization: Bearer <token>" \
  http://127.0.0.1:8080/agents/550e8400-e29b-41d4-a716-446655440000/observations

Live Event Stream

GET /events

Server-Sent Events (SSE) stream of live audit entries across all agents. Useful for real-time dashboards and alerting.

curl -H "Authorization: Bearer <token>" \
  -H "Accept: text/event-stream" \
  http://127.0.0.1:8080/events

Each event is a JSON-serialized AuditEntry:

data: {"id":"...","agent_id":"...","action":"ToolInvoke","timestamp":"...","prev_hash":"...","hash":"..."}

data: {"id":"...","agent_id":"...","action":"LifecycleTransition","timestamp":"...","prev_hash":"...","hash":"..."}

The stream sends keep-alive pings when idle. Clients should handle reconnections.

Query ParameterDescription
_cursorCursor for resuming a stream (reserved, currently unused)

CORS

Cross-origin requests are controlled by the AGENTD_API_CORS_ORIGINS environment variable:

ValueBehavior
Not set / emptyAllow all origins (*)
*Allow all origins
https://dashboard.example.com,https://ci.example.comAllow listed origins only

Allowed methods and headers are always unrestricted.

# Allow only a specific dashboard origin
AGENTD_API_CORS_ORIGINS=https://dashboard.example.com cargo run --bin agentd

Environment Variables

VariableDefaultDescription
AGENTD_API_ADDR127.0.0.1:8080HTTP bind address for the API gateway
AGENTD_API_CORS_ORIGINS(allow all)Comma-separated list of allowed CORS origins
AGENTD_API_TOKEN_DB/tmp/agentd_api_tokens.dbSQLite path for the API token store

See Environment Variables for the full reference.

Endpoint Summary

MethodPathAuthDescription
GET/healthNoneDaemon version and uptime
GET/agentsBearerList all agents
POST/agentsBearerSpawn an agent (inline manifest or by name)
GET/agents/:idBearerGet agent details
DELETE/agents/:idBearerTerminate an agent
GET/agents/:id/toolsBearerList available tools
POST/agents/:id/tools/:nameBearerInvoke a tool
GET/agents/:id/auditBearerQuery audit trail
GET/agents/:id/memory/:keyBearerRead a memory key
GET/agents/:id/observationsBearerQuery observation log
GET/eventsBearerSSE stream of live audit entries