---
hide:
  - navigation
---

# Agent2Agent (A2A) Protocol Specification

**Version:** `{{ a2a_version }}`

See [Release Notes](https://github.com/a2aproject/A2A/releases) 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?](./topics/what-is-a2a.md).

## 2. Core Concepts Summary

A2A revolves around several key concepts. For detailed explanations, please refer to the [Key Concepts guide](./topics/key-concepts.md).

- **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 more `Parts`.
- **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](#324-transport-extensions)** 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](https://www.jsonrpc.org/specification)** 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-Type` header for HTTP requests and responses containing JSON-RPC payloads **MUST** be `application/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`](https://github.com/a2aproject/A2A/blob/main/specification/grpc/a2a.proto).
- **Message Serialization**: **MUST** use Protocol Buffers version 3 for message serialization.
- **Service Definition**: **MUST** implement the `A2AService` gRPC 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_name` annotations 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/json` for 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 OK` status and a `Content-Type` header of `text/event-stream`.
- The body of this HTTP response contains a stream of **[Server-Sent Events (SSE)](https://html.spec.whatwg.org/multipage/server-sent-events.html#server-sent-events)** as defined by the W3C.
- Each SSE `data` field contains a complete JSON-RPC 2.0 Response object (specifically, a [`SendStreamingMessageResponse`](#721-sendstreamingmessageresponse-object)).

#### 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](#8-error-handling).
- **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 `AgentCard` using the `preferredTransport` and `additionalInterfaces` fields.
- **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 `AgentCard` information.
- **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:

- `category` represents the resource type (e.g., "message", "tasks", "agent")
- `action` represents 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](./topics/enterprise-ready.md).

### 4.1. Transport Security

As stated in section 3.1, production deployments **MUST** use HTTPS. Implementations **SHOULD** use modern [TLS](https://datatracker.ietf.org/doc/html/rfc8446) 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

1. **Discovery of Requirements:** The client discovers the server's required authentication schemes via the `authentication` field in the [`AgentCard`](#55-agentcard-object-structure). Scheme names often align with [OpenAPI Authentication methods](https://swagger.io/docs/specification/authentication/) (e.g., "Bearer" for OAuth 2.0 tokens, "Basic" for Basic Auth, "ApiKey" for API keys).
2. **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.
3. **Credential Transmission:** The client includes these credentials in the appropriate [HTTP headers](https://developer.mozilla.org/en-US/docs/Web/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 Unauthorized`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/401) or [`403 Forbidden`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/403) for authentication challenges or rejections.
- **SHOULD** include relevant HTTP headers (e.g., [`WWW-Authenticate`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/WWW-Authenticate)) with `401 Unauthorized` responses to indicate the required authentication scheme(s), guiding the client.

### 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):

