A2A's Transport Layer: HTTP, SSE, and JSON-RPC 2.0
A2A is intentionally boring at the wire level.
Search across all documentation pages
A2A is intentionally boring at the wire level.
It reuses HTTP for reachability, JSON-RPC 2.0 for request/response framing, and Server-Sent Events (SSE) (or binding-equivalent streams) for incremental task updates.
The interesting part is the agent data model (tasks, messages, parts, artifacts) carried on top of those standards.
A2A's design goals call out reuse of familiar enterprise web technology:
| Building block | Role in A2A |
|---|---|
| HTTP(S) | Ubiquitous transport, auth middleware, TLS |
| JSON-RPC 2.0 | Method name + params + correlated id + error object |
| SSE | One-way server → client event stream for task progress |
| Webhooks (push) | Server → client HTTP callbacks when the client cannot keep a stream open |
That is the opposite of a new binary agent bus. It is closer to "JSON APIs done with a shared agent vocabulary."
Modern A2A specs often describe layers:
Layer 1 Canonical data model (Task, Message, Part, Artifact, ...)
Layer 2 Abstract operations (send message, stream, get task, cancel, ...)
Layer 3 Protocol bindings (JSON-RPC, and possibly others)Implications for implementers:
| Role | Wire behavior |
|---|---|
| A2A client | Discovers Agent Card; sends JSON-RPC requests; optionally opens SSE; may register push URLs |
| A2A server | Serves card; accepts messages; creates/updates tasks; emits stream events or push payloads |
Client Server
| GET agent card |
|------------------------->|
| POST JSON-RPC message |
|------------------------->|
| 200 result: Task |
|<-------------------------|
| GET/POST stream (SSE) |
|------------------------->|
| event: status/artifact |
|<=========================|A typical request shape:
{
"jsonrpc": "2.0",
"id": "corr-123",
"method": "message/send",
"params": {
"message": {
"role": "user",
"messageId": "m-1",
"parts": [{ "kind": "text", "text": "Summarize ticket 4421" }]
}
}
}A typical success response:
{
"jsonrpc": "2.0",
"id": "corr-123",
"result": {
"id": "task-9",
"status": { "state": "working" }
}
}A typical error response:
{
"jsonrpc": "2.0",
"id": "corr-123",
"error": {
"code": -32000,
"message": "Content type not supported"
}
}Rules:
id (string or number per JSON-RPC rules your stack allows).error.params against the current schema before hitting production peers.Use plain POST when:
The server may return:
| Result type | Meaning |
|---|---|
| Message | Simple turn completed without long task tracking |
| Task | Work accepted; poll, stream, or wait for push for completion |
Long-running enterprise agents should prefer Task semantics even if the first response is fast.
When the card advertises streaming, clients open a stream for:
working → completed / failed / ...)SSE characteristics that matter in production:
| Topic | Guidance |
|---|---|
| Proxies | Disable or extend idle timeouts; allow text/event-stream |
| Auth | Same identity as the RPC call (header/cookie/mTLS) |
| Backpressure | Servers should bound event rates; clients should apply read deadlines |
| Reconnect | Decide whether task id allows resuming or requires replay from tasks/get-style reads |
| Payload | Each event often carries a full JSON object in data: lines |
data: {"taskId":"task-9","status":{"state":"working"}}
data: {"taskId":"task-9","artifact":{"parts":[{"kind":"text","text":"..."}]}}Exact event schemas are versioned; verify at build.
Streaming assumes the client can keep a connection.
Push patterns cover:
Typical flow:
Security: webhooks must verify sender authenticity and avoid open relay abuse.
Names differ by binding and version. Conceptually you need:
| Operation | Purpose |
|---|---|
| Send message | Start or continue work |
| Send streaming message | Same with SSE updates |
| Get task | Fetch current task snapshot |
| Cancel task | Best-effort stop |
| Configure push | Register/update webhook settings |
| Fetch authenticated card | Optional richer discovery after auth |
Prefer official SDKs over hand-rolled method strings once you leave tutorials.
| MCP | A2A (common path) | |
|---|---|---|
| Local default | stdio subprocess | Less common; agents are usually network services |
| Remote | Streamable HTTP (legacy HTTP+SSE) | HTTP + JSON-RPC, SSE for streams |
| Primary unit | tools/resources/prompts | tasks/messages/artifacts |
| Opacity | Host sees tool schemas | Peer hides tools; shows skills |
See stdio vs HTTP vs SSE: MCP's Transport Options.
| Concern | Practice |
|---|---|
| Client RPC timeout | Shorter than stream lifetime; longer than p99 send ack |
| Stream idle timeout | Heartbeats or periodic status events |
| Retries | Safe on pure reads; careful on send unless message ids make retries idempotent |
| Cancel | Always available for runaway cost |
| Exactly-once | Not free; design for at-least-once + dedupe keys |
Because A2A rides HTTP, you can place:
message/send equivalentsDo not forget that SSE is not a normal short REST call. Configure the path differently from CRUD APIs.
Some specification lines describe additional bindings (for example gRPC or HTTP+JSON/REST-style mappings) while keeping the same canonical model.
Guidance:
| Mode | Strength | Weakness | Best fit |
|---|---|---|---|
| Sync RPC only | Simple ops | Weak for long jobs | Quick Q&A agents |
| RPC + poll task | Easy through strict proxies | Laggy UX; more load | Enterprise networks that ban streams |
| RPC + SSE | Real-time progress | Proxy/timeout complexity | Interactive multi-minute tasks |
| RPC + push webhook | Works for disconnected clients | Webhook security & reachability | Overnight jobs, mobile backends |
error or failed task states.No. Advertise streaming only if implemented. Clients should read the Agent Card capabilities first.
It is the widely documented binding. Specs may add others; verify the profile your ecosystem standardizes on.
Bound them in your gateway. Prefer file references for large binaries instead of huge inline parts.
Yes, like other HTTP services, but sticky sessions or shared task stores may be required for multi-turn tasks and open streams.
Propagate W3C traceparent (or your standard) on RPC and webhook calls so client and remote agent share a trace.
Cards tell clients the endpoint URL and whether streaming/push exist before the first RPC. See Agent Cards.
Prefer official SDKs. Hand-rolled clients are fine for learning and contract tests.
Idle timeouts on streams, auth mismatch between card and gateway, and clients ignoring non-terminal task states.
A2A targets networked agents. Local stdio is MCP's comfort zone more than A2A's.
Clients call a cancel operation with the task id; servers best-effort stop work and mark the task canceled.
Not for the common A2A profile. SSE covers server → client streaming without full duplex sockets.
Hands-on: Agent-to-Agent Protocols Basics. Cross-cloud notes: Cross-Cloud Agent Interoperability.
Stack versions: Pins from the category manifest (verify at build): OpenRouter (~315+ models, July 2026 pricing/fees); LangGraph 1.0+; CrewAI 1.14+; Microsoft Agent Framework 1.0; Vercel AI SDK 6; Pydantic AI (latest); LlamaIndex (latest); OpenAI Agents SDK (latest + MCP); MCP (Linux Foundation governance); A2A (HTTP+SSE+JSON-RPC 2.0); Solana
@solana/web3.js+@solana/spl-token.
Reviewed by Chris St. John·Last updated Jul 16, 2026