API

Use the API from a client

Typed TypeScript clients

Typed clients infer their shape from the router rather than redeclaring request and response types:

import { createORPCClient } from '@orpc/client';
import { RPCLink } from '@orpc/client/fetch';
import type { RouterClient } from '@orpc/server';
import type { RpcRouter } from '@agent-zero/api';

const client: RouterClient<RpcRouter> = createORPCClient(
  new RPCLink({
    url: 'http://localhost:3000/rpc',
    headers: { authorization: `Bearer ${process.env.CONTROL_PLANE_TOKEN}` },
  }),
);

const { tasks } = await client.tasks.list();
await client.approvals.decide({ taskId: tasks[0]!.id, decision: 'approved' });

When a procedure changes, every client type-checks against the new shape at compile time — there is no generated client to regenerate.

Plain HTTP

Non-TypeScript or external callers can use plain HTTP against /api/v1/** instead, with the same bearer-token rules:

curl http://localhost:3000/api/v1/tasks

curl -X POST http://localhost:3000/api/v1/tasks \
  -H "Authorization: Bearer $CONTROL_PLANE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"repository": "/path/to/repo", "feedback": "…"}'

The interactive reference at /api/v1/docs documents every route from the generated OpenAPI spec at /api/v1/openapi.json.

Authorization is identical on both transports

/rpc/** and /api/v1/** serve the exact same rpcRouter, so a token that may create tasks over RPC may create the same tasks over REST and vice versa. Reads are open; mutations fail closed — see Protect endpoints.

Copyright © 2026