Skip to main content
Browse the documentation

Tools and connections

A2A

Let other agents discover your published agents and hand them work over the Agent-to-Agent protocol.

The Agent-to-Agent protocol (A2A) lets one agent find another and give it a task, whatever platform each one runs on. Snaga speaks it so that your agents can take work from outside callers in a standard shape: a task goes in, the agent works on it as an ordinary run, and the caller reads back its status, its reply and any artifacts.

How it fits together

  • Discovery — a public agent card describes an agent: its name, what it can do (skills), where to send tasks and how to authenticate.
  • Tasks — a task wraps one run of the agent. It moves through submitted, working, input-required, and ends completed, canceled or failed.
  • Two ways in — a plain REST surface under /api/v1/a2a/tasks, and a JSON-RPC 2.0 endpoint at /api/v1/a2a for A2A clients.

Discovery: the agent card

curl "https://api.snaga.ai/.well-known/agent.json?agent_id=<agent_id>"

No key is needed. Only an agent that is published — public visibility with its public configuration enabled — has a card; any other agent answers 404, and unpublishing an agent takes its card down. Without agent_id the request is refused with 422.

The card carries name, description, version, protocol_version, capabilities (streaming, push_notifications, state_transition_history), skills, authentication and a url — the A2A endpoint. The card currently gives it as http://api.snaga.ai/api/v1/a2a; send your requests to https://api.snaga.ai/api/v1/a2a. Add format=oasf to get the same agent described as an OASF record instead.

Sending a task

curl -X POST https://api.snaga.ai/api/v1/a2a/tasks \
  -H "Authorization: Bearer $SNAGA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "agent_id": "<agent_id>",
    "messages": [
      {"role": "user", "parts": [{"type": "text", "text": "Summarise last week'\''s support tickets."}]}
    ]
  }'

Each message has a role (user or agent) and a non-empty list of parts. A part is text, data (a JSON object) or file (with name, mime_type and inline base64 data). At least one user part must carry input; otherwise the request is refused with 422 and nothing is created and nothing is charged. An unknown agent is 404, again before anything exists.

Following a task

curl https://api.snaga.ai/api/v1/a2a/tasks/<task_id> \
  -H "Authorization: Bearer $SNAGA_API_KEY"

The task is reconciled against its run before it is returned, so the status and the agent's reply are current. The answer holds status, the messages exchanged, any artifacts, and metadata.uarp_run_id, the run behind the task.

To be told rather than ask, open the event stream:

curl -N https://api.snaga.ai/api/v1/a2a/tasks/<task_id>/events \
  -H "Authorization: Bearer $SNAGA_API_KEY"

It is a Server-Sent Events stream of the task's status updates. The key is re-checked as the stream runs, so a revoked or suspended credential closes a stream that is already open. See Pagination and streaming for how to read it from a browser.

GET /api/v1/a2a/tasks lists the company's tasks newest first. It reads only limit (1–200, default 50) and offset; a ?cursor parameter is ignored. The answer carries has_more and a cursor equal to offset + limit — pass that value back as offset to get the next page.

Cancelling

curl -X POST https://api.snaga.ai/api/v1/a2a/tasks/<task_id>/cancel \
  -H "Authorization: Bearer $SNAGA_API_KEY"

Cancelling stops the run behind the task as well. A task that is already finished — or does not exist — answers 409, so a second cancel of the same task is a conflict, not a success.

The JSON-RPC endpoint

A2A clients usually speak JSON-RPC 2.0. POST /api/v1/a2a accepts:

MethodDoesKey scope
tasks/sendcreate a taskagents:write
tasks/sendSubscribecreate a task and return its events_urlagents:write
tasks/getread a taskagents:read
tasks/cancelcancel a taskagents:write
tasks/pushNotification/setset where updates are pushedagents:write
tasks/pushNotification/getread that settingagents:read

Answers — errors included — come back as a JSON-RPC envelope with HTTP 200. Messages are validated exactly as on the REST route; a refused list answers JSON-RPC error -32602 with the fields in error.data.errors.

curl -X POST https://api.snaga.ai/api/v1/a2a \
  -H "Authorization: Bearer $SNAGA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc": "2.0", "id": 1, "method": "tasks/get", "params": {"id": "<task_id>"}}'

Keys and scopes

Reading tasks needs a key with agents:read; creating and cancelling need agents:write and a developer role or higher. Each task is an ordinary run of the agent, so it counts against your run allowance like any other run.