Run agents

Runtime API

Start and follow jobs from your own apps, over Connect, gRPC or gRPC-Web.

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.

MethodDoes
StartJobStarts an agent. Starting a job with the ID of one still running returns that job.
GetJobStatus, answer or error, child job IDs, and cost per branch
CancelJobCancels a job and its children
ListJobsRecent top-level jobs, newest first
WatchJobA 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
ListApprovalsWhat waits for a person's decision across the tenant's running jobs, oldest first; job narrows it to one job
DecideApprovalApproves or denies one, with a comment; admins and operators may. See Approvals
GetJobTraceThe job's steps from its history, with what each cost, and findings about what looks wrong. See Job history
GetJobStepWhat one step read and wrote. It can hold customer data: admins and operators may, and each call is in the audit log
GetCatalogThe 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:

Terminal
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, or never.
  • 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:

RouteDoes
POST /v1/agents/<name>/jobsStarts 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.jsonAn OpenAPI 3.1 document of the tenant's agents and flows
Terminal
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

Terminal
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:

Terminal
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:

agent
string required
The agent's or the flow's name, as the catalog lists it.
input
value
Text, or JSON that matches the agent's input schema. The edge checks it against the schema before the job starts: an input that does not fit is refused with invalid_argument (HTTP 400) and what is wrong, and no job is made.
tenant
string
The tenant to run in; empty means default.
id
string
An ID for the job; empty means a new random one. May not contain /.
timeout
duration
How long the job may run in all, on top of the agent's own limits.

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.

Copyright © 2026