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

Executions

POST /v1/executions

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

Request:

{
  "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": "[email protected]"
}

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": "[email protected]"
}

reason is required. rejected_by is optional.

Response 200:

{ "status": "rejected" }

SMCP Endpoints

POST /v1/smcp/attest

Attestation handshake — used by bootstrap.py at the start of each agent execution to establish an SMCP 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 SMCP Architecture for the full attestation flow.


POST /v1/smcp/invoke

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

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