Aegis Orchestrator
Reference

REST API Reference

Full HTTP API surface of the AEGIS Orchestrator — all routes, request/response schemas, and authentication.

REST API Reference

The AEGIS Orchestrator exposes an HTTP API on port 8080 (default). All request and response bodies are JSON unless otherwise noted.


Authentication

Route groupMechanism
Most endpointsKeycloak Bearer JWT: Authorization: Bearer <token>
POST /v1/webhooks/{source}HMAC-SHA256 signature: X-Aegis-Signature: sha256=<hex>
POST /v1/dispatch-gatewayInternal — no external auth (agent containers only)
GET /healthNone

Service Account Tenant Delegation

Service accounts (M2M clients using client credentials) may include an X-Tenant-Id: {tenant-slug} request header to scope operations to a specific user tenant. Without this header, service account requests scope to the aegis-system tenant by default.

This header is ignored for all other identity types (consumer users, operator users).


Agents

GET /v1/agents/lookup/{name}

Look up a deployed agent by its unique name. Returns the agent's ID and manifest metadata.

Path parameters:

ParameterDescription
nameThe unique name of the agent (e.g. code-reviewer)

Request headers:

HeaderRequiredDescription
AuthorizationBearer JWT
X-Tenant-IdNoFor service accounts: scope the lookup to this tenant instead of the default aegis-system tenant

Response 200:

{
  "agent_id": "agt-uuid",
  "name": "code-reviewer",
  "tenant_id": "tenant-slug"
}

Errors:

HTTPBodyCause
404{"error": "Agent not found"}No agent with that name exists in the resolved tenant

GET /v1/agents

List all deployed agents visible to the caller's resolved tenant context.

Request headers:

HeaderRequiredDescription
AuthorizationBearer JWT
X-Tenant-IdNoFor service accounts: scope the listing to this tenant instead of the default aegis-system tenant

Response 200:

{
  "agents": [
    {
      "agent_id": "agt-uuid",
      "name": "code-reviewer",
      "tenant_id": "tenant-slug"
    }
  ]
}

Executions

POST /v1/executions

Start an agent execution. Returns immediately with the execution_id; use the SSE stream to follow progress.

Request headers:

HeaderRequiredDescription
AuthorizationBearer JWT
X-Tenant-IdNoFor service accounts: scope the execution to this tenant instead of the default aegis-system tenant

Request body:

{
  "agent_id": "agt-uuid",
  "input": "Write a function that checks if a number is prime."
}
FieldTypeRequiredDescription
agent_idstring (UUID)ID of a deployed agent
inputstringTask input passed to the agent

Response 200:

{
  "execution_id": "exec-uuid"
}

Errors:

HTTPBodyCause
400{"error": "Invalid agent ID"}agent_id is not a valid UUID
500{"error": "<message>"}Execution failed to start

GET /v1/executions/{id}/stream

Stream execution events as Server-Sent Events (SSE). Returns Content-Type: text/event-stream.

Each data: line is a JSON-encoded ExecutionEvent object. Events match the types defined in the gRPC API reference.

Example stream:

data: {"execution_started":{"execution_id":"exec-uuid","agent_id":"agt-uuid","started_at":"2026-03-05T14:00:00Z"}}

data: {"iteration_started":{"execution_id":"exec-uuid","iteration_number":1,"action":"Write a primality check","started_at":"2026-03-05T14:00:01Z"}}

data: {"iteration_completed":{"execution_id":"exec-uuid","iteration_number":1,"output":"def is_prime(n): ...","completed_at":"2026-03-05T14:00:15Z"}}

data: {"execution_completed":{"execution_id":"exec-uuid","final_output":"def is_prime(n): ...","total_iterations":1,"completed_at":"2026-03-05T14:00:15Z"}}

Example (JavaScript EventSource):

const es = new EventSource(
  `https://your-aegis-node/v1/executions/${executionId}/stream`,
  { headers: { Authorization: `Bearer ${token}` } }
);

es.onmessage = (e) => {
  const event = JSON.parse(e.data);
  if (event.execution_completed) {
    console.log('Output:', event.execution_completed.final_output);
    es.close();
  }
};

Human Approvals

GET /v1/human-approvals

List all pending human approval requests.

Response 200:

{
  "pending_requests": [
    {
      "id": "req-uuid",
      "execution_id": "exec-uuid",
      "prompt": "Review the draft and approve or reject.",
      "created_at": "2026-03-05T14:00:00Z",
      "timeout_seconds": 86400
    }
  ]
}

GET /v1/human-approvals/{id}

Get a specific pending approval request.

Response 200:

{
  "request": {
    "id": "req-uuid",
    "execution_id": "exec-uuid",
    "prompt": "Review the draft and approve or reject.",
    "created_at": "2026-03-05T14:00:00Z",
    "timeout_seconds": 86400
  }
}

Errors:

HTTPBodyCause
400{"error": "Invalid request ID"}Not a valid UUID
200{"error": "Request not found or already completed"}Request expired or already resolved

