Base URL: http://localhost:8000. Interactive OpenAPI/Swagger lives at /docs.
When AUTH_ENABLED=true, /v1/* (except the public template catalog) and /mcp require
Authorization: Bearer <api_key>; /admin/* requires X-Admin-Token.
Run synchronously and return the full result. Blocks until done.
Request:
{ "query": "string (required)", "context": "string | null", "max_iterations": 6 }Response:
{
"run_id": "…",
"status": "done | max_iterations",
"answer": "…",
"iterations": 2,
"steps": [
{ "tool": "execute_python_code", "code": "…", "stdout": "…", "stderr": "",
"exit_code": 0, "timed_out": false, "duration_ms": 412 }
],
"usage": { "input_tokens": 8421, "output_tokens": 1290, "total_tokens": 9711,
"cost_usd": 0.0741, "llm_calls": 3 }
}Errors: 402 spend cap reached · 502 orchestration failed · 503 sandbox not ready.
Start a run in the background; returns 202 with a run_id and a telemetry WebSocket URL. Watch
it live, then fetch the result.
{ "run_id": "…", "status": "running", "telemetry_ws": "/ws/telemetry?run_id=…" }Stream a run as Server-Sent Events — one frame per telemetry phase
(start, thinking, writing_code, executing_sandbox, done/error), then a final result
event with the answer. An HTTP alternative to the telemetry WebSocket.
event: writing_code
data: {"run_id":"…","phase":"writing_code","message":"Generated code to run","data":{…}}
event: result
data: {"run_id":"…","status":"done","answer":"…","usage":{…}}
Fetch a background run's status and (once finished) its result. Never blocked by spend caps.
Streams OrchestratorEvents: thinking, writing_code, executing_sandbox, done, error,
each with data (code/stdout previews, exit codes, usage on done). Omit run_id for the global
"God View" feed. Requires ?api_key= / Bearer when auth is enabled.
GET /v1/templates?domain=legal|finance|general— list ready-to-run task templates.GET /v1/templates/packs— list the packs.GET /v1/templates/{id}— one template.
Turn a template into a run by POSTing its query (+ optional example_context) to
/v1/orchestrate. See templates.md.
POST /admin/keys{ "name": "…" }→201with the plaintextapi_key(shown once).GET /admin/keys→ keys with usage (request_count,input_tokens,output_tokens,cost_usd,spend_cap_usd).DELETE /admin/keys/{id}→204revoke.PUT /admin/keys/{id}/spend-cap{ "spend_cap_usd": 25.0 | null }→ set/clear the USD cap. Once a key'scost_usdreaches its cap, new orchestration requests get402.
The agent saves working scripts as named skills (via the save_skill/load_skill tools) and
reloads them later. Browse/curate them here:
GET /v1/skills?q=…— list skill summaries (name/description/tags/use_count; no code). Public.GET /v1/skills/{name}— one skill, including its code. Public.POST /v1/skills{name, description, code, tags}→201create/update (API key when auth on).DELETE /v1/skills/{name}→204(API key when auth on).
POST /oauth/token—client_credentialsgrant: sendgrant_type=client_credentialsplus the API key asclient_secret(form field or HTTP Basic). Returns a short-lived scoped JWT (access_token,expires_in,scope). Scopes:orchestrate:run,orchestrate:read.GET /.well-known/oauth-authorization-server— RFC 8414 metadata.GET /.well-known/oauth-protected-resource— RFC 9728 metadata.
Present the JWT as Authorization: Bearer <token> anywhere an API key is accepted; tokens are
validated for signature, iss, aud, exp, and scope. Static API keys keep working.
POST /mcp— streamable-HTTP MCP server exposing theorchestratetool. Point any MCP client (Claude Desktop, MCP Inspector) athttp://localhost:8000/mcp. WhenAUTH_ENABLED=trueit accepts a Bearer API key or a scoped token carryingorchestrate:run.GET /v1/mcp/upstreams— whenMCP_UPSTREAMSis configured, lists the upstream MCP servers Corenexia aggregates and the namespaced tools (<upstream>__<tool>) it re-exposes to the agent.
GET /health→{ status, sandbox_ready, sandbox, llm_provider }. Every response carries anX-Request-IDcorrelating it to telemetry.