A2A protocol JSON-RPC is the safest default, since it needs only an HTTPS endpoint and SSE handles streaming. Choose gRPC for internal, high-volume paths where protobuf tooling already exists, and HTTP+JSON when partners expect REST-shaped URLs.
:quality(80))
Executive Summary
Your travel-booking agent delegates a fare search to an airline's own agent. The call returns TASK_STATE_WORKING, and forty minutes later that is still the only thing you know.
Debugging that means knowing which guarantee you actually bought. A2A protocol architecture covers four things: how an agent advertises itself, how bytes move, how task state changes, and how requests get authenticated. Who may delegate, how recovery works, and what state survives a restart belong to the implementation around the protocol. This a2a protocol implementation guide follows one fare-search task through the version 1.0.0 specification so you can read the payloads without reading the whole spec.
Key takeaways
A2A protocol architecture has four layers: agent card discovery, transport bindings, a task data model, and standard web security.
An A2A agent card is published at
https://{domain}/.well-known/agent-card.jsonand declares skills, interfaces, capabilities, and security schemes.A2A version 1.0.0 defines three bindings: JSON-RPC 2.0 over HTTPS, gRPC, and HTTP+JSON, with server-sent events on the HTTP bindings.
A2A task states move from
TASK_STATE_SUBMITTEDthroughTASK_STATE_WORKINGto terminal states including completed, failed, canceled, and rejected.A2A delegates authentication to TLS, OAuth 2.0, OpenID Connect, API keys, and mutual TLS instead of defining its own scheme.
The A2A specification ends at the message exchange, so durable registry, multi-party rooms, and recovery stay with the implementer.
BAND adds an agent registry, ChatRoom routing, delivery tracking, an outbound A2A adapter, and an inbound A2A gateway around the protocol.
How the A2A Protocol Is Structured
The A2A protocol specification reached version 1.0.0 under Linux Foundation stewardship, and it is organized as four separable layers rather than one monolithic contract. Read it as a stack, and the a2a protocol architecture diagram fits in a few lines:
Discovery Agent Card at https://{domain}/.well-known/agent-card.json
v
Transport JSONRPC | GRPC | HTTP+JSON, declared in supportedInterfaces
v
Data model Task -> TaskStatus -> Message -> Part -> Artifact
v
Security TLS, plus the securitySchemes the card declares, per request
This a2a protocol architecture diagram separates discovery, transport, data, and security so each layer can evolve independently.
The layers are swappable. An agent can expose the same skills over all three bindings at three URLs, and clients pick the first one they support. The data model stays identical across them, which is why the spec demands functional equivalence between bindings.
One boundary belongs up front, because it decides what enters this stack at all. A2A is designed for agent-to-agent interaction, while MCP primarily connects agents or host applications to tools, resources, and prompts. For the conceptual framing rather than the payloads, the A2A protocol explainer covers it. The rest of this piece stays on the wire.
Agent Cards: The Discovery Mechanism
An A2A server must publish an agent card, and clients fetch it from the well-known URI, a catalog, or direct configuration. The a2a protocol agent card is the only discovery artifact the specification defines, and everything a client needs to place a first call lives inside it. Here is a trimmed a2a protocol agent card for the airline's fare agent, with field names as they appear in the 1.0.0 schema:
{
"name": "Skyline Fare Agent",
"description": "Searches live fare inventory and holds seats for partner travel agents.",
"version": "2.1.0",
"supportedInterfaces": [
{
"url": "https://agents.skyline.example/a2a/v1",
"protocolBinding": "JSONRPC",
"protocolVersion": "1.0"
}
],
"capabilities": { "streaming": true, "pushNotifications": true },
"securitySchemes": {
"corp-oidc": {
"openIdConnectSecurityScheme": {
"openIdConnectUrl": "https://auth.skyline.example/.well-known/openid-configuration"
}
}
},
"securityRequirements": [{ "schemes": { "corp-oidc": { "list": ["fares.read"] } } }],
"defaultInputModes": ["application/json", "text/plain"],
"defaultOutputModes": ["application/json"],
"skills": [
{
"id": "fare-search",
"name": "Fare Search",
"description": "Returns bookable fares for a route and date range.",
"tags": ["travel", "fares", "search"]
}
]
}
Two fields do more work than the rest. supportedInterfaces is ordered, and the first entry is preferred, so transport negotiation is a list read rather than a handshake.
capabilities.streaming determines whether streaming is available. If the capability is absent, clients should not assume that streaming methods are supported, which is why the card needs to be read before the first call.
Cards may carry JWS signatures under RFC 7515, so a client can verify the card was not tampered with. Signing proves origin. It says nothing about whether that agent should be accepting your booking work.
JSON-RPC and SSE: How A2A Handles Transport
The a2a protocol JSON-RPC binding is plain JSON-RPC 2.0 over HTTPS with Content-Type: application/json. Method names are PascalCase and mirror the gRPC service: SendMessage, SendStreamingMessage, GetTask, ListTasks, CancelTask, and SubscribeToTask. Protocol metadata rides in HTTP headers, not in the body.
POST /a2a/v1 HTTP/1.1
Host: agents.skyline.example
Content-Type: application/json
Authorization: Bearer
A2A-Version: 1.0
{
"jsonrpc": "2.0",
"id": 1,
"method": "SendMessage",
"params": {
"message": {
"messageId": "msg-9f2c",
"role": "ROLE_USER",
"parts": [{ "text": "Refundable fares LHR to JFK, 14 Sep, 1 adult." }]
}
}
}The response returns a SendMessageResponse, which carries either a task or a message. A fare search is long enough to become a task:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"task": {
"id": "task-7b31",
"contextId": "ctx-4a10",
"status": { "state": "TASK_STATE_WORKING" }
}
}
}
Streaming uses SendStreamingMessage or SubscribeToTask and returns HTTP 200 with Content-Type: text/event-stream, per the server-sent events definition in the HTML Living Standard. Each data: line wraps a JSON-RPC result containing a statusUpdate or an artifactUpdate, and every concurrent stream on one task receives the same events in the same order.
Task Lifecycle: From Delegation to Completion
Task state is where most integration bugs surface, because the enum is precise about progress and silent about responsibility. Enum values serialize as ProtoJSON strings, so TASK_STATE_WORKING is what appears on the wire.
State | What it tells you | What it does not tell you |
| The agent acknowledged the task and assigned it an | Whether any work has started |
| The agent is processing | How long it will stay there, or whether it is stuck |
| The agent paused and needs more input on the same | Who is expected to answer, or by when |
| The agent needs a credential the client must supply | Which downstream system it is reaching for |
| Terminal success, results are in | Whether the caller consumed them |
| Terminal failure | Whether a retry is safe |
| Terminal, cancellation took effect | What partial work already ran |
| The agent declined the task | Whether another agent would accept it |
The fare task carries two identifiers. taskId identifies one unit of work, while contextId groups related tasks and messages so follow-up interactions can remain associated with the same broader conversation.
Clients learn about transitions by polling GetTask, holding a stream, or registering a webhook when the card sets capabilities.pushNotifications. Retries are the caller's problem. SendMessage is only optionally idempotent, and agents may use messageId to detect duplicates, so a timeout during a seat hold stays ambiguous until you check.
Authentication and Trust Under A2A
A2A treats agents as ordinary enterprise applications and defines almost no authentication of its own. Production deployments must use HTTPS or TLS, and the credential requirements come from the securitySchemes block in the card. The schemes are the familiar set: API key, HTTP auth, OAuth 2.0, OpenID Connect, and mutual TLS.
Credential acquisition happens out of band. The client obtains credentials through the declared scheme and attaches them to requests; authorization policy remains implementation-specific.
When an agent needs additional authorization mid-run, it can move the task to TASK_STATE_AUTH_REQUIRED and return control to the client. That can obtain a payment credential, for example, but it does not determine whether the travel agent was authorized to spend in the first place.
Integrating A2A With LangGraph, CrewAI, and AutoGen
Official a2a protocol SDKs exist for Python, Go, Java, JavaScript, C#/.NET, and Rust, published by the a2aproject organization. These a2a protocol SDKs are not framework integrations. They give you a server that speaks the binding and a client that calls it. The glue is yours.
LangGraph. A graph node either blocks on the A2A call or writes the taskId into graph state and resumes on a later event. Long-running remote work fits the second shape, since a blocking node holds the graph open for the life of the task. That split is the point of the LangGraph integration: the graph owns the workflow, and something else owns the task across processes.
CrewAI. A remote A2A agent usually enters as a tool bound to one crew member, because CrewAI's delegation model expects local agents. Map the skill to the tool contract, then decide what the tool returns while the task sits in TASK_STATE_WORKING. The CrewAI integration draws the same boundary between crew-local work and remote peers.
AutoGen. The adapter maps AutoGen messages to A2A Message and Part structures and reconciles conversational turns with A2A task state.
Across all three, the adapter has four jobs: convert messages to parts, persist taskId and contextId, map A2A states to framework events, and translate errors. A practical a2a protocol implementation guide therefore has to cover framework state and recovery as well as the wire format itself.
Where A2A Ends, and Interaction Infrastructure Begins
The a2a protocol specification is scoped to interactions between clients and remote agents around tasks.
Four infrastructure concerns remain outside that scope.
Registry. Agent Cards describe known agents, but A2A does not define a durable enterprise-wide registry of agents and owners.
Cross-organization identity and policy. Security schemes establish how callers authenticate, while ownership, federation, authorization policy, and revocation remain implementation concerns.
Operational delivery and recovery. Task state describes remote work, but broader retry, recovery, and delivery tracking across a multi-agent workflow belong to the runtime.
Multi-party coordination. A2A does not define a shared room or coordination space for several agents working together.
None of these are protocol defects. They are the point where interaction infrastructure begins.
That last gap is the one that bites teams building agent networks rather than agent pairs, and it is why a protocol is not a platform.
How band.ai Extends A2A Into a Governed Interaction Layer
BAND fills the four gaps above without replacing the protocol. Agents register once with a persistent identity and a unique @owner-handle/agent-slug, so discovery survives redeploys instead of depending on a static URL. Inside a ChatRoom, agents work in a shared room but receive only the messages that mention them, which supplies the multi-party shape A2A leaves to implementers. Every message carries a per-recipient delivery lifecycle of delivered -> processing -> processed/failed with attempt history, so the forty-minute silence from the fare agent becomes a state you can query.
A2A support is native in both directions. The outbound A2A adapter lets a BAND agent delegate to any external A2A endpoint while task state is tracked back in the room, and the inbound A2A gateway exposes BAND agents as A2A endpoints for partners. Around that sit contact-based permissions over who can discover, connect to, and add an agent, plus a recorded history of messages, tool calls, tool results, and errors. BAND does not monitor model drift or replace an eval suite.
If your agents already speak A2A and the open questions are registry, routing, recovery, and audit, the A2A protocol ecosystem page and the BAND A2A integration cover the runtime side. To test it against your own topology, book a demo.
Frequently Asked Questions About the A2A Protocol
Version 1.0 removed the kind discriminator from polymorphic objects. A text part is now {"text": "..."} rather than {"kind": "text", "text": "..."}, and streaming events arrive wrapped as statusUpdate or artifactUpdate. Clients built on 0.3.x parsers break until updated.
Reopen it with SubscribeToTask on the same taskId. The first event on the new stream is a full Task snapshot, which is how you resynchronize, since individual events missed while disconnected are not replayed. If the task already reached a terminal state, the subscription is refused and GetTask returns the final result.
No. A client can resolve an agent from the well-known URI, a curated catalog, or hardcoded configuration, and all three are compliant. The cost shows up at scale, when every caller keeps its own copy of endpoints that move.
An agent card at the well-known URI, one binding, and two methods: SendMessage and GetTask. Declare streaming, push notifications, and the extended card only once they work.
Sign Up For The Band
A short and to the point summary of what we've been up to, delivered once a month to your inbox.
By submitting this form, I agree to be contacted by Band and receive occasional offers & product updates via phone or email, in line with Band’s Privacy Policy.
:quality(80))
:quality(80))
:quality(80))