POST /v1/human-approvals/{id}/approve

Approve a pending request and resume the workflow.

Request:

{
  "feedback": "Looks good, approved for production.",
  "approved_by": "alice@example.com"
}

Both fields are optional.

Response 200:

{ "status": "approved" }

POST /v1/human-approvals/{id}/reject

Reject a pending request and transition the workflow to the rejection path.

Request:

{
  "reason": "Needs more citations.",
  "rejected_by": "bob@example.com"
}

reason is required. rejected_by is optional.

Response 200:

{ "status": "rejected" }

SEAL Endpoints

POST /v1/seal/attest

Attestation handshake — used by bootstrap.py at the start of each agent execution to establish an SEAL session.

Request:

{
  "agent_id": "agt-uuid",
  "execution_id": "exec-uuid",
  "container_id": "container-hash",
  "agent_public_key": "<base64-encoded Ed25519 public key>"
}

Response 200:

{
  "security_token": "<JWT>",
  "session_id": "session-uuid",
  "expires_at": "2026-03-05T15:00:00Z"
}

See SEAL Architecture for the full attestation flow.


POST /v1/seal/invoke

SEAL-wrapped tool invocation. Called by bootstrap.py to invoke a tool through the orchestrator proxy. The body is a SealEnvelope containing a signed MCP tool call.

POST /v1/seal/invoke is the spec-compliant path. POST /v1/invoke is also registered as a convenience alias and remains fully functional.

See Tool Routing for the three routing paths and wire format.


Dispatch Gateway

POST /v1/dispatch-gateway

The inner-loop communication endpoint between bootstrap.py and the orchestrator. Handles the full LLM → tool call → LLM cycle.

This endpoint is called by bootstrap.py inside agent containers. It is bound to the internal Docker network and is not exposed externally.

Request — initial generate:

{
  "type": "generate",
  "agent_id": "agt-uuid",
  "execution_id": "exec-uuid",
  "iteration_number": 1,
  "model_alias": "default",
  "prompt": "Task: Write a primality check\n\nInput: in Python",
  "messages": []
}

Request — dispatch result:

{
  "type": "dispatch_result",
  "execution_id": "exec-uuid",
  "dispatch_id": "dispatch-uuid",
  "exit_code": 0,
  "stdout": "All tests passed.\n",
  "stderr": "",
  "duration_ms": 1243,
  "truncated": false
}

Response — final:

{
  "type": "final",
  "content": "def is_prime(n): ...",
  "tool_calls_executed": 2,
  "conversation": [...]
}

Response — dispatch a command:

{
  "type": "dispatch",
  "dispatch_id": "dispatch-uuid",
  "action": "exec",
  "command": "python",
  "args": ["-m", "pytest", "test_prime.py"],
  "cwd": "/workspace",
  "env_additions": {},
  "timeout_secs": 60,
  "max_output_bytes": 524288
}

Stimulus Ingestion

POST /v1/stimuli

Ingest a stimulus from an internal service or operator. Authenticated by Keycloak Bearer JWT.

Request:

{
  "source": "http_api",
  "content": "Deploy release v2.1.0 to production.",
  "idempotency_key": "deploy-v2.1.0"
}
FieldTypeRequiredDescription
sourcestringSource identifier. Use "http_api" or a custom source name.
contentstringStimulus payload — natural language or JSON string.
idempotency_keystringDeduplication key. Scoped to (source, key) with 24-hour TTL.

Response 200:

{
  "stimulus_id": "stim-uuid",
  "workflow_execution_id": "wfex-uuid"
}

Errors:

HTTPCodeCause
409idempotent_duplicateAlready processed within TTL window
422classification_failedRouterAgent confidence below threshold
422no_router_configuredNo direct route and no RouterAgent
500workflow_errorWorkflow execution failed to start

POST /v1/webhooks/{source}

Ingest a webhook from an external system. Authenticated by HMAC-SHA256.

Required headers:

HeaderFormatDescription
X-Aegis-Signaturesha256=<hex>HMAC-SHA256 of the raw body using the source's shared secret
X-Idempotency-Keyany stringOptional — enables duplicate delivery detection

Body: Any content type. The raw body bytes are used for HMAC verification and forwarded as the stimulus content.

Response 200:

{
  "stimulus_id": "stim-uuid",
  "workflow_execution_id": "wfex-uuid"
}

Errors:

HTTPCodeCause
401missing_signatureX-Aegis-Signature header absent
401invalid_signatureHMAC digest mismatch
401secret_not_foundAEGIS_WEBHOOK_SECRET_<SOURCE> not set
400malformed_signatureHeader not in sha256=<hex> format
409idempotent_duplicateSame delivery already processed
422classification_failedRouterAgent confidence below threshold

Health

GET /health

Liveness probe. Returns 200 OK when the orchestrator is running.

Response 200:

{ "status": "ok" }

See Also

On this page