Runtime API
The runtime API is oz0.runtime.v1.RuntimeService on the edge's HTTPS port, 7443. It speaks Connect (JSON or protobuf over HTTP), gRPC and gRPC-Web, so any language with an HTTP client or a gRPC library can use it. The CLI uses the same API.
| Method | Does |
|---|---|
StartJob | Starts an agent. Starting a job with the ID of one still running returns that job. |
GetJob | Status, answer or error, child job IDs, and cost per branch |
CancelJob | Cancels a job and its children |
ListJobs | Recent top-level jobs, newest first |
WatchJob | A stream of what the job and its child jobs do as it happens: text, tool calls, tool results, children and approvals, ending with the job's final state |
ListApprovals | What waits for a person's decision across the tenant's running jobs, oldest first; job narrows it to one job |
DecideApproval | Approves or denies one, with a comment; admins and operators may. See Approvals |
GetJobTrace | The job's steps from its history, with what each cost, and findings about what looks wrong. See Job history |
GetJobStep | What one step read and wrote. It can hold customer data: admins and operators may, and each call is in the audit log |
GetCatalog | The tenant's agents and flows, with their input and output schemas |
Authentication
Apps use one of the tenant's API keys. A tenant's admins make them with the CLI, or on the web UI's Settings page:
orchestrator-zero apikey create support-desk --tenant acme --role operator
orchestrator-zero apikey create dashboard --tenant acme --role reader --expires 30d
orchestrator-zero apikey list --tenant acme
orchestrator-zero apikey revoke 3f9c2a1b7d0e
The key is shown once, as oz0_<id>_<secret>; keep it as a secret. Send it as Authorization: Bearer <key>.
- A key has a role in its one tenant. A reader follows jobs. An operator also starts and cancels them and decides approvals.
- Operator keys see what jobs read and wrote, unless they are made with
--no-content. - Keys work only on the runtime API. They do not work on the admin API, or on Temporal's ports.
- A key lasts 90 days unless it is made with
--expires 30d, another time, ornever. - A revoked key stops working within seconds on every edge. The jobs a key starts, and the audit log, name it as
apikey:<id>.
Operators can use their certificate instead. server init writes one to the operator's directory, ~/.config/orchestrator-zero/<cluster>/, as operator.crt and operator.key, with the cluster's CA as ca.crt. Nodes are refused.
The edge's certificate comes from the cluster's own CA, so a client trusts that CA rather than the system's: ca.crt from an operator's directory, or fetched and checked the way the one-line install does.
Typed HTTP routes and the OpenAPI document
Next to the Connect API, the edge has three plain HTTP routes, for the same callers:
| Route | Does |
|---|---|
POST /v1/agents/<name>/jobs | Starts an agent or a flow with its input as the body: JSON, or text/plain for a text input. It answers 201 with the job. |
GET /v1/jobs/<id> | The job: its status, and its answer once it has one |
GET /v1/openapi.json | An OpenAPI 3.1 document of the tenant's agents and flows |
curl --cacert ca.crt -H "Authorization: Bearer $OZ0_API_KEY" -H 'Content-Type: application/json' \
-d '{"repo": "acme/api", "pr": 42}' 'https://edge.example.com:7443/v1/agents/reviewer/jobs?tenant=acme'
curl --cacert ca.crt -H "Authorization: Bearer $OZ0_API_KEY" 'https://edge.example.com:7443/v1/openapi.json?tenant=acme' > oz0.json
The document has one operation per agent, run_<name>. Its request body is the agent's input schema, and its response is the job, with output typed by the agent's output schema. Generate a client from it with any OpenAPI generator. It changes when a plugin changes an agent or a schema, and its ETag says when. A plugin installed before Orchestrator Zero put schemas in plugins' bundles needs plugin update before its agents' schemas appear.
Start a job with curl
curl --cacert ca.crt -H "Authorization: Bearer $OZ0_API_KEY" \
-H 'Content-Type: application/json' \
-d '{"agent": "reviewer", "input": {"repo": "acme/api", "pr": 42}, "timeout": "900s", "tenant": "acme"}' \
https://edge.example.com:7443/oz0.runtime.v1.RuntimeService/StartJob
{ "job": { "id": "job-bb270cf1-...", "agent": "reviewer", "status": "JOB_STATUS_RUNNING", "startedAt": "..." } }
Then poll it:
curl --cacert ca.crt -H "Authorization: Bearer $OZ0_API_KEY" \
-H 'Content-Type: application/json' -d '{"id": "job-bb270cf1-...", "tenant": "acme"}' \
https://edge.example.com:7443/oz0.runtime.v1.RuntimeService/GetJob
Requests and responses
StartJob takes:
invalid_argument (HTTP 400) and what is wrong, and no job is made.default./.A Job has id, agent, status, startedAt, closedAt, output (the answer, text or JSON), error, children (direct child job IDs), approvals (what it waits for, while it runs), flow (true for a flow's job) and cost. cost holds the totals (usd, calls, inputTokens, outputTokens) and branches: one entry per job in the tree, the job itself first, with its agent, models, nodes, tokens, cached tokens and cost.
The protobuf definition is proto/oz0/runtime/v1/runtime.proto in the repository. Generate a client for your language from it with buf or protoc; typed client SDKs for Python, TypeScript and Go are planned.