# A2A endpoint

The service speaks A2A 1.0 (JSON-RPC 2.0 over HTTP) at `POST https://api.criptonlabs.com/a2a`. It is stateless and free in every payment mode: there is no task, no session and no authentication, and every call is answered synchronously with a `message`. Paid access stays on `/mcp/pro` and `/v1/pro/*` (see the payments guide).

## Call a skill

Send `SendMessage` with one `data` part `{"skill": "<tool name>", "arguments": {...}}`. The skill ids are the 16 MCP tool names: `xrpl_fee`, `xrpl_latest_ledger`, `xrpl_network_health`, `xrpl_orderbook`, `xrpl_slippage`, `xrpl_amm`, `xrpl_account_summary`, `xrpl_account_lines`, `xrpl_account_transactions`, `xrpl_token`, `xrpl_payment_readiness`, `xrpl_paths`, `solana_transfer_readiness`, `solana_token`, `solana_latest_slot` and `solana_network_health`. The `arguments` are validated with the same schemas as the REST query parameters and the MCP tool inputs.

```sh
curl -s https://api.criptonlabs.com/a2a \
  -H 'content-type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"SendMessage","params":{"message":{"messageId":"m1","role":"ROLE_USER","parts":[{"data":{"skill":"xrpl_fee","arguments":{}},"mediaType":"application/json"}]}}}'
```

The reply holds `result.message` with `role` `ROLE_AGENT`, a fresh `messageId` and one `data` part (`mediaType` `application/json`) with the same JSON body the REST endpoint returns, `meta` included. A message with only `text` parts is not an error: the reply is a help message listing every skill and the `data` part format, and nothing is fetched.

## Stateless by design

- `ListTasks` returns an empty list. `GetTask` and `CancelTask` answer -32001 (task not found).
- Streaming, task subscription and the extended agent card answer -32004 (unsupported operation); the push notification config methods answer -32003.
- Any other method answers -32601; for 0.3-style names such as `message/send` the error hint says to use `SendMessage`.

## Version

Send `A2A-Version: 1.0` as a header or as the `A2A-Version` query parameter. When it is absent, 1.0 is assumed. Any other value, including an empty one, answers -32009.

## Errors

Errors are JSON-RPC errors (HTTP 200). `error.data` is an array with one `google.rpc.ErrorInfo` (`@type`, `reason`, `domain`, `metadata`). For service failures `metadata` carries the RFC 9457 fields (`type`, `title`, `status`, `detail`), so the `type` URL is a Markdown page with the cause and the fix.

| Code | Meaning |
|---|---|
| -32700 | The body is not valid JSON |
| -32600 | Invalid request: not a JSON-RPC 2.0 envelope, a batch (arrays are not accepted), an `id` that is not a string, number or null, or a body over 64 KB |
| -32601 | Unknown method |
| -32602 | Invalid params: unknown skill, invalid `arguments`, a part that is not `{skill, arguments}`, or no parts |
| -32603 | The service failed (for example all upstream nodes are down) |
| -32005 | The message has only `raw` or `url` parts |
| -32009 | Unsupported A2A version |

## Limits

- `GET` and `HEAD` answer 405 with `Allow: POST`.
- Every request counts against the `mcp` rate tier and the expensive skills also against the `expensive` tier; over the limit the endpoint answers HTTP 429 with `Retry-After`. See the rate-limits guide.
- No CORS headers: call it from a server-side client.
- The agent card at `/.well-known/agent-card.json` lists this endpoint first.
