A2A Protocol Architecture: A Technical Deep Dive

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.

A2A Protocol Architecture: A Technical Deep Dive cover

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.json and 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_SUBMITTED through TASK_STATE_WORKING to 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

TASK_STATE_SUBMITTED

The agent acknowledged the task and assigned it an id

Whether any work has started

TASK_STATE_WORKING

The agent is processing

How long it will stay there, or whether it is stuck

TASK_STATE_INPUT_REQUIRED

The agent paused and needs more input on the same taskId

Who is expected to answer, or by when

TASK_STATE_AUTH_REQUIRED

The agent needs a credential the client must supply

Which downstream system it is reaching for

TASK_STATE_COMPLETED

Terminal success, results are in artifacts

Whether the caller consumed them

TASK_STATE_FAILED

Terminal failure

Whether a retry is safe

TASK_STATE_CANCELED

Terminal, cancellation took effect

What partial work already ran

TASK_STATE_REJECTED

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

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.

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.