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
| Code | Meaning |
|---|---|
-32000 | Inbound A2A is disabled on this server |
-32002 | Unauthorized — missing/invalid X-API-Key |
-32001 | Task not found (or not yours) |
-32602 | Invalid params (e.g. missing goal text) |
-32601 | Unknown method |