Agent2Agent (A2A) Protocol Official Specification¶
{% macro render_spec_tabs(region_tag) %}
{% endmacro %}
See Release Notes for changes made between versions.
1. Introduction¶
The Agent2Agent (A2A) Protocol is an open standard designed to facilitate communication and interoperability between independent, potentially opaque AI agent systems. In an ecosystem where agents might be built using different frameworks, languages, or by different vendors, A2A provides a common language and interaction model.
This document provides the detailed technical specification for the A2A protocol. Its primary goal is to enable agents to:
- Discover each other's capabilities.
- Negotiate interaction modalities (text, files, structured data).
- Manage collaborative tasks.
- Securely exchange information to achieve user goals without needing access to each other's internal state, memory, or tools.
1.1. Key Goals of A2A¶
- Interoperability: Bridge the communication gap between disparate agentic systems.
- Collaboration: Enable agents to delegate tasks, exchange context, and work together on complex user requests.
- Discovery: Allow agents to dynamically find and understand the capabilities of other agents.
- Flexibility: Support various interaction modes including synchronous request/response, streaming for real-time updates, and asynchronous push notifications for long-running tasks.
- Security: Facilitate secure communication patterns suitable for enterprise environments, relying on standard web security practices.
- Asynchronicity: Natively support long-running tasks and interactions that may involve human-in-the-loop scenarios.
1.2. Guiding Principles¶
- Simple: Reuse existing, well-understood standards (HTTP, JSON-RPC 2.0, Server-Sent Events).
- Enterprise Ready: Address authentication, authorization, security, privacy, tracing, and monitoring by aligning with established enterprise practices.
- Async First: Designed for (potentially very) long-running tasks and human-in-the-loop interactions.
- Modality Agnostic: Support exchange of diverse content types including text, audio/video (via file references), structured data/forms, and potentially embedded UI components (e.g., iframes referenced in parts).
- Opaque Execution: Agents collaborate based on declared capabilities and exchanged information, without needing to share their internal thoughts, plans, or tool implementations.
For a broader understanding of A2A's purpose and benefits, see What is A2A?.
2. Core Concepts Summary¶
A2A revolves around several key concepts. For detailed explanations, please refer to the Key Concepts guide.
- A2A Client: An application or agent that initiates requests to an A2A Server on behalf of a user or another system.
- A2A Server (Remote Agent): An agent or agentic system that exposes an A2A-compliant HTTP endpoint, processing tasks and providing responses.
- Agent Card: A JSON metadata document published by an A2A Server, describing its identity, capabilities, skills, service endpoint, and authentication requirements.
- Message: A communication turn between a client and a remote agent, having a
role("user" or "agent") and containing one or moreParts. - Task: The fundamental unit of work managed by A2A, identified by a unique ID. Tasks are stateful and progress through a defined lifecycle.
- Part: The smallest unit of content within a Message or Artifact (e.g.,
TextPart,FilePart,DataPart). - Artifact: An output (e.g., a document, image, structured data) generated by the agent as a result of a task, composed of
Parts. - Streaming (SSE): Real-time, incremental updates for tasks (status changes, artifact chunks) delivered via Server-Sent Events.
- Push Notifications: Asynchronous task updates delivered via server-initiated HTTP POST requests to a client-provided webhook URL, for long-running or disconnected scenarios.
- Context: An optional, server-generated identifier to logically group related tasks.
- Extension: A mechanism for agents to provide additional functionality or data beyond the core A2A specification.
3. Transport and Format¶
3.1. Transport Layer Requirements¶
A2A supports multiple transport protocols, all operating over HTTP(S). Agents have flexibility in choosing which transport protocols to implement based on their specific requirements and use cases:
- A2A communication MUST occur over HTTP(S).
- The A2A Server exposes its service at one or more URLs defined in its
AgentCard. - Agents MUST implement at least one of the three core transport protocols defined in this specification.
- All supported transport protocols are considered equal in status and capability.
3.2. Supported Transport Protocols¶
A2A defines three core transport protocols. A2A-compliant agents SHOULD implement at least one of these transport protocols. They MAY be compliant implementing a transport extension as defined in 3.2.4 All three protocols are considered equal in status, and agents may choose to implement any combination of them based on their requirements.
3.2.1. JSON-RPC 2.0 Transport¶
Agents MAY support JSON-RPC 2.0 transport. If implemented, it MUST conform to these requirements:
- The primary data format is JSON-RPC 2.0 for all requests and responses (excluding SSE stream wrapper).
- Client requests and server responses MUST adhere to the JSON-RPC 2.0 specification.
- The
Content-Typeheader for HTTP requests and responses containing JSON-RPC payloads MUST beapplication/json. - Method names follow the pattern
{category}/{action}(e.g.,"message/send","tasks/get").
3.2.2. gRPC Transport¶
Agents MAY support gRPC transport. If implemented, it MUST conform to these requirements:
- Protocol Definition: MUST use the normative Protocol Buffers definition in
specification/grpc/a2a.proto. - Message Serialization: MUST use Protocol Buffers version 3 for message serialization.
- Service Definition: MUST implement the
A2AServicegRPC service as defined in the proto file. - Method Coverage: MUST provide all methods with functionally equivalent behavior to other supported transports.
- Field Mapping: MUST use the
json_nameannotations for HTTP/JSON transcoding compatibility. - Error Handling: MUST map A2A error codes to appropriate gRPC status codes as defined in the proto annotations.
- Transport Security: MUST support TLS encryption (gRPC over HTTP/2 with TLS).
3.2.3. HTTP+JSON/REST Transport¶
Agents MAY support REST-style HTTP+JSON transport. If implemented, it MUST conform to these requirements:
- HTTP Methods: MUST use appropriate HTTP verbs (GET for queries, POST for actions, PUT for updates, DELETE for removal).
- URL Patterns: MUST follow the URL patterns documented in each method section (e.g.,
/v1/message:send,/v1/tasks/{id}). - Content-Type: MUST use
application/jsonfor request and response bodies. - HTTP Status Codes: MUST use appropriate HTTP status codes (200, 400, 401, 403, 404, 500, etc.) that correspond to A2A error types.
- Request/Response Format: MUST use JSON objects that are structurally equivalent to the core A2A data structures.
- Method Coverage: MUST provide all methods with functionally equivalent behavior to other supported transports.
- Error Format: MUST return error responses in a consistent JSON format that maps to A2A error types.
3.2.4. Transport Extensions¶
Additional transport protocols MAY be defined as extensions to the core A2A specification. Such extensions:
- MUST maintain functional equivalence with the core transports
- MUST use clear namespace identifiers to avoid conflicts
- MUST be clearly documented and specified
- SHOULD provide migration paths from core transports
3.3. Streaming Transport (Server-Sent Events)¶
Streaming capabilities are transport-specific:
3.3.1. JSON-RPC 2.0 Streaming¶
When streaming is used for methods like message/stream or tasks/resubscribe:
- The server responds with an HTTP
200 OKstatus and aContent-Typeheader oftext/event-stream. - The body of this HTTP response contains a stream of Server-Sent Events (SSE) as defined by the W3C.
- Each SSE
datafield contains a complete JSON-RPC 2.0 Response object (specifically, aSendStreamingMessageResponse).
3.3.2. gRPC Streaming¶
gRPC transport uses server streaming RPCs for streaming operations as defined in the Protocol Buffers specification.
3.3.3. HTTP+JSON/REST Streaming¶
If REST transport is supported it MUST implement streaming using Server-Sent Events similar to JSON-RPC.
3.4. Transport Compliance and Interoperability¶
3.4.1. Functional Equivalence Requirements¶
When an agent supports multiple transports, all supported transports MUST:
- Identical Functionality: Provide the same set of operations and capabilities.
- Consistent Behavior: Return semantically equivalent results for the same requests.
- Same Error Handling: Map errors consistently across transports using the error codes defined in Section 8.
- Equivalent Authentication: Support the same authentication schemes declared in the
AgentCard.
3.4.2. Transport Selection and Negotiation¶
- Agent Declaration: Agents MUST declare all supported transports in their
AgentCardusing thepreferredTransportandadditionalInterfacesfields. - Client Choice: Clients MAY choose any transport declared by the agent.
- No Transport Negotiation: A2A does not define a dynamic transport negotiation protocol. Clients select a transport based on the static
AgentCardinformation. - Fallback Behavior: Clients SHOULD implement fallback logic to try alternative transports if their preferred transport fails. The specific fallback strategy is implementation-dependent.
3.4.3. Transport-Specific Extensions¶
Transports MAY provide transport-specific optimizations or extensions that do not compromise functional equivalence:
- gRPC: May leverage gRPC-specific features like bidirectional streaming, metadata, or custom status codes.
- REST: May provide additional HTTP caching headers or support HTTP conditional requests.
- JSON-RPC: May include additional fields in the JSON-RPC request/response objects that do not conflict with the core specification.
Such extensions MUST be backward-compatible and MUST NOT break interoperability with clients that do not support the extensions.
3.5. Method Mapping and Naming Conventions¶
To ensure consistency and predictability across different transports, A2A defines normative method mapping rules.
3.5.1. JSON-RPC Method Naming¶
JSON-RPC methods MUST follow the pattern: {category}/{action} where:
categoryrepresents the resource type (e.g., "message", "tasks", "agent")actionrepresents the operation (e.g., "send", "get", "cancel")- Nested actions use forward slashes (e.g., "tasks/pushNotificationConfig/set")
3.5.2. gRPC Method Naming¶
gRPC methods MUST follow Protocol Buffers service conventions using PascalCase:
- Convert JSON-RPC category/action to PascalCase compound words
- Use standard gRPC method prefixes (Get, Set, List, Create, Delete, Cancel)
3.5.3. HTTP+JSON/REST Method Naming¶
REST endpoints MUST follow RESTful URL patterns with appropriate HTTP verbs:
- Use resource-based URLs:
/v1/{resource}[/{id}][:{action}] - Use standard HTTP methods aligned with REST semantics
- Use colon notation for non-CRUD actions
3.5.4. Method Mapping Compliance¶
When implementing multiple transports, agents MUST:
- Use standard mappings: Follow the method mappings defined in sections 3.5.2 and 3.5.3.
- Maintain functional equivalence: Each transport-specific method MUST provide identical functionality across all supported transports.
- Consistent parameters: Use equivalent parameter structures across transports (accounting for transport-specific serialization differences).
- Equivalent responses: Return semantically equivalent responses across all transports for the same operation.
3.5.5. Extension Method Naming¶
For custom or extension methods not defined in the core A2A specification:
- JSON-RPC: Follow the
{category}/{action}pattern with a clear namespace (e.g.,myorg.extension/action) - gRPC: Use appropriate service and method names following Protocol Buffers conventions
- REST: Use clear resource-based URLs with appropriate HTTP methods
Extension methods MUST be clearly documented and MUST NOT conflict with core A2A method names or semantics.
3.5.6. Method Mapping Reference Table¶
For quick reference, the following table summarizes the method mappings across all transports:
| JSON-RPC Method | gRPC Method | REST Endpoint | Description |
|---|---|---|---|
message/send | SendMessage | POST /v1/message:send | Send message to agent |
message/stream | SendStreamingMessage | POST /v1/message:stream | Send message with streaming |
tasks/get | GetTask | GET /v1/tasks/{id} | Get task status |
tasks/list | ListTask | GET /v1/tasks | List tasks (gRPC/REST only) |
tasks/cancel | CancelTask | POST /v1/tasks/{id}:cancel | Cancel task |
tasks/resubscribe | TaskSubscription | POST /v1/tasks/{id}:subscribe | Resume task streaming |
tasks/pushNotificationConfig/set | CreateTaskPushNotification | POST /v1/tasks/{id}/pushNotificationConfigs | Set push notification config |
tasks/pushNotificationConfig/get | GetTaskPushNotification | GET /v1/tasks/{id}/pushNotificationConfigs/{configId} | Get push notification config |
tasks/pushNotificationConfig/list | ListTaskPushNotification | GET /v1/tasks/{id}/pushNotificationConfigs | List push notification configs |
tasks/pushNotificationConfig/delete | DeleteTaskPushNotification | DELETE /v1/tasks/{id}/pushNotificationConfigs/{configId} | Delete push notification config |
agent/getAuthenticatedExtendedCard | GetAgentCard | GET /v1/card | Get authenticated agent card |
4. Authentication and Authorization¶
A2A treats agents as standard enterprise applications, relying on established web security practices. Identity information is not transmitted within A2A JSON-RPC payloads; it is handled at the HTTP transport layer.
For a comprehensive guide on enterprise security aspects, see Enterprise-Ready Features.
4.1. Transport Security¶
As stated in section 3.1, production deployments MUST use HTTPS. Implementations SHOULD use modern TLS configurations (TLS 1.3+ recommended) with strong cipher suites.
4.2. Server Identity Verification¶
A2A Clients SHOULD verify the A2A Server's identity by validating its TLS certificate against trusted certificate authorities (CAs) during the TLS handshake.
4.3. Client/User Identity & Authentication Process¶
- Discovery of Requirements: The client discovers the server's required authentication schemes via the
authenticationfield in theAgentCard. Scheme names often align with OpenAPI Authentication methods (e.g., "Bearer" for OAuth 2.0 tokens, "Basic" for Basic Auth, "ApiKey" for API keys). - Credential Acquisition (Out-of-Band): The client obtains the necessary credentials (e.g., API keys, OAuth tokens, JWTs) through an out-of-band process specific to the required authentication scheme and the identity provider. This process is outside the scope of the A2A protocol itself.
- Credential Transmission: The client includes these credentials in the appropriate HTTP headers (e.g.,
Authorization: Bearer <token>,X-API-Key: <value>) of every A2A request sent to the server.
4.4. Server Responsibilities for Authentication¶
The A2A Server:
- MUST authenticate every incoming request based on the provided HTTP credentials and its declared authentication requirements from its Agent Card.
- SHOULD use standard HTTP status codes like
401 Unauthorizedor403 Forbiddenfor authentication challenges or rejections. - SHOULD include relevant HTTP headers (e.g.,
WWW-Authenticate) with401 Unauthorizedresponses to indicate the required authentication scheme(s), guiding the client. - SHOULD verify the Client's webhook server identity by validating its TLS certificate against trusted certificate authorities (CAs) during the TLS handshake.
4.5. In-Task Authentication (Secondary Credentials)¶
If an agent, during the execution of a task, requires additional credentials for a different system or resource (e.g., to access a specific tool on behalf of the user that requires its own auth):
- It SHOULD transition the A2A task to the
auth-requiredstate (seeTaskState). - The accompanying
TaskStatus.message(often aDataPart) SHOULD provide details about the required secondary authentication, potentially using anPushNotificationAuthenticationInfo-like structure to describe the need. - The A2A Client then obtains these new credentials out-of-band and provides them in a subsequent
message/sendormessage/streamrequest. How these credentials are used (e.g., passed as data within the A2A message if the agent is proxying, or used by the client to interact directly with the secondary system) depends on the specific scenario.
4.6. Authorization¶
Once a client is authenticated, the A2A Server is responsible for authorizing the request based on the authenticated client/user identity and its own policies. Authorization logic is implementation-specific and MAY be enforced based on:
- The specific skills requested (e.g., as identified by
AgentSkill.idfrom the Agent Card). - The actions attempted within the task.
- Data access policies relevant to the resources the agent manages.
- OAuth scopes associated with the presented token, if applicable.
Servers should implement the principle of least privilege.
5. Agent Discovery: The Agent Card¶
5.1. Purpose¶
A2A Servers MUST make an Agent Card available. The Agent Card is a JSON document that describes the server's identity, capabilities, skills, service endpoint URL, and how clients should authenticate and interact with it. Clients use this information for discovering suitable agents and for configuring their interactions.
For more on discovery strategies, see the Agent Discovery guide.
5.2. Discovery Mechanisms¶
Clients can find Agent Cards through various methods, including but not limited to:
- Well-Known URI: Accessing a predefined path on the agent's domain (see Section 5.3).
- Registries/Catalogs: Querying curated catalogs or registries of agents (which might be enterprise-specific, public, or domain-specific).
- Direct Configuration: Clients may be pre-configured with the Agent Card URL or the card content itself.
5.3. Recommended Location¶
If using the well-known URI strategy, the recommended location for an agent's Agent Card is: https://{server_domain}/.well-known/agent-card.json This follows the principles of RFC 8615 for well-known URIs.
5.4. Security of Agent Cards¶
Agent Cards themselves might contain information that is considered sensitive.
- If an Agent Card contains sensitive information, the endpoint serving the card MUST be protected by appropriate access controls (e.g., mTLS, network restrictions, authentication required to fetch the card).
- It is generally NOT RECOMMENDED to include plaintext secrets (like static API keys) directly in an Agent Card. Prefer authentication schemes where clients obtain dynamic credentials out-of-band.
5.5. AgentCard Object Structure¶
{{ render_spec_tabs('AgentCard') }}
5.5.1. AgentProvider Object¶
Information about the organization or entity providing the agent.
{{ render_spec_tabs('AgentProvider') }}
5.5.2. AgentCapabilities Object¶
Specifies optional A2A protocol features supported by the agent.
{{ render_spec_tabs('AgentCapabilities') }}
5.5.2.1. AgentExtension Object¶
Specifies an extension to the A2A protocol supported by the agent.
{{ render_spec_tabs('AgentExtension') }}
5.5.3. SecurityScheme Object¶
Describes the authentication requirements for accessing the agent's url endpoint. Refer Sample Agent Card for an example.
{{ render_spec_tabs('SecurityScheme') }}
5.5.4. AgentSkill Object¶
Describes a specific capability, function, or area of expertise the agent can perform or address.
{{ render_spec_tabs('AgentSkill') }}
5.5.5. AgentInterface Object¶
Provides a declaration of a combination of the target URL and the supported transport to interact with the agent. This enables agents to expose the same functionality through multiple transport protocols.
{{ render_spec_tabs('AgentInterface') }}
The transport field SHOULD use one of the core A2A transport protocol values:
"JSONRPC": JSON-RPC 2.0 over HTTP"GRPC": gRPC over HTTP/2"HTTP+JSON": REST-style HTTP with JSON
Additional transport values MAY be used for future extensions, but such extensions MUST not conflict with core A2A protocol functionality.
5.5.6. AgentCardSignature Object¶
Represents a JSON Web Signature (JWS) used to verify the integrity of the AgentCard.
{{ render_spec_tabs('AgentCardSignature') }}
5.6. Transport Declaration and URL Relationships¶
The AgentCard MUST properly declare the relationship between URLs and transport protocols:
5.6.1. Main URL and Preferred Transport¶
- Main URL requirement: The
urlfield MUST specify the primary endpoint for the agent. - Transport correspondence: The transport protocol available at the main
urlMUST match thepreferredTransportfield. - Required declaration: The
preferredTransportfield is REQUIRED and MUST be present in everyAgentCard. - Transport availability: The main
urlMUST support the transport protocol declared inpreferredTransport.
5.6.2. Additional Interfaces¶
- URL uniqueness: Each
AgentInterfaceinadditionalInterfacesSHOULD specify a distinct URL for clarity, but MAY reuse URLs if multiple transport protocols are available at the same endpoint. - Transport declaration: Each
AgentInterfaceMUST accurately declare the transport protocol available at its specified URL. - Completeness: The
additionalInterfacesarray SHOULD include all supported transports, including the main URL's transport for completeness.
5.6.3. Client Transport Selection Rules¶
Clients MUST follow these rules when selecting a transport:
- Parse transport declarations: Extract available transports from both the main
url/preferredTransportcombination and alladditionalInterfaces. - Prefer declared preference: If the client supports the
preferredTransport, it SHOULD use the mainurl. - Fallback selection: If the preferred transport is not supported by the client, it MAY select any supported transport from
additionalInterfaces. - Graceful degradation: Clients SHOULD implement fallback logic to try alternative transports if their first choice fails.
- URL-transport matching: Clients MUST use the correct URL for the selected transport protocol as declared in the AgentCard.
5.6.4. Validation Requirements¶
Agent Cards MUST satisfy these validation requirements:
- Transport consistency: The
preferredTransportvalue MUST be present and MUST be available at the mainurl. - Interface completeness: If
additionalInterfacesis provided, it SHOULD include an entry corresponding to the mainurlandpreferredTransport. - No conflicts: The same URL MUST NOT declare conflicting transport protocols across different interface declarations.
- Minimum transport requirement: The agent MUST declare at least one supported transport protocol through either the main
url/preferredTransportcombination oradditionalInterfaces.
5.7. Sample Agent Card¶
{
"protocolVersion": "0.2.9",
"name": "GeoSpatial Route Planner Agent",
"description": "Provides advanced route planning, traffic analysis, and custom map generation services. This agent can calculate optimal routes, estimate travel times considering real-time traffic, and create personalized maps with points of interest.",
"url": "https://georoute-agent.example.com/a2a/v1",
"preferredTransport": "JSONRPC",
"additionalInterfaces" : [
{"url": "https://georoute-agent.example.com/a2a/v1", "transport": "JSONRPC"},
{"url": "https://georoute-agent.example.com/a2a/grpc", "transport": "GRPC"},
{"url": "https://georoute-agent.example.com/a2a/json", "transport": "HTTP+JSON"}
],
"provider": {
"organization": "Example Geo Services Inc.",
"url": "https://www.examplegeoservices.com"
},
"iconUrl": "https://georoute-agent.example.com/icon.png",
"version": "1.2.0",
"documentationUrl": "https://docs.examplegeoservices.com/georoute-agent/api",
"capabilities": {
"streaming": true,
"pushNotifications": true,
"stateTransitionHistory": false
},
"securitySchemes": {
"google": {
"type": "openIdConnect",
"openIdConnectUrl": "https://accounts.google.com/.well-known/openid-configuration"
}
},
"security": [{ "google": ["openid", "profile", "email"] }],
"defaultInputModes": ["application/json", "text/plain"],
"defaultOutputModes": ["application/json", "image/png"],
"skills": [
{
"id": "route-optimizer-traffic",
"name": "Traffic-Aware Route Optimizer",
"description": "Calculates the optimal driving route between two or more locations, taking into account real-time traffic conditions, road closures, and user preferences (e.g., avoid tolls, prefer highways).",
"tags": ["maps", "routing", "navigation", "directions", "traffic"],
"examples": [
"Plan a route from '1600 Amphitheatre Parkway, Mountain View, CA' to 'San Francisco International Airport' avoiding tolls.",
"{\"origin\": {\"lat\": 37.422, \"lng\": -122.084}, \"destination\": {\"lat\": 37.7749, \"lng\": -122.4194}, \"preferences\": [\"avoid_ferries\"]}"
],
"inputModes": ["application/json", "text/plain"],
"outputModes": [
"application/json",
"application/vnd.geo+json",
"text/html"
]
},
{
"id": "custom-map-generator",
"name": "Personalized Map Generator",
"description": "Creates custom map images or interactive map views based on user-defined points of interest, routes, and style preferences. Can overlay data layers.",
"tags": ["maps", "customization", "visualization", "cartography"],
"examples": [
"Generate a map of my upcoming road trip with all planned stops highlighted.",
"Show me a map visualizing all coffee shops within a 1-mile radius of my current location."
],
"inputModes": ["application/json"],
"outputModes": [
"image/png",
"image/jpeg",
"application/json",
"text/html"
]
}
],
"supportsAuthenticatedExtendedCard": true,
"signatures": [
{
"protected": "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpPU0UiLCJraWQiOiJrZXktMSIsImprdSI6Imh0dHBzOi8vZXhhbXBsZS5jb20vYWdlbnQvandrcy5qc29uIn0",
"signature": "QFdkNLNszlGj3z3u0YQGt_T9LixY3qtdQpZmsTdDHDe3fXV9y9-B3m2-XgCpzuhiLt8E0tV6HXoZKHv4GtHgKQ"
}
]
}
6. Protocol Data Objects¶
These objects define the structure of data exchanged within the JSON-RPC methods of the A2A protocol.
6.1. Task Object¶
Represents the stateful unit of work being processed by the A2A Server for an A2A Client. A task encapsulates the entire interaction related to a specific goal or request. A task which has reached a terminal state (completed, canceled, rejected, or failed) can't be restarted. Tasks in completed state SHOULD use artifacts for returning the generated output to the clients. For more information, refer to the Life of a Task guide.
{{ render_spec_tabs('Task') }}
6.2. TaskStatus Object¶
Represents the current state and associated context (e.g., a message from the agent) of a Task.
{{ render_spec_tabs('TaskStatus') }}
6.3. TaskState Enum¶
Defines the possible lifecycle states of a Task.
{{ render_spec_tabs('TaskState') }}
6.4. Message Object¶
Represents a single communication turn or a piece of contextual information between a client and an agent. Messages are used for instructions, prompts, replies, and status updates.
{{ render_spec_tabs('Message') }}
6.5. Part Union Type¶
Represents a distinct piece of content within a Message or Artifact. A Part is a union type representing exportable content as either TextPart, FilePart, or DataPart. All Part types also include an optional metadata field (Record<string, any>) for part-specific metadata.
{{ render_spec_tabs('Part') }}
It MUST be one of the following:
6.5.1. TextPart Object¶
For conveying plain textual content.
6.5.2. FilePart Object¶
For conveying file-based content.
{{ render_spec_tabs('FilePart') }}
6.5.3. DataPart Object¶
For conveying structured JSON data. Useful for forms, parameters, or any machine-readable information.
{{ render_spec_tabs('DataPart') }}
6.6 FileBase Object¶
Base entity for File Contents.
6.6.1 FileWithBytes Object¶
Represents the data for a file, used within a FilePart.
6.6.2 FileWithUri Object¶
Represents the URI for a file, used within a FilePart.
6.7. Artifact Object¶
Represents a tangible output generated by the agent during a task. Artifacts are the results or products of the agent's work.
{{ render_spec_tabs('Artifact') }}
6.8. PushNotificationConfig Object¶
Configuration provided by the client to the server for sending asynchronous push notifications about task updates.
{{ render_spec_tabs('PushNotificationConfig') }}
6.9. PushNotificationAuthenticationInfo Object¶
A generic structure for specifying authentication requirements, typically used within PushNotificationConfig to describe how the A2A Server should authenticate to the client's webhook.
{{ render_spec_tabs('PushNotificationAuthenticationInfo') }}
6.10. TaskPushNotificationConfig Object¶
Used as the params object for the tasks/pushNotificationConfig/set method and as the result object for the tasks/pushNotificationConfig/get method.
{{ render_spec_tabs('TaskPushNotificationConfig') }}
6.11. JSON-RPC Structures¶
A2A adheres to the standard JSON-RPC 2.0 structures for requests and responses.
6.11.1. JSONRPCRequest Object¶
All A2A method calls are encapsulated in a JSON-RPC Request object.
jsonrpc: A String specifying the version of the JSON-RPC protocol. MUST be exactly"2.0".method: A String containing the name of the method to be invoked (e.g.,"message/send","tasks/get").params: A Structured value that holds the parameter values to be used during the invocation of the method. This member MAY be omitted if the method expects no parameters. A2A methods typically use anobjectforparams.id: An identifier established by the Client that MUST contain a String, Number, orNULLvalue if included. If it is not included it is assumed to be a notification. The value SHOULD NOT beNULLfor requests expecting a response, and Numbers SHOULD NOT contain fractional parts. The Server MUST reply with the same value in the Response object if included. This member is used to correlate the context between the two objects. A2A methods typically expect a response or stream, soidwill usually be present and non-null.
6.11.2. JSONRPCResponse Object¶
Responses from the A2A Server are encapsulated in a JSON-RPC Response object.
jsonrpc: A String specifying the version of the JSON-RPC protocol. MUST be exactly"2.0".id: This member is REQUIRED. It MUST be the same as the value of theidmember in the Request Object. If there was an error in detecting theidin the Request object (e.g. Parse error/Invalid Request), it MUST benull.- EITHER
result: This member is REQUIRED on success. This member MUST NOT exist if there was an error invoking the method. The value of this member is determined by the method invoked on the Server. - OR
error: This member is REQUIRED on failure. This member MUST NOT exist if there was no error triggered during invocation. The value of this member MUST be anJSONRPCErrorobject. - The members
resultanderrorare mutually exclusive: one MUST be present, and the other MUST NOT.
6.12. JSONRPCError Object¶
When a JSON-RPC call encounters an error, the Response Object will contain an error member with a value of this structure.
7. Protocol RPC Methods¶
All A2A RPC methods are invoked by the A2A Client by sending an HTTP POST request to the A2A Server's url (as specified in its AgentCard). The body of the HTTP POST request MUST be a JSONRPCRequest object, and the Content-Type header MUST be application/json.
The A2A Server's HTTP response body MUST be a JSONRPCResponse object (or, for streaming methods, an SSE stream where each event's data is a JSONRPCResponse). The Content-Type for JSON-RPC responses is application/json. For SSE streams, it is text/event-stream.
7.1. message/send¶
Sends a message to an agent to initiate a new interaction or to continue an existing one. This method is suitable for synchronous request/response interactions or when client-side polling (using tasks/get) is acceptable for monitoring longer-running tasks. A task which has reached a terminal state (completed, canceled, rejected, or failed) can't be restarted. Sending a message to such a task will result in an error. For more information, refer to the Life of a Task guide.
- URL:
message/send - HTTP Method:
POST - Payload:
MessageSendParams - Response:
Task|Message(A message object or the current or final state of the task after processing the message).
- URL:
SendMessage - HTTP Method:
POST - Payload:
- Response:
The error response for all transports in case of failure is a JSONRPCError or equivalent.
7.1.1. MessageSendParams Object¶
{{ render_spec_tabs('MessageSendParams') }}
7.1.2 MessageSendConfiguration Object¶
{{ render_spec_tabs('MessageSendConfiguration') }}
7.2. message/stream¶
Sends a message to an agent to initiate/continue a task AND subscribes the client to real-time updates for that task via Server-Sent Events (SSE). This method requires the server to have AgentCard.capabilities.streaming: true. Just like message/send, a task which has reached a terminal state (completed, canceled, rejected, or failed) can't be restarted. Sending a message to such a task will result in an error. For more information, refer to the Life of a Task guide.
- URL:
message/stream - HTTP Method:
POST - Payload:
MessageSendParams(same asmessage/send) - Response: A stream of Server-Sent Events. Each SSE
datafield contains aSendStreamingMessageResponse
- URL:
SendStreamingMessage - HTTP Method:
POST - Payload:
- Response:
7.2.1. SendStreamingMessageResponse Object¶
This is the structure of the JSON object found in the data field of each Server-Sent Event sent by the server for a message/stream request or tasks/resubscribe request.
{{ render_spec_tabs('SendStreamingMessageSuccessResponse') }}
7.2.2. TaskStatusUpdateEvent Object¶
Carries information about a change in the task's status during streaming. This is one of the possible result types in a SendStreamingMessageSuccessResponse.
{{ render_spec_tabs('TaskStatusUpdateEvent') }}
7.2.3. TaskArtifactUpdateEvent Object¶
Carries a new or updated artifact (or a chunk of an artifact) generated by the task during streaming. This is one of the possible result types in a SendTaskStreamingResponse.
{{ render_spec_tabs('TaskArtifactUpdateEvent') }}
7.3. tasks/get¶
Retrieves the current state (including status, artifacts, and optionally history) of a previously initiated task. This is typically used for polling the status of a task initiated with message/send, or for fetching the final state of a task after being notified via a push notification or after an SSE stream has ended.
- URL:
tasks/get - HTTP Method:
POST - Payload:
TaskQueryParams - Response:
Task
- URL:
GetTask - HTTP Method:
POST - Payload:
- Response:
Task
- URL:
v1/tasks/{id}?historyLength={historyLength} - HTTP Method:
GET - Payload: None
- Response:
Task
7.3.1. TaskQueryParams Object¶
{{ render_spec_tabs('TaskQueryParams') }}
7.4. tasks/list¶
Retrieves a list of tasks with optional filtering and pagination capabilities. This method allows clients to discover and manage multiple tasks across different contexts or with specific status criteria.
Pagination Strategy: This method uses cursor-based pagination (via pageToken/nextPageToken) rather than offset-based pagination for better performance and consistency, especially with large datasets. Cursor-based pagination avoids the "deep pagination problem" where skipping large numbers of records becomes inefficient for databases. This approach is consistent with the gRPC specification, which also uses cursor-based pagination (page_token/next_page_token).
Ordering: Implementations MUST return tasks sorted by their last update time in descending order (most recently updated tasks first). This ensures consistent pagination and allows clients to efficiently monitor recent task activity.
Security Note: Implementations MUST ensure appropriate scope limitation based on the authenticated user's permissions. Servers SHOULD NOT return tasks from other users or unauthorized contexts. Even when contextId is not specified in the request, the implementation MUST still scope results to the caller's authorization and tenancy boundaries. The implementation MAY choose to limit results to tasks created by the current authenticated user, tasks within a default user context, or return an authorization error if the scope cannot be safely determined.
- Request
paramstype:ListTasksParams(Optional parameters for filtering and pagination) - Response
resulttype (on success):ListTasksResult(A paginated list of tasks matching the criteria) - Response
errortype (on failure):JSONRPCError(see specific error cases below)
Error Cases for tasks/list:
The following table details specific error conditions that should result in an InvalidParamsError (-32602) response:
| Parameter | Invalid Condition | Error Details | Example |
|---|---|---|---|
pageSize | Value outside 1–100 range | Must be between 1 and 100 inclusive | pageSize: 0 or pageSize: 101 |
pageToken | Malformed token format | Token is not a valid base64-encoded cursor | pageToken: "invalid!@#" |
pageToken | Expired token | Token has exceeded its validity period | pageToken: "<expired-token>" |
historyLength | Negative value | Must be non-negative integer | historyLength: -1 |
status | Invalid enum value | Must be one of: pending, working, completed, failed, canceled | status: "running" |
lastUpdatedAfter | Invalid timestamp format | Must be a valid Unix timestamp in milliseconds | lastUpdatedAfter: "not-a-number" |
lastUpdatedAfter | Future timestamp | Timestamp is in the future (optional validation) | lastUpdatedAfter: 4102444800000 (year 2100) |
Additional Error Responses:
-32001(TaskNotFoundError): WhencontextIdrefers to a nonexistent or inaccessible context-32600(InvalidRequest): When the request structure is malformed-32603(InternalError): When a server-side error occurs during task retrieval
7.4.1. ListTasksParams Object¶
Parameters for filtering and paginating task results.
Note on includeArtifacts parameter: When includeArtifacts is false (the default), the artifacts field MUST be omitted entirely from each Task object in the response. The field should not be present as an empty array or null value. When includeArtifacts is true, the artifacts field should be included with its actual content (which may be an empty array if the task has no artifacts).
7.4.2. ListTasksResult Object¶
Result object containing the filtered tasks and pagination information.
Note on nextPageToken: The nextPageToken field MUST always be present in the response. When there are no more results to retrieve (i.e., this is the final page), the field MUST be set to an empty string (""). Clients should check for an empty string to determine if more pages are available.
7.5. tasks/cancel¶
Requests the cancellation of an ongoing task. The server will attempt to cancel the task, but success is not guaranteed (e.g., the task might have already completed or failed, or cancellation might not be supported at its current stage).
- URL:
tasks/cancel - HTTP Method:
POST - Payload:
TaskIdParams - Response:
Task
- URL:
CancelTask - HTTP Method:
POST - Payload:
- Response:
Task
- URL:
/v1/tasks/{id}:cancel - HTTP Method:
POST - Payload:
- Response:
Task
- Response
errortype (on failure):JSONRPCError(e.g.,TaskNotFoundError,TaskNotCancelableError).
7.5.1. TaskIdParams Object (for tasks/cancel and tasks/pushNotificationConfig/get)¶
A simple object containing just the task ID and optional metadata.
{{ render_spec_tabs('TaskIdParams') }}
7.6. tasks/pushNotificationConfig/set¶
Sets or updates the push notification configuration for a specified task. This allows the client to tell the server where and how to send asynchronous updates for the task. Requires the server to have AgentCard.capabilities.pushNotifications: true.
- URL:
tasks/pushNotificationConfig/set - HTTP Method:
POST - Payload:
TaskPushNotificationConfig - Response:
TaskPushNotificationConfig
- URL:
CreateTaskPushNotification - HTTP Method:
POST - Payload:
- Response:
TaskPushNotificationConfig
7.7. tasks/pushNotificationConfig/get¶
Retrieves the current push notification configuration for a specified task. Requires the server to have AgentCard.capabilities.pushNotifications: true.
- URL:
tasks/pushNotificationConfig/get - HTTP Method:
POST - Payload:
GetTaskPushNotificationConfigParams - Response:
TaskPushNotificationConfig
- URL:
GetTaskPushNotification - HTTP Method:
POST - Payload:
- Response:
TaskPushNotificationConfig
- URL:
/v1/tasks/{taskId}/pushNotificationConfigs/{configId} - HTTP Method:
GET - Payload: None
- Response:
TaskPushNotificationConfig
Response error type (on failure): JSONRPCError (e.g., PushNotificationNotSupportedError, TaskNotFoundError).
7.7.1. GetTaskPushNotificationConfigParams Object (tasks/pushNotificationConfig/get)¶
A object for fetching the push notification configuration for a task.
{{ render_spec_tabs('GetTaskPushNotificationConfigParams') }}
7.8. tasks/pushNotificationConfig/list¶
Retrieves the associated push notification configurations for a specified task. Requires the server to have AgentCard.capabilities.pushNotifications: true.
- URL:
tasks/pushNotificationConfig/list - HTTP Method:
POST - Payload:
ListTaskPushNotificationConfigParams - Response:
TaskPushNotificationConfig[]
- URL:
ListTaskPushNotification - HTTP Method:
POST - Payload:
- Response:
repeated TaskPushNotificationConfig
- URL:
/v1/tasks/{id}/pushNotificationConfigs - HTTP Method:
GET - Payload:: None
- Response:
[TaskPushNotificationConfig]
- Response
errortype (on failure):JSONRPCError(e.g.,PushNotificationNotSupportedError,TaskNotFoundError).
7.8.1. ListTaskPushNotificationConfigParams Object (tasks/pushNotificationConfig/list)¶
A object for fetching the push notification configurations for a task.
{{ render_spec_tabs('ListTaskPushNotificationConfigParams') }}
7.9. tasks/pushNotificationConfig/delete¶
Deletes an associated push notification configuration for a task. Requires the server to have AgentCard.capabilities.pushNotifications: true.
- Request
paramstype:DeleteTaskPushNotificationConfigParams - Response
resulttype (on success): [null] - Response
errortype (on failure):JSONRPCError(e.g.,PushNotificationNotSupportedError,TaskNotFoundError).
7.9.1. DeleteTaskPushNotificationConfigParams Object (tasks/pushNotificationConfig/delete)¶
A object for deleting an associated push notification configuration for a task.
{{ render_spec_tabs('DeleteTaskPushNotificationConfigParams') }}
7.10. tasks/resubscribe¶
Allows a client to reconnect to an SSE stream for an ongoing task after a previous connection (from message/stream or an earlier tasks/resubscribe) was interrupted. Requires the server to have AgentCard.capabilities.streaming: true.
The purpose is to resume receiving subsequent updates. The server's behavior regarding events missed during the disconnection period (e.g., whether it attempts to backfill some missed events or only sends new ones from the point of resubscription) is implementation-dependent and not strictly defined by this specification.
- URL:
tasks/resubscribe - HTTP Method:
POST - Payload:
TaskIdParams - Response: A stream of Server-Sent Events. Each SSE
datafield contains aSendStreamingMessageResponse
- URL:
TaskSubscription - HTTP Method:
POST - Payload:
- Response:
7.10. agent/getAuthenticatedExtendedCard¶
Retrieves a potentially more detailed version of the Agent Card after the client has authenticated. This endpoint is available only if AgentCard.supportsAuthenticatedExtendedCard is true.
- Authentication: The client MUST authenticate the request using one of the schemes declared in the public
AgentCard.securitySchemesandAgentCard.securityfields. - Response
resulttype (on success):AgentCard(A complete Agent Card object, which may contain additional details or skills not present in the public card). - Response
errortype (on failure): Standard HTTP error codes.401 Unauthorized: Authentication failed (missing or invalid credentials). The server SHOULD include aWWW-Authenticateheader.
- URL:
agent/getAuthenticatedExtendedCard - HTTP Method:
POST - Payload: None
- Response:
AgentCard
- URL:
GetAgentCard - HTTP Method:
POST - Payload: None
- Response:
AgentCard
- URL:
/v1/card - HTTP Method:
GET - Payload: None
- Response:
AgentCard
Clients retrieving this authenticated card SHOULD replace their cached public Agent Card with the content received from this endpoint for the duration of their authenticated session or until the card's version changes.
8. Error Handling¶
A2A uses standard JSON-RPC 2.0 error codes and structure for reporting errors. Errors are returned in the error member of the JSONRPCErrorResponse object. See JSONRPCError Object definition.
8.1. Standard JSON-RPC Errors¶
These are standard codes defined by the JSON-RPC 2.0 specification.
| Code | JSON-RPC Spec Meaning | Typical A2A message | Description |
|---|---|---|---|
-32700 | Parse error | Invalid JSON payload | Server received JSON that was not well-formed. |
-32600 | Invalid Request | Invalid JSON-RPC Request | The JSON payload was valid JSON, but not a valid JSON-RPC Request object. |
-32601 | Method not found | Method not found | The requested A2A RPC method (e.g., "tasks/foo") does not exist or is not supported. |
-32602 | Invalid params | Invalid method parameters | The params provided for the method are invalid (e.g., wrong type, missing required field). |
-32603 | Internal error | Internal server error | An unexpected error occurred on the server during processing. |
-32000 to -32099 | Server error | (Server-defined) | Reserved for implementation-defined server-errors. A2A-specific errors use this range. |
8.2. A2A-Specific Errors¶
These are custom error codes defined within the JSON-RPC server error range (-32000 to -32099) to provide more specific feedback about A2A-related issues. Servers SHOULD use these codes where applicable.
| Code | Error Name (Conceptual) | Typical message string | Description |
|---|---|---|---|
-32001 | TaskNotFoundError | Task not found | The specified task id does not correspond to an existing or active task. It might be invalid, expired, or already completed and purged. |
-32002 | TaskNotCancelableError | Task cannot be canceled | An attempt was made to cancel a task that is not in a cancelable state (e.g., it has already reached a terminal state like completed, failed, or canceled). |
-32003 | PushNotificationNotSupportedError | Push Notification is not supported | Client attempted to use push notification features (e.g., tasks/pushNotificationConfig/set) but the server agent does not support them (i.e., AgentCard.capabilities.pushNotifications is false). |
-32004 | UnsupportedOperationError | This operation is not supported | The requested operation or a specific aspect of it (perhaps implied by parameters) is not supported by this server agent implementation. Broader than just method not found. |
-32005 | ContentTypeNotSupportedError | Incompatible content types | A Media Type provided in the request's message.parts (or implied for an artifact) is not supported by the agent or the specific skill being invoked. |
-32006 | InvalidAgentResponseError | Invalid agent response type | Agent generated an invalid response for the requested method |
-32007 | AuthenticatedExtendedCardNotConfiguredError | Authenticated Extended Card not configured | The agent does not have an Authenticated Extended Card configured. |
Servers MAY define additional error codes within the -32000 to -32099 range for more specific scenarios not covered above, but they SHOULD document these clearly. The data field of the JSONRPCError object can be used to provide more structured details for any error.
9. Common Workflows & Examples¶
This section provides illustrative JSON examples of common A2A interactions. Timestamps, context IDs, and request/response IDs are for demonstration purposes. For brevity, some optional fields might be omitted if not central to the example.
9.1. Fetching Authenticated Extended Agent Card¶
Scenario: A client discovers a public Agent Card indicating support for an authenticated extended card and wants to retrieve the full details.
- Client fetches the public Agent Card:
Server responds with the public Agent Card (like the example in Section 5.6), including supportsAuthenticatedExtendedCard: true (at the root level) and securitySchemes.
-
Client identifies required authentication from the public card.
-
Client obtains necessary credentials out-of-band (e.g., performs OAuth 2.0 flow with Google, resulting in an access token).
-
Client fetches the authenticated extended Agent Card using
agent/getAuthenticatedExtendedCardrequest:
-
Server authenticates and authorizes the request.
-
Server responds with the full Agent Card as the JSON-RPC result:
9.2. Basic Execution (Synchronous / Polling Style)¶
Scenario: Client asks a simple question, and the agent responds quickly with a task
- Client sends a message using
message/send:
{
"jsonrpc": "2.0",
"id": 1,
"method": "message/send",
"params": {
"message": {
"role": "user",
"parts": [
{
"kind": "text",
"text": "tell me a joke"
}
],
"messageId": "9229e770-767c-417b-a0b0-f0741243c589"
},
"metadata": {}
}
}
- Server processes the request, creates a task and responds (task completes quickly)
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"id": "363422be-b0f9-4692-a24d-278670e7c7f1",
"contextId": "c295ea44-7543-4f78-b524-7a38915ad6e4",
"status": {
"state": "completed"
},
"artifacts": [
{
"artifactId": "9b6934dd-37e3-4eb1-8766-962efaab63a1",
"name": "joke",
"parts": [
{
"kind": "text",
"text": "Why did the chicken cross the road? To get to the other side!"
}
]
}
],
"history": [
{
"role": "user",
"parts": [
{
"kind": "text",
"text": "tell me a joke"
}
],
"messageId": "9229e770-767c-417b-a0b0-f0741243c589",
"taskId": "363422be-b0f9-4692-a24d-278670e7c7f1",
"contextId": "c295ea44-7543-4f78-b524-7a38915ad6e4"
}
],
"kind": "task",
"metadata": {}
}
}
If the task were longer-running, the server might initially respond with status.state: "working". The client would then periodically call tasks/get with params: {"id": "363422be-b0f9-4692-a24d-278670e7c7f1"} until the task reaches a terminal state.
Scenario: Client asks a simple question, and the agent responds quickly without a task
- Client sends a message using
message/send:
{
"jsonrpc": "2.0",
"id": 1,
"method": "message/send",
"params": {
"message": {
"role": "user",
"parts": [
{
"kind": "text",
"text": "tell me a joke"
}
],
"messageId": "9229e770-767c-417b-a0b0-f0741243c589"
},
"metadata": {}
}
}
- Server processes the request, responds quickly without a task
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"messageId": "363422be-b0f9-4692-a24d-278670e7c7f1",
"contextId": "c295ea44-7543-4f78-b524-7a38915ad6e4",
"parts": [
{
"kind": "text",
"text": "Why did the chicken cross the road? To get to the other side!"
}
],
"kind": "message",
"metadata": {}
}
}
9.3. Streaming Task Execution (SSE)¶
Scenario: Client asks the agent to write a long paper describing an attached picture.
- Client sends a message and subscribes using
message/stream:
{
"jsonrpc": "2.0",
"id": 1,
"method": "message/stream",
"params": {
"message": {
"role": "user",
"parts": [
{
"kind": "text",
"text": "write a long paper describing the attached pictures"
},
{
"kind": "file",
"file": {
"mimeType": "image/png",
"data": "<base64-encoded-content>"
}
}
],
"messageId": "bbb7dee1-cf5c-4683-8a6f-4114529da5eb"
},
"metadata": {}
}
}
- Server responds with HTTP 200 OK,
Content-Type: text/event-stream, and starts sending SSE events:
Event 1: Task status update - working
data: {
"jsonrpc": "2.0",
"id": 1,
"result": {
"id": "225d6247-06ba-4cda-a08b-33ae35c8dcfa",
"contextId": "05217e44-7e9f-473e-ab4f-2c2dde50a2b1",
"status": {
"state": "submitted",
"timestamp":"2025-04-02T16:59:25.331844"
},
"history": [
{
"role": "user",
"parts": [
{
"kind": "text",
"text": "write a long paper describing the attached pictures"
},
{
"kind": "file",
"file": {
"mimeType": "image/png",
"data": "<base64-encoded-content>"
}
}
],
"messageId": "bbb7dee1-cf5c-4683-8a6f-4114529da5eb",
"taskId": "225d6247-06ba-4cda-a08b-33ae35c8dcfa",
"contextId": "05217e44-7e9f-473e-ab4f-2c2dde50a2b1"
}
],
"kind": "task",
"metadata": {}
}
}
data: {
"jsonrpc": "2.0",
"id": 1,
"result": {
"taskId": "225d6247-06ba-4cda-a08b-33ae35c8dcfa",
"contextId": "05217e44-7e9f-473e-ab4f-2c2dde50a2b1",
"artifact": {
"artifactId": "9b6934dd-37e3-4eb1-8766-962efaab63a1",
"parts": [
{"kind":"text", "text": "<section 1...>"}
]
},
"append": false,
"lastChunk": false,
"kind":"artifact-update"
}
}
data: {
"jsonrpc": "2.0",
"id": 1,
"result": {
"taskId": "225d6247-06ba-4cda-a08b-33ae35c8dcfa",
"contextId": "05217e44-7e9f-473e-ab4f-2c2dde50a2b1",
"artifact": {
"artifactId": "9b6934dd-37e3-4eb1-8766-962efaab63a1",
"parts": [
{"kind":"text", "text": "<section 2...>"}
],
},
"append": true,
"lastChunk": false,
"kind":"artifact-update"
}
}
data: {
"jsonrpc": "2.0",
"id": 1,
"result": {
"taskId": "225d6247-06ba-4cda-a08b-33ae35c8dcfa",
"contextId": "05217e44-7e9f-473e-ab4f-2c2dde50a2b1",
"artifact": {
"artifactId": "9b6934dd-37e3-4eb1-8766-962efaab63a1",
"parts": [
{"kind":"text", "text": "<section 3...>"}
]
},
"append": true,
"lastChunk": true,
"kind":"artifact-update"
}
}
data: {
"jsonrpc": "2.0",
"id": 1,
"result": {
"taskId": "225d6247-06ba-4cda-a08b-33ae35c8dcfa",
"contextId": "05217e44-7e9f-473e-ab4f-2c2dde50a2b1",
"status": {
"state": "completed",
"timestamp":"2025-04-02T16:59:35.331844"
},
"final": true,
"kind":"status-update"
}
}
(Server closes the SSE connection after the final:true event).
9.4. Multi-Turn Interaction (Input Required)¶
Scenario: Client wants to book a flight, and the agent needs more information.
- Client sends a message using
message/send:
{
"jsonrpc": "2.0",
"id": "req-003",
"method": "message/send",
"params": {
"message": {
"role": "user",
"parts": [{ "kind": "text", "text": "I'd like to book a flight." }]
},
"messageId": "c53ba666-3f97-433c-a87b-6084276babe2"
}
}
- Server responds, task state is
input-required:
{
"jsonrpc": "2.0",
"id": "req-003",
"result": {
"id": "3f36680c-7f37-4a5f-945e-d78981fafd36",
"contextId": "c295ea44-7543-4f78-b524-7a38915ad6e4",
"status": {
"state": "input-required",
"message": {
"role": "agent",
"parts": [
{
"kind": "text",
"text": "Sure, I can help with that! Where would you like to fly to, and from where? Also, what are your preferred travel dates?"
}
],
"messageId": "c2e1b2dd-f200-4b04-bc22-1b0c65a1aad2",
"taskId": "3f36680c-7f37-4a5f-945e-d78981fafd36",
"contextId": "c295ea44-7543-4f78-b524-7a38915ad6e4"
},
"timestamp": "2024-03-15T10:10:00Z"
},
"history": [
{
"role": "user",
"parts": [
{
"kind": "text",
"text": "I'd like to book a flight."
}
],
"messageId": "c53ba666-3f97-433c-a87b-6084276babe2",
"taskId": "3f36680c-7f37-4a5f-945e-d78981fafd36",
"contextId": "c295ea44-7543-4f78-b524-7a38915ad6e4"
}
],
"kind": "task"
}
}
- Client
message/send(providing the requested input, using the same task ID):
{
"jsonrpc": "2.0",
"id": "req-004",
"method": "message/send",
"params": {
"message": {
"role": "user",
"parts": [
{
"kind": "text",
"text": "I want to fly from New York (JFK) to London (LHR) around October 10th, returning October 17th."
}
],
"contextId": "c295ea44-7543-4f78-b524-7a38915ad6e4",
"taskId": "3f36680c-7f37-4a5f-945e-d78981fafd36",
"messageId": "0db1d6c4-3976-40ed-b9b8-0043ea7a03d3"
},
"configuration": {
"blocking": true
}
}
}
- Server processes the new input and responds (e.g., task completed or more input needed):
{
"jsonrpc": "2.0",
"id": "req-004",
"result": {
"id": "3f36680c-7f37-4a5f-945e-d78981fafd36",
"contextId": "c295ea44-7543-4f78-b524-7a38915ad6e4",
"status": {
"state": "completed",
"message": {
"role": "agent",
"parts": [
{
"kind": "text",
"text": "Okay, I've found a flight for you. Confirmation XYZ123. Details are in the artifact."
}
]
}
},
"artifacts": [
{
"artifactId": "9b6934dd-37e3-4eb1-8766-962efaab63a1",
"name": "FlightItinerary.json",
"parts": [
{
"kind": "data",
"data": {
"confirmationId": "XYZ123",
"from": "JFK",
"to": "LHR",
"departure": "2024-10-10T18:00:00Z",
"arrival": "2024-10-11T06:00:00Z",
"returnDeparture": "..."
}
}
]
}
],
"history": [
{
"role": "user",
"parts": [
{
"kind": "text",
"text": "I'd like to book a flight."
}
],
"messageId": "c53ba666-3f97-433c-a87b-6084276babe2",
"taskId": "3f36680c-7f37-4a5f-945e-d78981fafd36",
"contextId": "c295ea44-7543-4f78-b524-7a38915ad6e4"
},
{
"role": "agent",
"parts": [
{
"kind": "text",
"text": "Sure, I can help with that! Where would you like to fly to, and from where? Also, what are your preferred travel dates?"
}
],
"messageId": "c2e1b2dd-f200-4b04-bc22-1b0c65a1aad2",
"taskId": "3f36680c-7f37-4a5f-945e-d78981fafd36",
"contextId": "c295ea44-7543-4f78-b524-7a38915ad6e4"
},
{
"role": "user",
"parts": [
{
"kind": "text",
"text": "I want to fly from New York (JFK) to London (LHR) around October 10th, returning October 17th."
}
],
"contextId": "c295ea44-7543-4f78-b524-7a38915ad6e4",
"taskId": "3f36680c-7f37-4a5f-945e-d78981fafd36",
"messageId": "0db1d6c4-3976-40ed-b9b8-0043ea7a03d3"
}
],
"kind": "task",
"metadata": {}
}
}
9.5. Task Listing and Management¶
Scenario: Client wants to see all tasks from a specific context or all tasks with a particular status.
- Client requests all tasks from a specific context:
{
"jsonrpc": "2.0",
"id": "list-001",
"method": "tasks/list",
"params": {
"contextId": "c295ea44-7543-4f78-b524-7a38915ad6e4",
"pageSize": 10,
"historyLength": 3
}
}
- Server responds with matching tasks:
{
"jsonrpc": "2.0",
"id": "list-001",
"result": {
"tasks": [
{
"id": "3f36680c-7f37-4a5f-945e-d78981fafd36",
"contextId": "c295ea44-7543-4f78-b524-7a38915ad6e4",
"status": {
"state": "completed",
"timestamp": "2024-03-15T10:15:00Z"
},
"totalSize": 5,
"pageSize": 10,
"nextPageToken": ""
}
}
- Client requests all working tasks across all contexts:
{
"jsonrpc": "2.0",
"id": "list-002",
"method": "tasks/list",
"params": {
"status": "working",
"pageSize": 20
}
}
- Server responds with all currently working tasks:
{
"jsonrpc": "2.0",
"id": "list-002",
"result": {
"tasks": [
{
"id": "789abc-def0-1234-5678-9abcdef01234",
"contextId": "another-context-id",
"status": {
"state": "working",
"message": {
"role": "agent",
"parts": [
{
"kind": "text",
"text": "Processing your document analysis..."
}
],
"messageId": "msg-status-update"
},
"timestamp": "2024-03-15T10:20:00Z"
},
"kind": "task"
}
],
"totalSize": 1,
"pageSize": 20,
"nextPageToken": ""
}
}
- Continuing pagination - Client requests the next page using nextPageToken:
{
"jsonrpc": "2.0",
"id": "list-003",
"method": "tasks/list",
"params": {
"contextId": "c295ea44-7543-4f78-b524-7a38915ad6e4",
"pageSize": 10,
"pageToken": "<base64-encoded-cursor-token>"
}
}
- Server responds with the next page of results:
{
"jsonrpc": "2.0",
"id": "list-003",
"result": {
"tasks": [
// ... additional tasks
],
"totalSize": 15,
"pageSize": 10,
"nextPageToken": "<base64-encoded-cursor-token>"
}
}
- Error example - Client sends invalid parameters:
{
"jsonrpc": "2.0",
"id": "list-error-001",
"method": "tasks/list",
"params": {
"pageSize": 150,
"historyLength": -5,
"status": "running"
}
}
- Server responds with validation error:
{
"jsonrpc": "2.0",
"id": "list-error-001",
"error": {
"code": -32602,
"message": "Invalid params",
"data": {
"errors": [
{
"field": "pageSize",
"message": "Must be between 1 and 100 inclusive, got 150"
},
{
"field": "historyLength",
"message": "Must be non-negative integer, got -5"
},
{
"field": "status",
"message": "Invalid status value 'running'. Must be one of: pending, working, completed, failed, canceled"
}
]
}
}
}
9.6. Push Notification Setup and Usage¶
Scenario: Client requests a long-running report generation and wants to be notified via webhook when it's done.
- Client
message/sendwithpushNotificationconfig:
{
"jsonrpc": "2.0",
"id": "req-005",
"method": "message/send",
"params": {
"message": {
"role": "user",
"parts": [
{
"kind": "text",
"text": "Generate the Q1 sales report. This usually takes a while. Notify me when it's ready."
}
],
"messageId": "6dbc13b5-bd57-4c2b-b503-24e381b6c8d6"
},
"configuration": {
"pushNotificationConfig": {
"url": "https://client.example.com/webhook/a2a-notifications",
"token": "secure-client-token-for-task-aaa",
"authentication": {
"schemes": ["Bearer"]
// Assuming server knows how to get a Bearer token for this webhook audience,
// or this implies the webhook is public/uses the 'token' for auth.
// 'credentials' could provide more specifics if needed by the server.
}
}
}
}
}
- Server acknowledges the task (e.g., status
submittedorworking):
{
"jsonrpc": "2.0",
"id": "req-005",
"result": {
"id": "43667960-d455-4453-b0cf-1bae4955270d",
"contextId": "c295ea44-7543-4f78-b524-7a38915ad6e4",
"status": { "state": "submitted", "timestamp": "2024-03-15T11:00:00Z" }
// ... other fields ...
}
}
-
(Later) A2A Server completes the task and POSTs a notification to
https://client.example.com/webhook/a2a-notifications: -
HTTP Headers might include:
Authorization: Bearer <server_jwt_for_webhook_audience>(if server authenticates to webhook)Content-Type: application/jsonX-A2A-Notification-Token: secure-client-token-for-task-aaa
- HTTP Body (Task object is sent as JSON payload):
{
"id": "43667960-d455-4453-b0cf-1bae4955270d",
"contextId": "c295ea44-7543-4f78-b524-7a38915ad6e4",
"status": { "state": "completed", "timestamp": "2024-03-15T18:30:00Z" },
"kind": "task"
// ... other fields ...
}
-
Client's Webhook Service:
-
Receives the POST.
- Validates the
Authorizationheader (if applicable). - Validates the
X-A2A-Notification-Token. - Internally processes the notification (e.g., updates application state, notifies end user).
9.7. File Exchange (Upload and Download)¶
Scenario: Client sends an image for analysis, and the agent returns a modified image.
- Client
message/sendwith aFilePart(uploading image bytes):
{
"jsonrpc": "2.0",
"id": "req-007",
"method": "message/send",
"params": {
"message": {
"role": "user",
"parts": [
{
"kind": "text",
"text": "Analyze this image and highlight any faces."
},
{
"kind": "file",
"file": {
"name": "input_image.png",
"mimeType": "image/png",
"bytes": "iVBORw0KGgoAAAANSUhEUgAAAAUA..." // Base64 encoded image data
}
}
],
"messageId": "6dbc13b5-bd57-4c2b-b503-24e381b6c8d6"
}
}
}
- Server processes the image and responds with a
FilePartin an artifact (e.g., providing a URI to the modified image):
{
"jsonrpc": "2.0",
"id": "req-007",
"result": {
"id": "43667960-d455-4453-b0cf-1bae4955270d",
"contextId": "c295ea44-7543-4f78-b524-7a38915ad6e4",
"status": { "state": "completed", "timestamp": "2024-03-15T12:05:00Z" },
"artifacts": [
{
"artifactId": "9b6934dd-37e3-4eb1-8766-962efaab63a1",
"name": "processed_image_with_faces.png",
"parts": [
{
"kind": "file",
"file": {
"name": "output.png",
"mimeType": "image/png",
// Server might provide a URI to a temporary storage location
"uri": "https://storage.example.com/processed/task-bbb/output.png?token=xyz"
// Or, alternatively, it could return bytes directly:
// "bytes": "ASEDGhw0KGgoAAAANSUhEUgAA..."
}
}
]
}
],
"kind": "task"
}
}
9.8. Structured Data Exchange (Requesting and Providing JSON)¶
Scenario: Client asks for a list of open support tickets in a specific JSON format.
- Client
message/send,Part.metadatahints at desired output schema/Media Type: (Note: A2A doesn't formally standardize schema negotiation in v0.2.0, butmetadatacan be used for such hints by convention between client/server).
{
"jsonrpc": "2.0",
"id": 9,
"method": "message/send",
"params": {
"message": {
"role": "user",
"parts": [
{
"kind": "text",
"text": "Show me a list of my open IT tickets",
"metadata": {
"mimeType": "application/json",
"schema": {
"type": "array",
"items": {
"type": "object",
"properties": {
"ticketNumber": { "type": "string" },
"description": { "type": "string" }
}
}
}
}
}
],
"messageId": "85b26db5-ffbb-4278-a5da-a7b09dea1b47"
},
"metadata": {}
}
}
- Server responds with structured JSON data:
{
"jsonrpc": "2.0",
"id": 9,
"result": {
"id": "d8c6243f-5f7a-4f6f-821d-957ce51e856c",
"contextId": "c295ea44-7543-4f78-b524-7a38915ad6e4",
"status": {
"state": "completed",
"timestamp": "2025-04-17T17:47:09.680794"
},
"artifacts": [
{
"artifactId": "c5e0382f-b57f-4da7-87d8-b85171fad17c",
"parts": [
{
"kind": "text",
"text": "[{\"ticketNumber\":\"REQ12312\",\"description\":\"request for VPN access\"},{\"ticketNumber\":\"REQ23422\",\"description\":\"Add to DL - team-gcp-onboarding\"}]"
}
]
}
],
"kind": "task"
}
}
These examples illustrate the flexibility of A2A in handling various interaction patterns and data types. Implementers should refer to the detailed object definitions for all fields and constraints.
10. Appendices¶
10.1. Relationship to MCP (Model Context Protocol)¶
A2A and MCP are complementary protocols designed for different aspects of agentic systems:
- Model Context Protocol (MCP): Focuses on standardizing how AI models and agents connect to and interact with tools, APIs, data sources, and other external resources. It defines structured ways to describe tool capabilities (like function calling in LLMs), pass inputs, and receive structured outputs. Think of MCP as the "how-to" for an agent to use a specific capability or access a resource.
- Agent2Agent Protocol (A2A): Focuses on standardizing how independent, often opaque, AI agents communicate and collaborate with each other as peers. A2A provides an application-level protocol for agents to discover each other, negotiate interaction modalities, manage shared tasks, and exchange conversational context or complex results. It's about how agents partner or delegate work.
How they work together: An A2A Client agent might request an A2A Server agent to perform a complex task. The Server agent, in turn, might use MCP to interact with several underlying tools, APIs, or data sources to gather information or perform actions necessary to fulfill the A2A task.
For a more detailed comparison, see the A2A and MCP guide.
10.2. Security Considerations Summary¶
Security is a paramount concern in A2A. Key considerations include:
- Transport Security: Always use HTTPS with strong TLS configurations in production environments.
- Authentication:
- Handled via standard HTTP mechanisms (e.g.,
Authorizationheader with Bearer tokens, API keys). - Requirements are declared in the
AgentCard. - Credentials MUST be obtained out-of-band by the client.
- A2A Servers MUST authenticate every request.
- Handled via standard HTTP mechanisms (e.g.,
- Authorization:
- A server-side responsibility based on the authenticated identity.
- Implement the principle of least privilege.
- Can be granular, based on skills, actions, or data.
- Push Notification Security:
- Webhook URL validation (by the A2A Server sending notifications) is crucial to prevent SSRF.
- Authentication of the A2A Server to the client's webhook is essential.
- Authentication of the notification by the client's webhook receiver (verifying it came from the legitimate A2A Server and is relevant) is critical.
- See the Streaming & Asynchronous Operations guide for detailed push notification security.
- Input Validation: Servers MUST rigorously validate all RPC parameters and the content/structure of data in
MessageandArtifactparts to prevent injection attacks or processing errors. - Resource Management: Implement rate limiting, concurrency controls, and resource limits to protect agents from abuse or overload.
- Data Privacy: Adhere to all applicable privacy regulations for data exchanged in
MessageandArtifactparts. Minimize sensitive data transfer.
For a comprehensive discussion, refer to the Enterprise-Ready Features guide.
11. A2A Compliance Requirements¶
This section defines the normative requirements for A2A-compliant implementations.
11.1. Agent Compliance¶
For an agent to be considered A2A-compliant, it MUST:
11.1.1. Transport Support Requirements¶
- Support at least one transport: Agents MUST implement at least one transport protocols as defined in Section 3.2.
- Expose Agent Card: MUST provide a valid
AgentCarddocument as defined in Section 5. - Declare transport capabilities: MUST accurately declare all supported transports in the
AgentCardusingpreferredTransportandadditionalInterfacesfields following the requirements in Section 5.6.
11.1.2. Core Method Implementation¶
MUST implement all of the following core methods via at least one supported transport:
message/send- Send messages and initiate taskstasks/get- Retrieve task status and resultstasks/cancel- Request task cancellation
11.1.3. Optional Method Implementation¶
MAY implement the following optional methods:
message/stream- Streaming message interaction (requirescapabilities.streaming: true)tasks/resubscribe- Resume streaming for existing tasks (requirescapabilities.streaming: true)tasks/pushNotificationConfig/set- Configure push notifications (requirescapabilities.pushNotifications: true)tasks/pushNotificationConfig/get- Retrieve push notification config (requirescapabilities.pushNotifications: true)tasks/pushNotificationConfig/list- List push notification configs (requirescapabilities.pushNotifications: true)tasks/pushNotificationConfig/delete- Delete push notification config (requirescapabilities.pushNotifications: true)agent/authenticatedExtendedCard- Retrieve authenticated agent card (requiressupportsAuthenticatedExtendedCard: true)
11.1.4. Multi-Transport Compliance¶
If an agent supports additional transports (gRPC, HTTP+JSON), it MUST:
- Functional equivalence: Provide identical functionality across all supported transports.
- Consistent behavior: Return semantically equivalent results for the same operations.
- Transport-specific requirements: Conform to all requirements defined in Section 3.2 for each supported transport.
- Method mapping compliance: Use the standard method mappings defined in Section 3.5 for all supported transports.
11.1.5. Data Format Compliance¶
- JSON-RPC structure: MUST use valid JSON-RPC 2.0 request/response objects as defined in Section 6.11.
- A2A data objects: MUST use the data structures defined in Section 6 for all protocol entities.
- Error handling: MUST use the error codes defined in Section 8.
11.2. Client Compliance¶
For a client to be considered A2A-compliant, it MUST:
11.2.1. Transport Support¶
- Multi-transport capability: MUST be able to communicate with agents using at least one transport protocols.
- Agent Card processing: MUST be able to parse and interpret
AgentCarddocuments. - Transport selection: MUST be able to select an appropriate transport from the agent's declared capabilities following the rules defined in Section 5.6.3.
11.2.2. Protocol Implementation¶
- Core method usage: MUST properly construct requests for at least
message/sendandtasks/getmethods. - Error handling: MUST properly handle all A2A error codes defined in Section 8.2.
- Authentication: MUST support at least one authentication method when interacting with agents that require authentication.
11.2.3. Optional Client Features¶
Clients MAY implement:
- Multi-transport support: Support for gRPC and/or HTTP+JSON transports.
- Streaming support: Handle streaming methods and Server-Sent Events.
- Push notification handling: Serve as webhook endpoints for push notifications.
- Extended Agent Cards: Retrieve and use authenticated extended agent cards.
11.3. Compliance Testing¶
Implementations SHOULD validate compliance through:
- Transport interoperability: Test communication with agents using different transport implementations.
- Method mapping verification: Verify that all supported transports use the correct method names and URL patterns as defined in Section 3.5.
- Error handling: Verify proper handling of all defined error conditions.
- Data format validation: Ensure JSON schemas match the TypeScript type definitions in
types/src/types.ts. - Multi-transport consistency: For multi-transport agents, verify functional equivalence across all supported transports.