1. It **SHOULD** transition the A2A task to the `auth-required` state (see [`TaskState`](#63-taskstate-enum)).
2. The accompanying `TaskStatus.message` (often a [`DataPart`](#653-datapart-object)) **SHOULD** provide details about the required secondary authentication, potentially using an [`PushNotificationAuthenticationInfo`](#69-pushnotificationauthenticationinfo-object)-like structure to describe the need.
3. The A2A Client then obtains these new credentials out-of-band and provides them in a subsequent [`message/send`](#71-messagesend) or [`message/stream`](#72-messagestream) request. 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.id` from 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](./topics/agent-discovery.md).

### 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](#53-recommended-location)).
- **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](https://datatracker.ietf.org/doc/html/rfc8615) 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

```ts { .no-copy }
--8<-- "types/src/types.ts:AgentCard"
```

#### 5.5.1. `AgentProvider` Object

Information about the organization or entity providing the agent.

```ts { .no-copy }
--8<-- "types/src/types.ts:AgentProvider"
```

#### 5.5.2. `AgentCapabilities` Object

Specifies optional A2A protocol features supported by the agent.

```ts { .no-copy }
--8<-- "types/src/types.ts:AgentCapabilities"
```

#### 5.5.2.1. `AgentExtension` Object

Specifies an extension to the A2A protocol supported by the agent.

```ts { .no-copy }
--8<-- "types/src/types.ts:AgentExtension"
```

#### 5.5.3. `SecurityScheme` Object

Describes the authentication requirements for accessing the agent's `url` endpoint. Refer [Sample Agent Card](#57-sample-agent-card) for an example.

```ts { .no-copy }
--8<-- "types/src/types.ts:SecurityScheme"
```

#### 5.5.4. `AgentSkill` Object

Describes a specific capability, function, or area of expertise the agent can perform or address.

```ts { .no-copy }
--8<-- "types/src/types.ts: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.

```ts { .no-copy }
--8<-- "types/src/types.ts:TransportProtocol"
```

```ts { .no-copy }
--8<-- "types/src/types.ts: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.

```ts { .no-copy }
--8<-- "types/src/types.ts: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 `url` field **MUST** specify the primary endpoint for the agent.
- **Transport correspondence**: The transport protocol available at the main `url` **MUST** match the `preferredTransport` field.
- **Required declaration**: The `preferredTransport` field is **REQUIRED** and **MUST** be present in every `AgentCard`.
- **Transport availability**: The main `url` **MUST** support the transport protocol declared in `preferredTransport`.

#### 5.6.2. Additional Interfaces

- **URL uniqueness**: Each `AgentInterface` in `additionalInterfaces` **SHOULD** specify a distinct URL for clarity, but **MAY** reuse URLs if multiple transport protocols are available at the same endpoint.
- **Transport declaration**: Each `AgentInterface` **MUST** accurately declare the transport protocol available at its specified URL.
- **Completeness**: The `additionalInterfaces` array **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:

1. **Parse transport declarations**: Extract available transports from both the main `url`/`preferredTransport` combination and all `additionalInterfaces`.
2. **Prefer declared preference**: If the client supports the `preferredTransport`, it **SHOULD** use the main `url`.
3. **Fallback selection**: If the preferred transport is not supported by the client, it **MAY** select any supported transport from `additionalInterfaces`.
4. **Graceful degradation**: Clients **SHOULD** implement fallback logic to try alternative transports if their first choice fails.
5. **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 `preferredTransport` value **MUST** be present and **MUST** be available at the main `url`.
- **Interface completeness**: If `additionalInterfaces` is provided, it **SHOULD** include an entry corresponding to the main `url` and `preferredTransport`.
- **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`/`preferredTransport` combination or `additionalInterfaces`.

### 5.7. Sample Agent Card

```json
{
  "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](./topics/life-of-a-task.md).

```ts { .no-copy }
--8<-- "types/src/types.ts:Task"
```

### 6.2. `TaskStatus` Object

Represents the current state and associated context (e.g., a message from the agent) of a `Task`.

```ts { .no-copy }
--8<-- "types/src/types.ts:TaskStatus"
```

### 6.3. `TaskState` Enum

Defines the possible lifecycle states of a `Task`.

```ts { .no-copy }
--8<-- "types/src/types.ts: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.

```ts { .no-copy }
--8<-- "types/src/types.ts: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.

```ts { .no-copy }
--8<-- "types/src/types.ts:Part"
```

```ts { .no-copy }
--8<-- "types/src/types.ts:PartBase"
```

It **MUST** be one of the following:

#### 6.5.1. `TextPart` Object

For conveying plain textual content.

```ts { .no-copy }
--8<-- "types/src/types.ts:TextPart"
```

#### 6.5.2. `FilePart` Object

For conveying file-based content.

```ts { .no-copy }
--8<-- "types/src/types.ts:FilePart"
```

#### 6.5.3. `DataPart` Object

For conveying structured JSON data. Useful for forms, parameters, or any machine-readable information.

```ts { .no-copy }
--8<-- "types/src/types.ts:DataPart"
```

### 6.6 `FileBase` Object

Base entity for File Contents.

```ts { .no-copy }
--8<-- "types/src/types.ts:FileBase"
```

#### 6.6.1 `FileWithBytes` Object

Represents the data for a file, used within a `FilePart`.

```ts { .no-copy }
--8<-- "types/src/types.ts:FileWithBytes"
```

#### 6.6.2 `FileWithUri` Object

Represents the URI for a file, used within a `FilePart`.

```ts { .no-copy }
--8<-- "types/src/types.ts:FileWithUri"
```

### 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.

```ts { .no-copy }
--8<-- "types/src/types.ts:Artifact"
```

### 6.8. `PushNotificationConfig` Object

Configuration provided by the client to the server for sending asynchronous push notifications about task updates.

```ts { .no-copy }
--8<-- "types/src/types.ts: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.

```ts { .no-copy }
--8<-- "types/src/types.ts:PushNotificationAuthenticationInfo"
```

### 6.10. `TaskPushNotificationConfig` Object

Used as the `params` object for the [`tasks/pushNotificationConfig/set`](#75-taskspushnotificationconfigset) method and as the `result` object for the [`tasks/pushNotificationConfig/get`](#76-taskspushnotificationconfigget) method.

```ts { .no-copy }
--8<-- "types/src/types.ts:TaskPushNotificationConfig"
```

### 6.11. JSON-RPC Structures

A2A adheres to the standard [JSON-RPC 2.0](https://www.jsonrpc.org/specification) 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 an `object` for `params`.
- `id`: An identifier established by the Client that **MUST** contain a String, Number, or `NULL` value if included. If it is not included it is assumed to be a notification. The value **SHOULD NOT** be `NULL` for 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, so `id` will 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 the `id` member in the Request Object. If there was an error in detecting the `id` in the Request object (e.g. Parse error/Invalid Request), it **MUST** be `null`.
- **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 an [`JSONRPCError`](#612-jsonrpcerror-object) object.
- The members `result` and `error` are 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.

```ts { .no-copy }
--8<-- "types/src/types.ts:JSONRPCError"
```

## 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](./topics/life-of-a-task.md).

<div class="grid cards" markdown>

=== "JSON-RPC"
    -   **URL:** `message/send`
    -   **HTTP Method:** `POST`
    -   **Payload**: [`MessageSendParams`](#711-messagesendparams-object)
    -   **Response**: [`Task` | `Message`](#61-task-object) (A message object or the current or final state of the task after processing the message).

=== "gRPC"
    -   **URL:** `SendMessage`
    -   **HTTP Method:** `POST`
    -   **Payload:**
        ```proto
        message SendMessageRequest {
          Message msg = 1;
          SendMessageConfiguration configuration = 2;
        }
        ```
    -   **Response:**
        ```proto
        message SendMessageResponse {
          oneof payload {
            Task task = 1;
            Message msg = 2;
          }
        }
        ```

=== "REST"
    -   **URL:** `/v1/message:send`
    -   **HTTP Method:** `POST`
    -   **Payload:**
        ```typescript
        {
          message: Message,
          configuration?: MessageSendConfiguration,
          metadata?: { [key: string]: any }
        }
        ```
    -   **Response:**
        ```typescript
        // Returns one of a message or a task
        {
          message?: Message,
          task?: Task
        }
        ```

</div>

The `error` response for all transports in case of failure is a [`JSONRPCError`](#612-jsonrpcerror-object) or equivalent.

#### 7.1.1. `MessageSendParams` Object

```ts { .no-copy }
--8<-- "types/src/types.ts:MessageSendParams"

--8<-- "types/src/types.ts: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](./topics/life-of-a-task.md).

<div class="grid cards" markdown>

=== "JSON-RPC"
    -   **URL:** `message/stream`
    -   **HTTP Method:** `POST`
    -   **Payload**: [`MessageSendParams`](#711-messagesendparams-object) (same as `message/send`)
    -   **Response**: A stream of Server-Sent Events. Each SSE `data` field contains a [`SendStreamingMessageResponse`](#721-sendstreamingmessageresponse-object)

=== "gRPC"
    -   **URL:** `SendStreamingMessage`
    -   **HTTP Method:** `POST`
    -   **Payload:**
        ```proto
        message SendMessageRequest {
          Message msg = 1;
          SendMessageConfiguration configuration = 2;
        }
        ```
    -   **Response:**
        ```proto
        message StreamResponse {
          oneof payload {
            Task task;
            Message msg;
            TaskStatusUpdateEvent status_update;
            TaskArtifactUpdateEvent artifact_update;
          }
        }
        ```

=== "REST"
    -   **URL:** `/v1/message:stream`
    -   **HTTP Method:** `POST`
    -   **Payload:**
        ```typescript
        {
          message: Message,
          configuration?: MessageSendConfiguration,
          metadata?: { [key: string]: any }
        }
        ```
    -   **Response:**
        ```typescript
        {
          message?: Message
          task?: Task
          statusUpdate?: TaskStatusUpdateEvent
          artifactUpdate?: TaskArtifactUpdateEvent
        }
        ```

</div>

#### 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.

```ts { .no-copy }
--8<-- "types/src/types.ts:SendStreamingMessageResponse"

--8<-- "types/src/types.ts: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`.

```ts { .no-copy }
--8<-- "types/src/types.ts: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`.

```ts { .no-copy }
--8<-- "types/src/types.ts: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.

<div class="grid cards" markdown>

=== "JSON-RPC"
    -   **URL:** `tasks/get`
    -   **HTTP Method:** `POST`
    -   **Payload**: [`TaskQueryParams`](#731-taskqueryparams-object)
    -   **Response**: `Task`

=== "gRPC"
    -   **URL:** `GetTask`
    -   **HTTP Method:** `POST`
    -   **Payload:**
        ```proto
        message GetTaskRequest {
          // name=tasks/{id}
          string name;
          int32 history_length;
        }
        ```
    -   **Response**: `Task`

=== "REST"
    -   **URL:** `v1/tasks/{id}?historyLength={historyLength}`
    -   **HTTP Method:** `GET`
    -   **Payload:** None
    -   **Response**: `Task`

</div>

#### 7.3.1. `TaskQueryParams` Object

```ts { .no-copy }
--8<-- "types/src/types.ts:TaskQueryParams"
```

### `tasks/list`

<div class="grid cards" markdown>

=== "JSON-RPC"
    -  N/A

=== "gRPC"
    -   **URL:** `ListTask`
    -   **HTTP Method:** `GET`
    -   **Payload:**
        ```proto
        {}
        ```
    -   **Response**: `repeated Task`

=== "REST"
    -   **URL:** `/v1/tasks`
    -   **HTTP Method:** `GET`
    -   **Payload:**
        ```typescript
        {}
        ```
    -   **Response**: `[Task]`

</div>

### 7.4. `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).

<div class="grid cards" markdown>

=== "JSON-RPC"
    -   **URL:** `tasks/cancel`
    -   **HTTP Method:** `POST`
    -   **Payload**: [`TaskIdParams`](#741-taskidparams-object-for-taskscancel-and-taskspushnotificationconfigget)
    -   **Response**: `Task`

=== "gRPC"
    -   **URL:** `CancelTask`
    -   **HTTP Method:** `POST`
    -   **Payload:**
        ```proto
        message CancelTaskRequest{
          // name=tasks/{id}
          string name;
        }
        ```
    -   **Response**: `Task`

=== "REST"
    -   **URL:** `/v1/tasks/{id}:cancel`
    -   **HTTP Method:** `POST`
    -   **Payload:**
        ```typescript
        {
          name: string
        }
        ```
    -   **Response**: `Task`

</div>

#### 7.4.1. `TaskIdParams` Object (for `tasks/cancel` and `tasks/pushNotificationConfig/get`)

A simple object containing just the task ID and optional metadata.

```ts { .no-copy }
--8<-- "types/src/types.ts:TaskIdParams"
```

### 7.5. `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`.

<div class="grid cards" markdown>

=== "JSON-RPC"
    -   **URL:** `tasks/pushNotificationConfig/set`
    -   **HTTP Method:** `POST`
    -   **Payload**: [`TaskPushNotificationConfig`](#610-taskpushnotificationconfig-object)
    -   **Response**: [`TaskPushNotificationConfig`](#610-taskpushnotificationconfig-object)

=== "gRPC"
    -   **URL:** `CreateTaskPushNotification`
    -   **HTTP Method:** `POST`
    -   **Payload:**
        ```proto
        message SetTaskPushNotificationRequest {
          TaskPushNotificationConfig config = 1;
        }
        ```
    -   **Response**: `TaskPushNotificationConfig`

=== "REST"
    -   **URL:** `/v1/tasks/{id}/pushNotificationConfigs`
    -   **HTTP Method:** `POST`
    -   **Payload:**
        ```typescript
        {
          config: TaskPushNotificationConfig
        }
        ```
    -   **Response**: `TaskPushNotificationConfig`

</div>

### 7.6. `tasks/pushNotificationConfig/get`

Retrieves the current push notification configuration for a specified task. Requires the server to have `AgentCard.capabilities.pushNotifications: true`.

<div class="grid cards" markdown>

=== "JSON-RPC"
    -   **URL:** `tasks/pushNotificationConfig/get`
    -   **HTTP Method:** `POST`
    -   **Payload**: [`GetTaskPushNotificationConfigParams`](#761-gettaskpushnotificationconfigparams-object-taskspushnotificationconfigget)
    -   **Response**: [`TaskPushNotificationConfig`](#610-taskpushnotificationconfig-object)

=== "gRPC"
    -   **URL:** `GetTaskPushNotification`
    -   **HTTP Method:** `POST`
    -   **Payload:**
        ```proto
        message TaskSubscriptionRequest {
          // name=tasks/{id}/pushNotification/{id}
          string name;
        }
        ```
    -   **Response**: `TaskPushNotificationConfig`

=== "REST"
    -   **URL:** `/v1/tasks/{taskId}/pushNotificationConfigs/{configId}`
    -   **HTTP Method:** `GET`
    -   **Payload:** None
    -   **Response**: `TaskPushNotificationConfig`

</div>

**Response `error` type (on failure)**: [`JSONRPCError`](#612-jsonrpcerror-object) (e.g., [`PushNotificationNotSupportedError`](#82-a2a-specific-errors), [`TaskNotFoundError`](#82-a2a-specific-errors)).

#### 7.6.1. `GetTaskPushNotificationConfigParams` Object (`tasks/pushNotificationConfig/get`)

A object for fetching the push notification configuration for a task.

```ts { .no-copy }
--8<-- "types/src/types.ts:GetTaskPushNotificationConfigParams"
```

### 7.7. `tasks/pushNotificationConfig/list`

Retrieves the associated push notification configurations for a specified task. Requires the server to have `AgentCard.capabilities.pushNotifications: true`.

<div class="grid cards" markdown>

=== "JSON-RPC"
    -   **URL:** `tasks/pushNotificationConfig/list`
    -   **HTTP Method:** `POST`
    -   **Payload:** [`ListTaskPushNotificationConfigParams`](#771-listtaskpushnotificationconfigparams-object-taskspushnotificationconfiglist)
    -   **Response**: `TaskPushNotificationConfig[]`

=== "gRPC"
    -   **URL:** `ListTaskPushNotification`
    -   **HTTP Method:** `POST`
    -   **Payload:**
        ```proto
        message ListTaskPushNotificationRequest {
          // parent=tasks/{id}
          string parent = 1;
        }
        ```
    -   **Response**: `repeated TaskPushNotificationConfig`

=== "REST"
    -   **URL:** `/v1/tasks/{id}/pushNotificationConfigs`
    -   **HTTP Method:** `GET`
    -   **Payload:**: None
    -   **Response**: `[TaskPushNotificationConfig]`

</div>

#### 7.7.1. `ListTaskPushNotificationConfigParams` Object (`tasks/pushNotificationConfig/list`)

A object for fetching the push notification configurations for a task.

```ts { .no-copy }
--8<-- "types/src/types.ts:ListTaskPushNotificationConfigParams"
```

### 7.8. `tasks/pushNotificationConfig/delete`

Deletes an associated push notification configuration for a task. Requires the server to have `AgentCard.capabilities.pushNotifications: true`.

- **Request `params` type**: [`DeleteTaskPushNotificationConfigParams`](#781-deletetaskpushnotificationconfigparams-object-taskspushnotificationconfigdelete)
- **Response `result` type (on success)**: [`null`]
- **Response `error` type (on failure)**: [`JSONRPCError`](#612-jsonrpcerror-object) (e.g., [`PushNotificationNotSupportedError`](#82-a2a-specific-errors), [`TaskNotFoundError`](#82-a2a-specific-errors)).

#### 7.8.1. `DeleteTaskPushNotificationConfigParams` Object (`tasks/pushNotificationConfig/delete`)

A object for deleting an associated push notification configuration for a task.

```ts { .no-copy }
--8<-- "types/src/types.ts:DeleteTaskPushNotificationConfigParams"
```

### 7.9. `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.

<div class="grid cards" markdown>

=== "JSON-RPC"
    -   **URL:** `tasks/resubscribe`
    -   **HTTP Method:** `POST`
    -   **Payload**: [`TaskIdParams`](#741-taskidparams-object-for-taskscancel-and-taskspushnotificationconfigget)
    -   **Response**: A stream of Server-Sent Events. Each SSE `data` field contains a [`SendStreamingMessageResponse`](#721-sendstreamingmessageresponse-object)

=== "gRPC"
    -   **URL:** `TaskSubscription`
    -   **HTTP Method:** `POST`
    -   **Payload:**
        ```proto
        message TaskSubscriptionRequest{
          // name=tasks/{id}
          string name;
        }
        ```
    -   **Response:**
        ```proto
        message StreamResponse {
          oneof payload {
            Task task;
            Message msg;
            TaskStatusUpdateEvent status_update;
            TaskArtifactUpdateEvent artifact_update;
          }
        }
        ```

=== "REST"
    -   **URL:** `/v1/tasks/{id}:subscribe`
    -   **HTTP Method:** `POST`
    -   **Payload:**
        ```typescript
        {
          name: string
        }
        ```
    -   **Response:**
        ```typescript
        {
          message?: Message
          task?: Task
          statusUpdate?: TaskStatusUpdateEvent
          artifactUpdate?: TaskArtifactUpdateEvent
        }
        ```

</div>

### 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.securitySchemes` and `AgentCard.security` fields.
- **Response `result` type (on success)**: `AgentCard` (A complete Agent Card object, which may contain additional details or skills not present in the public card).
- **Response `error` type (on failure)**: Standard HTTP error codes.
    - `401 Unauthorized`: Authentication failed (missing or invalid credentials). The server **SHOULD** include a `WWW-Authenticate` header.

<div class="grid cards" markdown>

=== "JSON-RPC"
    -   **URL:** `agent/getAuthenticatedExtendedCard`
    -   **HTTP Method:** `POST`
    -   **Payload:** None
    -   **Response:** `AgentCard`

=== "gRPC"
    -   **URL:** `GetAgentCard`
    -   **HTTP Method:** `POST`
    -   **Payload:** None
    -   **Response:** `AgentCard`

=== "REST"
    -   **URL:** `/v1/card`
    -   **HTTP Method:** `GET`
    -   **Payload:** None
    -   **Response:** `AgentCard`

</div>

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.

```ts { .no-copy }
--8<-- "types/src/types.ts:GetAuthenticatedExtendedCardSuccessResponse"
```

## 8. Error Handling

A2A uses standard [JSON-RPC 2.0 error codes and structure](https://www.jsonrpc.org/specification#error_object) for reporting errors. Errors are returned in the `error` member of the `JSONRPCErrorResponse` object. See [`JSONRPCError` Object definition](#612-jsonrpcerror-object).

### 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](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types) 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.

1. **Client fetches the public Agent Card:**

   ```none
   GET https://example.com/.well-known/agent-card.json
   ```

   _Server responds with the public Agent Card (like the example in Section 5.6), including `supportsAuthenticatedExtendedCard: true` (at the root level) and `securitySchemes`._

2. **Client identifies required authentication from the public card.**

3. **Client obtains necessary credentials out-of-band (e.g., performs OAuth 2.0 flow with Google, resulting in an access token).**

4. **Client fetches the authenticated extended Agent Card using `agent/getAuthenticatedExtendedCard` request:**

   ```json
   {
     "jsonrpc": "2.0",
     "id": 1,
     "method": "agent/getAuthenticatedExtendedCard"
   }
   ```

5. **Server authenticates and authorizes the request.**

6. **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

1. **Client sends a message using `message/send`:**

   ```json
   {
     "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": {}
     }
   }
   ```

2. **Server processes the request, creates a task and responds (task completes quickly)**

   ```json
   {
     "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

1. **Client sends a message using `message/send`:**

   ```json
   {
     "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": {}
     }
   }
   ```

2. **Server processes the request, responds quickly without a task**

   ```json
   {
     "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.

1. **Client sends a message and subscribes using `message/stream`:**

   ```json
   {
     "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": {}
     }
   }
   ```

2. **Server responds with HTTP 200 OK, `Content-Type: text/event-stream`, and starts sending SSE events:**

   _Event 1: Task status update - working_

   ```json
   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.

1. **Client sends a message using `message/send`:**

   ```json
   {
     "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"
     }
   }
   ```

2. **Server responds, task state is `input-required`:**

   ```json
   {
     "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"
     }
   }
   ```

3. **Client `message/send` (providing the requested input, using the _same_ task ID):**

   ```json
   {
     "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
       }
     }
   }
   ```

4. **Server processes the new input and responds (e.g., task completed or more input needed):**

   ```json
   {
     "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. Push Notification Setup and Usage

**Scenario:** Client requests a long-running report generation and wants to be notified via webhook when it's done.

1. **Client `message/send` with `pushNotification` config:**

   ```json
   {
     "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.
           }
         }
       }
     }
   }
   ```

2. **Server acknowledges the task (e.g., status `submitted` or `working`):**

   ```json
   {
     "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 ...
     }
   }
   ```

3. **(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/json`
     - `X-A2A-Notification-Token: secure-client-token-for-task-aaa`
   - **HTTP Body (Task object is sent as JSON payload):**

   ```json
   {
     "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 ...
   }
   ```

4. **Client's Webhook Service:**

   - Receives the POST.
   - Validates the `Authorization` header (if applicable).
   - Validates the `X-A2A-Notification-Token`.
   - Internally processes the notification (e.g., updates application state, notifies end user).

### 9.6. File Exchange (Upload and Download)

**Scenario:** Client sends an image for analysis, and the agent returns a modified image.

1. **Client `message/send` with a `FilePart` (uploading image bytes):**

   ```json
   {
     "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"
       }
     }
   }
   ```

2. **Server processes the image and responds with a `FilePart` in an artifact (e.g., providing a URI to the modified image):**

   ```json
   {
     "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.7. Structured Data Exchange (Requesting and Providing JSON)

**Scenario:** Client asks for a list of open support tickets in a specific JSON format.

1. **Client `message/send`, `Part.metadata` hints at desired output schema/Media Type:**
   _(Note: A2A doesn't formally standardize schema negotiation in v0.2.0, but `metadata` can be used for such hints by convention between client/server)._

   ```json
   {
     "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": {}
     }
   }
   ```

2. **Server responds with structured JSON data:**

   ```json
   {
     "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)](https://modelcontextprotocol.io/):** 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](./topics/a2a-and-mcp.md).

### 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., `Authorization` header 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.
- **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](./topics/streaming-and-async.md#security-considerations-for-push-notifications) for detailed push notification security.
- **Input Validation:** Servers MUST rigorously validate all RPC parameters and the content/structure of data in `Message` and `Artifact` parts 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 `Message` and `Artifact` parts. Minimize sensitive data transfer.

For a comprehensive discussion, refer to the [Enterprise-Ready Features guide](./topics/enterprise-ready.md).

## 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](#32-supported-transport-protocols).
- **Expose Agent Card**: **MUST** provide a valid `AgentCard` document as defined in [Section 5](#5-agent-discovery-the-agent-card).
- **Declare transport capabilities**: **MUST** accurately declare all supported transports in the `AgentCard` using `preferredTransport` and `additionalInterfaces` fields following the requirements in [Section 5.6](#56-transport-declaration-and-url-relationships).

#### 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 tasks
- `tasks/get` - Retrieve task status and results
- `tasks/cancel` - Request task cancellation

#### 11.1.3. Optional Method Implementation

**MAY** implement the following optional methods:

- `message/stream` - Streaming message interaction (requires `capabilities.streaming: true`)
- `tasks/resubscribe` - Resume streaming for existing tasks (requires `capabilities.streaming: true`)
- `tasks/pushNotificationConfig/set` - Configure push notifications (requires `capabilities.pushNotifications: true`)
- `tasks/pushNotificationConfig/get` - Retrieve push notification config (requires `capabilities.pushNotifications: true`)
- `tasks/pushNotificationConfig/list` - List push notification configs (requires `capabilities.pushNotifications: true`)
- `tasks/pushNotificationConfig/delete` - Delete push notification config (requires `capabilities.pushNotifications: true`)
- `agent/authenticatedExtendedCard` - Retrieve authenticated agent card (requires `supportsAuthenticatedExtendedCard: 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](#32-supported-transport-protocols) for each supported transport.
- **Method mapping compliance**: Use the standard method mappings defined in [Section 3.5](#35-method-mapping-and-naming-conventions) 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](#611-json-rpc-structures).
- **A2A data objects**: **MUST** use the data structures defined in [Section 6](#6-protocol-data-objects) for all protocol entities.
- **Error handling**: **MUST** use the error codes defined in [Section 8](#8-error-handling).

### 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 `AgentCard` documents.
- **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](#563-client-transport-selection-rules).

#### 11.2.2. Protocol Implementation

- **Core method usage**: **MUST** properly construct requests for at least `message/send` and `tasks/get` methods.
- **Error handling**: **MUST** properly handle all A2A error codes defined in [Section 8.2](#82-a2a-specific-errors).
- **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](#35-method-mapping-and-naming-conventions).
- **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`](https://github.com/a2aproject/A2A/blob/main/types/src/types.ts).
- **Multi-transport consistency**: For multi-transport agents, verify functional equivalence across all supported transports.
