{"id":334,"date":"2026-08-30T05:02:16","date_gmt":"2026-08-30T05:02:16","guid":{"rendered":"https:\/\/www.akarnik.com\/blog\/how-a2a-protocol-works"},"modified":"2026-08-30T05:02:16","modified_gmt":"2026-08-30T05:02:16","slug":"how-a2a-protocol-works","status":"publish","type":"post","link":"https:\/\/www.akarnik.com\/blog\/how-a2a-protocol-works","title":{"rendered":"Google A2A Protocol: Agent Cards, Tasks &amp; Transport"},"content":{"rendered":"<p><em>Written by: Arjun Karnik, Growth Marketing Specialist<\/em><\/p>\n<h2 id=\"key-takeaways\">Key Takeaways<\/h2>\n<ul>\n<li>The A2A protocol is an open standard that lets autonomous AI agents discover capabilities, submit tasks, and exchange results across frameworks using JSON-RPC 2.0 over HTTP and Server-Sent Events.<\/li>\n<li>Every A2A-compliant agent publishes an Agent Card at a well-known URL following RFC 8615 so client agents can discover and evaluate it with a simple unauthenticated HTTP GET request.<\/li>\n<li>The protocol defines eight TaskState values grouped into Active, Interrupted, and Terminal states, and tasks become immutable after reaching a terminal state such as COMPLETED, FAILED, CANCELED, or REJECTED.<\/li>\n<li>A2A supports long-running tasks through streaming, push notifications, and asynchronous execution, while OAuth 2.0 and JWS-signed cards provide authentication and opaqueness guarantees.<\/li>\n<li>Learn more about implementing A2A in your own projects by <a href=\"https:\/\/www.akarnik.com\/demo\" target=\"_blank\">exploring the interactive A2A demo<\/a>.<\/li>\n<\/ul>\n<h2>Agent Cards: Schema, Discovery, and What to Look For<\/h2>\n<p>Agent Cards are JSON discovery files that let AI agents locate, evaluate, and delegate tasks to each other without hard-coded integrations. Every A2A-compliant agent publishes its Agent Card at a well-known URL following RFC 8615 so client agents can discover it through an unauthenticated HTTP GET request.<\/p>\n<p>Per a2a.proto v1.0.0, the A2A Agent Card requires exactly eight top-level fields: name, description, version, capabilities, supportedInterfaces, defaultInputModes, defaultOutputModes, and skills. Clients typically retrieve this card from the <a href=\"https:\/\/mnemoverse.com\/docs\/library\/a2a-agent-card\" target=\"_blank\" rel=\"noindex nofollow\">standard A2A Agent Card discovery endpoint<\/a> at <code>https:\/\/{agent-server-domain}\/.well-known\/agent-card.json<\/code>, which removes the need for out-of-band configuration, although registries, direct configuration, and older legacy paths remain available.<\/p>\n<p>The following minimal Agent Card shows the required eight-field structure and illustrates how OAuth 2.0 client credentials flow connects to the security schemes. Notice how the <code>security<\/code> array references scopes defined in <code>securitySchemes<\/code>:<\/p>\n<pre><code>{ \"name\": \"Invoice Agent\", \"description\": \"Processes and validates invoice documents.\", \"version\": \"1.0.0\", \"capabilities\": { \"streaming\": true, \"pushNotifications\": false, \"stateTransitionHistory\": true }, \"supportedInterfaces\": [ { \"url\": \"https:\/\/invoiceagent.example.com\/a2a\", \"protocolBinding\": \"JSONRPC\", \"protocolVersion\": \"1.0\" } ], \"defaultInputModes\": [\"text\/plain\", \"application\/json\"], \"defaultOutputModes\": [\"application\/json\"], \"skills\": [ { \"id\": \"validate-invoice\", \"name\": \"Validate Invoice\", \"description\": \"Validates invoice line items against purchase orders.\", \"tags\": [\"finance\", \"validation\"] } ], \"securitySchemes\": { \"oauth2\": { \"type\": \"oauth2\", \"flows\": { \"clientCredentials\": { \"tokenUrl\": \"https:\/\/auth.example.com\/token\", \"scopes\": { \"invoice:read\": \"Read invoice data\" } } } } }, \"security\": [{ \"oauth2\": [\"invoice:read\"] }] }<\/code><\/pre>\n<p>Servers hosting an Agent Card should return HTTP caching headers, including Cache-Control with max-age and an ETag derived from the card&#8217;s version field or content hash. Signed A2A Agent Cards attach a detached JWS, typically EdDSA over Ed25519, so clients can verify cryptographic provenance.<\/p>\n<h2>A2A Task Lifecycle: States and Client Responsibilities<\/h2>\n<p>Once a client agent discovers and evaluates a remote agent through its Agent Card, it submits work by creating a task. Understanding how tasks move between states helps you design retry logic, error handling, and long-running workflows. The A2A protocol defines eight TaskState enum values organized into Active states, Interrupted states, and Terminal states, and tasks become immutable after they reach a terminal state such as COMPLETED, FAILED, CANCELED, or REJECTED. Any follow-up work then requires a new Task ID within the same context.<\/p>\n<table>\n<thead>\n<tr>\n<th>State<\/th>\n<th>Category<\/th>\n<th>Definition<\/th>\n<th>Valid Next States<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>SUBMITTED<\/td>\n<td>Active<\/td>\n<td>Initial state when a task is created<\/td>\n<td>WORKING, REJECTED<\/td>\n<\/tr>\n<tr>\n<td>WORKING<\/td>\n<td>Active<\/td>\n<td>Agent actively processing the task<\/td>\n<td>COMPLETED, FAILED, INPUT_REQUIRED, AUTH_REQUIRED, CANCELED<\/td>\n<\/tr>\n<tr>\n<td>INPUT_REQUIRED<\/td>\n<td>Interrupted<\/td>\n<td>Agent needs client input and pauses execution<\/td>\n<td>WORKING, CANCELED<\/td>\n<\/tr>\n<tr>\n<td>AUTH_REQUIRED<\/td>\n<td>Interrupted<\/td>\n<td>Agent needs authentication credentials<\/td>\n<td>WORKING, CANCELED<\/td>\n<\/tr>\n<tr>\n<td>COMPLETED<\/td>\n<td>Terminal<\/td>\n<td>Task finished successfully<\/td>\n<td>None (immutable)<\/td>\n<\/tr>\n<tr>\n<td>FAILED<\/td>\n<td>Terminal<\/td>\n<td>Task encountered an error<\/td>\n<td>None (immutable)<\/td>\n<\/tr>\n<tr>\n<td>CANCELED<\/td>\n<td>Terminal<\/td>\n<td>Task was canceled by request<\/td>\n<td>None (immutable)<\/td>\n<\/tr>\n<tr>\n<td>REJECTED<\/td>\n<td>Terminal<\/td>\n<td>Task was rejected by agent before execution<\/td>\n<td>None (immutable)<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>State changes reach clients through TaskStatusUpdateEvent objects when they use SendStreamingMessage, SubscribeToTask, or push notifications.<\/p>\n<h2>JSON-RPC over HTTP: Core Transport for A2A<\/h2>\n<p>The A2A protocol implements JSON-RPC 2.0 over HTTP or HTTPS, and all requests are POSTed to the base URL declared in AgentInterface.url while the JSON-RPC method field selects the operation. The v1.0 protocol bindings support JSON-RPC 2.0 over HTTPS as the most common deployment, along with gRPC and HTTP+JSON or REST.<\/p>\n<p>The following example shows a verbatim SendMessage request payload:<\/p>\n<pre><code>POST \/a2a HTTP\/1.1 Host: invoiceagent.example.com Content-Type: application\/json Authorization: Bearer eyJhbGci... A2A-Version: 1.0 { \"jsonrpc\": \"2.0\", \"id\": \"req-7f3a1b\", \"method\": \"message\/send\", \"params\": { \"message\": { \"role\": \"user\", \"parts\": [ { \"kind\": \"text\", \"text\": \"Validate invoice INV-2026-0042 against PO-9981.\" } ] } } }<\/code><\/pre>\n<p>The following request shows the corresponding tasks\/get call for polling:<\/p>\n<pre><code>POST \/a2a HTTP\/1.1 Host: invoiceagent.example.com Content-Type: application\/json Authorization: Bearer eyJhbGci... { \"jsonrpc\": \"2.0\", \"id\": \"req-7f3a1c\", \"method\": \"tasks\/get\", \"params\": { \"taskId\": \"task-a1b2c3d4\" } }<\/code><\/pre>\n<p>A2A-specific JSON-RPC error codes include -32001 TaskNotFoundError, -32002 TaskNotCancelableError, -32003 PushNotificationNotSupportedError, -32004 UnsupportedOperationError, and -32005 ContentTypeNotSupportedError.<\/p>\n<h2>Server-Sent Events: Streaming Long-Running Tasks<\/h2>\n<p>The JSON-RPC transport above works well for short-lived requests, but many agent tasks run for minutes or hours. For these scenarios, A2A supports long-running tasks through streaming, push notifications, and asynchronous execution when agents or users are not continuously connected. For streaming operations, the client sends <code>Accept: text\/event-stream<\/code>, and the server responds with <code>Content-Type: text\/event-stream<\/code> and delivers events whose data field contains a complete JSON-RPC 2.0 response object.<\/p>\n<p>The following example shows a SendStreamingMessage request and its SSE response stream:<\/p>\n<pre><code>POST \/a2a HTTP\/1.1 Host: invoiceagent.example.com Content-Type: application\/json Accept: text\/event-stream Authorization: Bearer eyJhbGci... { \"jsonrpc\": \"2.0\", \"id\": \"req-stream-01\", \"method\": \"message\/stream\", \"params\": { \"message\": { \"role\": \"user\", \"parts\": [{ \"kind\": \"text\", \"text\": \"Validate invoice INV-2026-0042.\" }] } } } HTTP\/1.1 200 OK Content-Type: text\/event-stream Cache-Control: no-cache data: {\"jsonrpc\":\"2.0\",\"id\":\"req-stream-01\",\"result\":{\"kind\":\"statusUpdate\",\"taskId\":\"task-a1b2c3d4\",\"status\":{\"state\":\"submitted\"}}} data: {\"jsonrpc\":\"2.0\",\"id\":\"req-stream-01\",\"result\":{\"kind\":\"statusUpdate\",\"taskId\":\"task-a1b2c3d4\",\"status\":{\"state\":\"working\"}}} data: {\"jsonrpc\":\"2.0\",\"id\":\"req-stream-01\",\"result\":{\"kind\":\"artifactUpdate\",\"taskId\":\"task-a1b2c3d4\",\"artifact\":{\"parts\":[{\"kind\":\"text\",\"text\":\"Invoice INV-2026-0042 validated. 12 line items matched.\"}]}} data: {\"jsonrpc\":\"2.0\",\"id\":\"req-stream-01\",\"result\":{\"kind\":\"statusUpdate\",\"taskId\":\"task-a1b2c3d4\",\"status\":{\"state\":\"completed\"}}}<\/code><\/pre>\n<p>In A2A v1.0, stream closure at terminal state replaces the older <code>final: true<\/code> pattern used in v0.x. For long-running SSE streams, the server can emit periodic keep-alive comments (<code>: keep-alive<\/code>) controlled by WithTransportKeepAlive(interval), which prevents proxy or client timeouts.<\/p>\n<h2>Security, Authentication, and Opaqueness<\/h2>\n<p>OAuth 2.0 with client credentials flow is the most common choice for enterprise deployments because it integrates with existing identity infrastructure, supports narrow scoping at the skill level, and fits the A2A v1.0 security model.<\/p>\n<p>A2A AgentCard security schemes support five types: APIKeySecurityScheme, HTTPAuthSecurityScheme, OAuth2SecurityScheme, OpenIDConnectSecurityScheme, and MutualTLSSecurityScheme. Signed A2A Agent Cards, introduced in v1.0 on 12 March 2026, attach a detached JWS, typically using EdDSA over Ed25519, and the public key is resolved through a DID or a well-known URI.<\/p>\n<p>A2A supports opaqueness by design so agents do not expose internal memory, tools, or proprietary logic. This opaqueness comes from the architecture, because collaboration occurs only through standardized task delegation and Agent Cards, without any mechanism for one agent to inspect another agent&#8217;s internals. Since agents operate as autonomous peers rather than local tools, the A2A security and trust model focuses on verifying remote agents instead of assuming trust within a shared process boundary.<\/p>\n<p>A2A transport security uses HTTPS with TLS plus role-based access control that connects to existing enterprise identity systems. The protocol deliberately does not solve identity semantics and therefore inherits the identity weaknesses of the underlying infrastructure.<\/p>\n<h2>A2A and MCP: Architectural Trade-offs for Collaboration<\/h2>\n<p>MCP operates as Layer 1 for vertical agent-to-tool integration, and A2A operates as Layer 2 for horizontal agent-to-agent collaboration, so production multi-agent systems often use both. The table below highlights the main architectural trade-off: A2A&#8217;s stateful task model and built-in discovery enable cross-vendor delegation, while MCP&#8217;s stateless function-call pattern focuses on low-latency tool access within a single system boundary.<\/p>\n<table>\n<thead>\n<tr>\n<th>Dimension<\/th>\n<th>A2A<\/th>\n<th>MCP<\/th>\n<th>Source<\/th>\n<\/tr>\n<\/thead>\n<tbody>\n<tr>\n<td>Discovery<\/td>\n<td>Agent Cards at \/.well-known\/agent-card.json, no prior configuration required<\/td>\n<td>Explicitly configured endpoints, no built-in discovery<\/td>\n<td>Redis<\/td>\n<\/tr>\n<tr>\n<td>Task model<\/td>\n<td>Stateful, multi-step task lifecycle with states from submitted to terminal<\/td>\n<td>Stateless single-input single-output function call pattern<\/td>\n<td>SAP Community<\/td>\n<\/tr>\n<tr>\n<td>Transport<\/td>\n<td>JSON-RPC 2.0 over HTTP plus SSE streaming and push notifications<\/td>\n<td>JSON-RPC over stdio or Streamable HTTP<\/td>\n<td>Tyk<\/td>\n<\/tr>\n<tr>\n<td>Interoperability scope<\/td>\n<td>Peer-to-peer delegation of complete autonomous tasks between agents across vendors<\/td>\n<td>Connecting AI or LLM applications to external data sources, tools, and APIs<\/td>\n<td>AI Growth Agent<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>Enterprise architectures commonly use MCP for downward tool access and A2A for sideways agent coordination, because MCP decisions live inside one system owner&#8217;s budget while A2A decisions cross budgets, vendors, and legal entities.<\/p>\n<h2>Version 1.0.0: Current Spec and Extension Path<\/h2>\n<p>The current stable version of the Agent-to-Agent (A2A) protocol is <a href=\"https:\/\/a2a-protocol.org\/latest\/specification\/\" target=\"_blank\" rel=\"noindex nofollow\">v1.0.0, released under Linux Foundation governance with 150+ participating organizations including Google, Microsoft, Salesforce, and ServiceNow<\/a>, and builders targeting 2026 deployments should implement against this release.<\/p>\n<p>A2A v1.0.0 introduced signed Agent Cards using JSON Web Signature (JWS), an extension mechanism, and multi-transport support across JSON-RPC 2.0, gRPC, and HTTP+JSON or REST bindings.<\/p>\n<p>The canonical specification and schema files live in the a2a-project GitHub repository. The <a href=\"https:\/\/developers.googleblog.com\/developers-guide-to-ai-agent-protocols\" target=\"_blank\" rel=\"noindex nofollow\">Google Developer Blog published a practitioner guide to A2A and MCP in 2026<\/a> that covers runtime discovery and routing patterns. The core nouns defined in the A2A protocol, including AgentCard, AgentSkill, Task, Message, Part, Artifact, and Extension, are defined in Protocol Buffers and published as JSON Schema 2020-12, auto-generated from the proto files.<\/p>\n<p>The extension mechanism in v1.0 allows implementers to declare custom capabilities inside the AgentCapabilities.extensions array without breaking conformance. Each extension carries a URI, description, required flag, and params object, which enables forward-compatible capability negotiation between agents from different vendors.<\/p>\n<p>Evaluate the A2A v1.0.0 specification directly on the a2a-project GitHub repository to review normative schema definitions, conformance tests, and the full proto source.<\/p>\n<h2>Frequently Asked Questions<\/h2>\n<h3>How does task submission work in A2A?<\/h3>\n<p>Task submission in A2A begins after a client agent fetches and parses the remote agent&#8217;s Agent Card from <code>\/.well-known\/agent-card.json<\/code>. The client then sends an HTTP POST to the endpoint declared in the Agent Card&#8217;s supportedInterfaces array. The request body is a JSON-RPC 2.0 object with the method set to <code>message\/send<\/code> for non-streaming submission or <code>message\/stream<\/code> for streaming, and the params object contains a Message with a role field and a parts array holding the content.<\/p>\n<p>The server creates a Task object, assigns it a unique taskId and contextId, and returns either the Task immediately or a streaming SSE connection. The task progresses through the eight defined states, and clients poll for updates using <code>tasks\/get<\/code> with the taskId or subscribe to real-time updates through SSE using <code>tasks\/resubscribe<\/code>. When the task reaches a terminal state, it follows the immutability rule described in the Task Lifecycle section, and any follow-up work uses a new task that shares the same contextId and references the original taskId in the referenceTaskIds field of the new Message.<\/p>\n<h3>What is the exact Agent Card discovery endpoint?<\/h3>\n<p>The canonical Agent Card discovery endpoint is <code>https:\/\/{agent-server-domain}\/.well-known\/agent-card.json<\/code>, defined by IETF RFC 8615 and described in detail earlier in this article. This path follows the same well-known URI pattern used by OAuth 2.0 metadata and WebFinger, which means no out-of-band configuration or platform-specific catalog is required. The endpoint must return HTTP 200 with a Content-Type of either <code>application\/a2a+json<\/code> or <code>application\/json<\/code>.<\/p>\n<p>The response is a JSON object containing the eight required top-level fields: name, description, version, capabilities, supportedInterfaces, defaultInputModes, defaultOutputModes, and skills. Servers should include standard HTTP caching headers such as Cache-Control with max-age and an ETag derived from the card&#8217;s version field or content hash so clients can use conditional requests with If-None-Match. When the capabilities object declares <code>extendedAgentCard: true<\/code>, authenticated clients may call the GetExtendedAgentCard RPC to retrieve additional private skills or metadata not present in the public card. Signed cards include a signatures array of JWS objects that clients can verify after canonicalizing the card per RFC 8785.<\/p>\n<h3>How does A2A differ from MCP in agent collaboration?<\/h3>\n<p>A2A and MCP address different layers of the agent stack and work best together rather than as direct alternatives. <a href=\"https:\/\/en.wikipedia.org\/wiki\/Model_Context_Protocol\" target=\"_blank\" rel=\"noindex nofollow\">MCP, introduced by Anthropic in November 2024, standardizes how a single agent connects downward to tools, databases, files, and APIs using a client-server model, and it became stateless at the protocol layer after a July 2026 revision.<\/a> Its core primitives are tools, which are invokable functions with JSON schemas, resources, which are static or dynamic data entities, and prompts, which are templated guidance.<\/p>\n<p>A2A, released by Google in April 2025, standardizes how one agent reaches sideways to another autonomous agent. Its core primitives are tasks, messages, artifacts, and Agent Cards. In practice, MCP gives an agent access to its tools, while A2A lets two agents delegate work to each other across vendor and framework boundaries.<\/p>\n<p>A2A tasks are stateful objects with an eight-state lifecycle that supports long-running, multi-turn, human-in-the-loop workflows that can run for hours or days. MCP interactions follow a stateless single-input single-output pattern. A2A also provides built-in discovery through Agent Cards at a well-known URI, whereas MCP requires explicitly configured endpoints. In enterprise architectures, MCP handles downward tool access within a single system owner&#8217;s boundary, and A2A handles sideways coordination that crosses vendor, budget, and legal entity lines.<\/p>\n<h2>Conclusion<\/h2>\n<p>The Agent-to-Agent (A2A) protocol combines discovery, stateful tasks, streaming, and security into a practical foundation for cross-vendor agent interoperability. Agent Cards at a well-known RFC 8615 URI, an eight-field JSON schema that declares identity and skills, an eight-state task lifecycle with strict terminal immutability, JSON-RPC 2.0 over HTTP as the primary transport, SSE streaming for real-time task updates, and OAuth 2.0 plus JWS-signed cards for authentication and opaqueness all work together to support production multi-agent systems under Linux Foundation governance with v1.0.0 and 150+ participating organizations.<\/p>\n<p>Implementers evaluating A2A for production deployments should review the full proto definitions, conformance tests, and JSON Schema files before committing to an integration path. Evaluate the A2A v1.0.0 specification on the a2a-project GitHub repository to confirm normative schemas, task lifecycle definitions, and transport binding conformance for your implementation.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Master the A2A protocol spec: Agent Cards, task lifecycle, JSON-RPC, SSE streaming &amp; MCP trade-offs. Get expert clarity with Arjun Karnik.<\/p>\n","protected":false},"author":118,"featured_media":333,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-334","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/www.akarnik.com\/blog\/wp-json\/wp\/v2\/posts\/334","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.akarnik.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.akarnik.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"replies":[{"embeddable":true,"href":"https:\/\/www.akarnik.com\/blog\/wp-json\/wp\/v2\/comments?post=334"}],"version-history":[{"count":0,"href":"https:\/\/www.akarnik.com\/blog\/wp-json\/wp\/v2\/posts\/334\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.akarnik.com\/blog\/wp-json\/wp\/v2\/media\/333"}],"wp:attachment":[{"href":"https:\/\/www.akarnik.com\/blog\/wp-json\/wp\/v2\/media?parent=334"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.akarnik.com\/blog\/wp-json\/wp\/v2\/categories?post=334"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.akarnik.com\/blog\/wp-json\/wp\/v2\/tags?post=334"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}