Skip to main content

Agent API (A2A)

V2 only — invite-only edition. This is part of AI Partner V2 and is not in the open-source V1 you self-host from the Quick Start. V2 is available now, by invite. See V1 vs V2.

What it is

AI Partner can act as a callable agent for other agents and applications, speaking the A2A protocol: a public discovery card, a JSON-RPC endpoint, and SSE streaming for live progress. An external developer's agent can delegate a goal ("research X and produce a report") and get back the result — executed with AI Partner's full toolset (web, documents, code sandbox, knowledge base).

Every consumer runs as its own service account: isolated workspace, isolated knowledge, separate usage metering, and a per-consumer concurrency cap.

Enabling it (admin)

Admin Console → Agent Access → toggle Inbound Agent API on, then create a consumer (New Consumer) — this mints the API key (shown once). Toggling is also available via PATCH /api/admin/agent-access.

Discovery

The agent card is public (no auth):

curl https://your-server/.well-known/agent.json

It advertises the endpoint URL, capabilities (streaming), and the security scheme (apiKeyAuth via X-API-Key).

Authentication

Every call to /api/a2a requires the consumer's API key:

X-API-Key: aip_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Missing or invalid key → JSON-RPC error -32002 Unauthorized (HTTP 401). When the feature is disabled → -32000.

Running a task

Fire-and-forget: message/send

curl -X POST https://your-server/api/a2a \
-H "Content-Type: application/json" \
-H "X-API-Key: aip_..." \
-d '{
"jsonrpc": "2.0", "id": 1, "method": "message/send",
"params": { "message": { "parts": [{ "text": "Research the top 3 CRM tools and write a comparison" }] } }
}'
# → { "jsonrpc":"2.0", "id":1, "result": { "id": "<taskId>", "status": { "state": "running" } } }

Poll: tasks/get

-d '{ "jsonrpc":"2.0", "id":2, "method":"tasks/get", "params": { "id": "<taskId>" } }'
# running → { "result": { "id":"...", "status": { "state": "running" } } }
# done → { "result": { "id":"...", "status": { "state": "completed" }, "artifacts":[{ "parts":[{ "text":"..." }] }] } }

Tasks are scoped to the calling key — one consumer can never read another's tasks (-32001 Task not found).

Stream: message/stream

Same request shape with "method": "message/stream" — the response is an SSE stream of TaskStatusUpdateEvent (running, with reasoning snippets) and a final TaskArtifactUpdateEvent with the result. Dropping the connection cancels the goal. tasks/resubscribe re-attaches to a still-running task's stream.

Limits & metering

  • 3 concurrent goals per consumer (the standard per-user cap); additional sends while at the cap are rejected.
  • Global API rate limit applies (500 requests/min per IP).
  • Every LLM call is metered to the consumer; admins see per-consumer cost in Agent Access and can export a monthly statement (JSON/CSV) for invoicing: GET /api/admin/agent-consumers/:id/statement?period=monthly&format=csv.

Errors

CodeMeaning
-32000Inbound A2A is disabled on this server
-32002Unauthorized — missing/invalid X-API-Key
-32001Task not found (or not yours)
-32602Invalid params (e.g. missing goal text)
-32601Unknown method