---
hide:
  - navigation
---

# Agent2Agent (A2A) Protocol Specification

**Version:** `0.1.0`

## 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.
- **Task:** The fundamental unit of work managed by A2A, identified by a unique ID. Tasks are stateful and progress through a defined lifecycle.
- **Message:** A communication turn within a Task, having a `role` ("user" or "agent") and containing one or more `Parts`.
- **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.
- **Session:** An optional, client-generated identifier to logically group related tasks.

## 3. Transport and Format

### 3.1. Transport Protocol

- A2A communication **MUST** occur over **HTTP(S)**.
- The A2A Server exposes its service at a URL defined in its `AgentCard`.

### 3.2. Data Format

A2A uses **[JSON-RPC 2.0](https://www.jsonrpc.org/specification)** as the payload format for all requests and responses (excluding the 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`.

### 3.3. Streaming Transport (Server-Sent Events)

When streaming is used for methods like `tasks/sendSubscribe` 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 [`SendTaskStreamingResponse`](#721-sendtaskstreamingresponse-object)).

## 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.2+ 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 `input-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 [`AuthenticationInfo`](#69-authenticationinfo-object-for-push-notifications)-like structure to describe the need.
3. The A2A Client then obtains these new credentials out-of-band and provides them in a subsequent [`tasks/send`](#71-taskssend) or [`tasks/sendSubscribe`](#72-taskssendsubscribe) 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.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 (e.g., the URL of an internal-only agent, or scheme-specific information in `authentication.credentials`).

- 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. If `authentication.credentials` is used, it should be for non-secret information like OAuth flow URLs or API key _names_ (not values).

### 5.5. `AgentCard` Object Structure

```typescript
// An AgentCard conveys key information about an A2A Server:
// - Overall identity and descriptive details.
// - Service endpoint URL.
// - Supported A2A protocol capabilities (streaming, push notifications).
// - Authentication requirements.
// - Default input/output content types (MIME types).
// - A list of specific skills the agent offers.
interface AgentCard {
  // Human-readable name of the agent (e.g., "Recipe Advisor Agent").
  name: string;
  // A human-readable description of the agent and its general purpose.
  // [CommonMark](https://commonmark.org/) MAY be used for rich text formatting.
  // (e.g., "This agent helps users find recipes, plan meals, and get cooking instructions.")
  description?: string | null;
  // The base URL endpoint for the agent's A2A service (where JSON-RPC requests are sent).
  // Must be an absolute HTTPS URL for production (e.g., `https://agent.example.com/a2a/api`).
  // HTTP MAY be used for local development/testing only.
  url: string;
  // Information about the organization or entity providing the agent.
  provider?: AgentProvider | null;
  // Version string for the agent or its A2A implementation
  // (format is defined by the provider, e.g., "1.0.0", "2023-10-26-beta").
  version: string;
  // URL pointing to human-readable documentation for the agent (e.g., API usage, detailed skill descriptions).
  documentationUrl?: string | null;
  // Specifies optional A2A protocol features supported by this agent.
  capabilities: AgentCapabilities;
  // Authentication schemes required to interact with the agent's `url` endpoint.
  // If `null`, omitted, or an empty `schemes` array, no A2A-level authentication is explicitly advertised
  // (NOT recommended for production; other security like network ACLs might still apply).
  authentication?: AgentAuthentication | null;
  // Array of [MIME types](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types)
  // the agent generally accepts as input across all skills, unless overridden by a specific skill.
  // Default if omitted: `["text/plain"]`. Example: `["text/plain", "image/png"]`.
  defaultInputModes?: string[];
  // Array of MIME types the agent generally produces as output across all skills, unless overridden by a specific skill.
  // Default if omitted: `["text/plain"]`. Example: `["text/plain", "application/json"]`.
  defaultOutputModes?: string[];
  // An array of specific skills or capabilities the agent offers.
  // Must contain at least one skill if the agent is expected to perform actions beyond simple presence.
  skills: AgentSkill[];
}
```

| Field Name           | Type                                                               | Required | Description                                                                                                       |
| :------------------- | :----------------------------------------------------------------- | :------- | :---------------------------------------------------------------------------------------------------------------- |
| `name`               | `string`                                                           | Yes      | Human-readable name of the agent.                                                                                 |
| `description`        | `string` \| `null`                                                 | No       | Human-readable description. [CommonMark](https://commonmark.org/) MAY be used.                                    |
| `url`                | `string`                                                           | Yes      | Base URL for the agent's A2A service. Must be absolute. HTTPS for production.                                     |
| `provider`           | [`AgentProvider`](#551-agentprovider-object) \| `null`             | No       | Information about the agent's provider.                                                                           |
| `version`            | `string`                                                           | Yes      | Agent or A2A implementation version string.                                                                       |
| `documentationUrl`   | `string` \| `null`                                                 | No       | URL to human-readable documentation for the agent.                                                                |
| `capabilities`       | [`AgentCapabilities`](#552-agentcapabilities-object)               | Yes      | Specifies optional A2A protocol features supported (e.g., streaming, push notifications).                         |
| `authentication`     | [`AgentAuthentication`](#553-agentauthentication-object) \| `null` | No       | Authentication schemes required. `null` or empty implies no A2A-advertised auth (not recommended for production). |
| `defaultInputModes`  | `string[]`                                                         | No       | Default accepted input MIME types. Defaults to `["text/plain"]` if omitted.                                       |
| `defaultOutputModes` | `string[]`                                                         | No       | Default produced output MIME types. Defaults to `["text/plain"]` if omitted.                                      |
| `skills`             | [`AgentSkill[]`](#554-agentskill-object)                           | Yes      | Array of skills. Must have at least one if the agent performs actions.                                            |

#### 5.5.1. `AgentProvider` Object

Information about the organization or entity providing the agent.

```typescript
interface AgentProvider {
  // Name of the organization or entity.
  organization: string;
  // URL for the provider's organization website or relevant contact page.
  url?: string | null;
}
```

| Field Name     | Type               | Required | Description                             |
| :------------- | :----------------- | :------- | :-------------------------------------- |
| `organization` | `string`           | Yes      | Name of the organization/entity.        |
| `url`          | `string` \| `null` | No       | URL for the provider's website/contact. |

#### 5.5.2. `AgentCapabilities` Object

Specifies optional A2A protocol features supported by the agent.

```typescript
interface AgentCapabilities {
  // If `true`, the agent supports `tasks/sendSubscribe` and `tasks/resubscribe` for real-time
  // updates via Server-Sent Events (SSE). Default: `false`.
  streaming?: boolean;
  // If `true`, the agent supports `tasks/pushNotification/set` and `tasks/pushNotification/get`
  // for asynchronous task updates via webhooks. Default: `false`.
  pushNotifications?: boolean;
  // If `true`, the agent may include a detailed history of status changes
  // within the `Task` object (future enhancement; specific mechanism TBD). Default: `false`.
  stateTransitionHistory?: boolean;
}
```

| Field Name               | Type      | Required | Default | Description                                                                               |
| :----------------------- | :-------- | :------- | :------ | :---------------------------------------------------------------------------------------- |
| `streaming`              | `boolean` | No       | `false` | Indicates support for SSE streaming methods (`tasks/sendSubscribe`, `tasks/resubscribe`). |
| `pushNotifications`      | `boolean` | No       | `false` | Indicates support for push notification methods (`tasks/pushNotification/*`).             |
| `stateTransitionHistory` | `boolean` | No       | `false` | Placeholder for future feature: exposing detailed task status change history.             |

#### 5.5.3. `AgentAuthentication` Object

Describes the authentication requirements for accessing the agent's `url` endpoint.

```typescript
interface AgentAuthentication {
  // Array of authentication scheme names supported/required by the agent's endpoint
  // (e.g., "Bearer", "Basic", "OAuth2", "ApiKey").
  // Standard names (e.g., from OpenAPI specification, IANA registry) SHOULD be used where applicable.
  // An empty array means no specific A2A-level schemes are advertised.
  schemes: string[];
  // Optional field, MAY contain non-secret, scheme-specific information.
  // Examples: For "OAuth2", this could be a JSON string with `tokenUrl`, `authorizationUrl`, `scopes`.
  // For "ApiKey", it could specify the header name (`in: "header"`, `name: "X-Custom-API-Key"`).
  // **CRITICAL**: This field MUST NOT contain plaintext secrets (e.g., actual API key values, passwords).
  // If the Agent Card itself needs to be protected due to this field containing sensitive URLs
  // or configuration, the endpoint serving the Agent Card MUST be secured.
  credentials?: string | null; // E.g., A JSON string parsable by the client for scheme details.
}
```

| Field Name    | Type               | Required | Description                                                                                                                                                                                       |
| :------------ | :----------------- | :------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `schemes`     | `string[]`         | Yes      | Array of auth scheme names (e.g., "Bearer", "OAuth2", "ApiKey"). Empty array means no A2A-advertised schemes.                                                                                     |
| `credentials` | `string` \| `null` | No       | Optional non-secret, scheme-specific configuration info (e.g., OAuth URLs, API key header name). **MUST NOT contain plaintext secrets.** Secure the Agent Card if this field implies sensitivity. |

#### 5.5.4. `AgentSkill` Object

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

```typescript
interface AgentSkill {
  // A unique identifier for this skill within the context of this agent
  // (e.g., "currency-converter", "generate-image-from-prompt", "summarize-text-v2").
  // Clients MAY use this ID to request a specific skill if the agent supports such dispatch.
  id: string;
  // Human-readable name of the skill (e.g., "Currency Conversion Service", "Image Generation AI").
  name: string;
  // Detailed description of what the skill does, its purpose, and any important considerations.
  // [CommonMark](https://commonmark.org/) MAY be used for rich text formatting.
  description?: string | null;
  // Array of keywords or categories for discoverability and categorization
  // (e.g., ["finance", "conversion"], ["media", "generative ai", "image"]).
  tags?: string[] | null;
  // Array of example prompts, inputs, or use cases illustrating how to use this skill
  // (e.g., ["convert 100 USD to EUR", "generate a photorealistic image of a cat wearing a wizard hat"]).
  // These help clients (and potentially end-users or other agents) understand how to formulate requests for this skill.
  examples?: string[] | null;
  // Overrides `agentCard.defaultInputModes` specifically for this skill.
  // If `null` or omitted, the agent's `defaultInputModes` apply.
  inputModes?: string[] | null; // Array of MIME types
  // Overrides `agentCard.defaultOutputModes` specifically for this skill.
  // If `null` or omitted, the agent's `defaultOutputModes` apply.
  outputModes?: string[] | null; // Array of MIME types
}
```

| Field Name    | Type                 | Required | Description                                                                    |
| :------------ | :------------------- | :------- | :----------------------------------------------------------------------------- |
| `id`          | `string`             | Yes      | Unique skill identifier within this agent.                                     |
| `name`        | `string`             | Yes      | Human-readable skill name.                                                     |
| `description` | `string` \| `null`   | No       | Detailed skill description. [CommonMark](https://commonmark.org/) MAY be used. |
| `tags`        | `string[]` \| `null` | No       | Keywords/categories for discoverability.                                       |
| `examples`    | `string[]` \| `null` | No       | Example prompts or use cases demonstrating skill usage.                        |
| `inputModes`  | `string[]` \| `null` | No       | Overrides `defaultInputModes` for this specific skill. Accepted MIME types.    |
| `outputModes` | `string[]` \| `null` | No       | Overrides `defaultOutputModes` for this specific skill. Produced MIME types.   |

### 5.6. Sample Agent Card

```json
{
  "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",
  "provider": {
    "organization": "Example Geo Services Inc.",
    "url": "https://www.examplegeoservices.com"
  },
  "version": "1.2.0",
  "documentationUrl": "https://docs.examplegeoservices.com/georoute-agent/api",
  "capabilities": {
    "streaming": true,
    "pushNotifications": true,
    "stateTransitionHistory": false
  },
  "authentication": {
    "schemes": ["OAuth2"],
    "credentials": "{\"authorizationUrl\": \"https://auth.examplegeoservices.com/authorize\", \"tokenUrl\": \"https://auth.examplegeoservices.com/token\", \"scopes\": {\"route:plan\": \"Allows planning new routes.\", \"map:custom\": \"Allows creating and managing custom maps.\"}}"
  },
  "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"
      ]
    }
  ]
}
```

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

```typescript
interface Task {
  // A unique identifier for the task. This ID is typically generated by the client
  // when initiating the task and MUST be used by the server to refer to this task.
  // It should be sufficiently unique (e.g., a UUID v4).
  id: string;
  // An optional, client-generated identifier used to group related tasks into a logical session.
  // Useful for maintaining context across multiple, sequential, or related tasks.
  sessionId?: string | null;
  // The current status of the task, including its lifecycle state, an optional associated message,
  // and a timestamp.
  status: TaskStatus;
  // An array of outputs (artifacts) generated by the agent for this task.
  // This array can be populated incrementally, especially during streaming.
  // Artifacts represent the tangible results of the task.
  artifacts?: Artifact[] | null;
  // An optional array of recent messages exchanged within this task,
  // ordered chronologically (oldest first).
  // This history is included if requested by the client via the `historyLength` parameter
  // in `TaskSendParams` or `TaskQueryParams`.
  history?: Message[] | null;
  // Arbitrary key-value metadata associated with the task.
  // Keys SHOULD be strings; values can be any valid JSON type (string, number, boolean, array, object).
  // This can be used for application-specific data, tracing info, etc.
  metadata?: Record<string, any> | null;
}
```

| Field Name  | Type                                          | Required | Description                                                                   |
| :---------- | :-------------------------------------------- | :------- | :---------------------------------------------------------------------------- |
| `id`        | `string`                                      | Yes      | Unique task identifier (e.g., UUID), typically client-generated.              |
| `sessionId` | `string` \| `null`                            | No       | Optional client-generated ID to group related tasks into a session.           |
| `status`    | [`TaskStatus`](#62-taskstatus-object)         | Yes      | Current status of the task (state, message, timestamp).                       |
| `artifacts` | [`Artifact[]`](#67-artifact-object) \| `null` | No       | Array of outputs generated by the agent for this task.                        |
| `history`   | [`Message[]`](#64-message-object) \| `null`   | No       | Optional array of recent messages exchanged, if requested by `historyLength`. |
| `metadata`  | `Record<string, any>` \| `null`               | No       | Arbitrary key-value metadata associated with the task.                        |

### 6.2. `TaskStatus` Object

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

```typescript
interface TaskStatus {
  // The current lifecycle state of the task.
  state: TaskState;
  // An optional message associated with the current status.
  // This could be a progress update from the agent, a prompt for more input,
  // a summary of the final result, or an error message.
  message?: Message | null;
  // The date and time (UTC is STRONGLY recommended) when this status was recorded by the server.
  // Format: ISO 8601 `date-time` string (e.g., "2023-10-27T10:00:00Z").
  timestamp?: string | null;
}
```

| Field Name  | Type                                      | Required | Description                                                |
| :---------- | :---------------------------------------- | :------- | :--------------------------------------------------------- |
| `state`     | [`TaskState`](#63-taskstate-enum)         | Yes      | Current lifecycle state of the task.                       |
| `message`   | [`Message`](#64-message-object) \| `null` | No       | Optional message providing context for the current status. |
| `timestamp` | `string` (ISO 8601) \| `null`             | No       | Timestamp (UTC recommended) when this status was recorded. |

### 6.3. `TaskState` Enum

Defines the possible lifecycle states of a `Task`.

```typescript
type TaskState =
  | 'submitted' // Task received by server, acknowledged, but processing has not yet actively started.
  | 'working' // Task is actively being processed by the agent.
  | 'input-required' // Agent requires additional input from the client/user to proceed. (Task is paused)
  | 'completed' // Task finished successfully. (Terminal state)
  | 'canceled' // Task was canceled by the client or potentially by the server. (Terminal state)
  | 'failed' // Task terminated due to an error during processing. (Terminal state)
  | 'unknown'; // The state of the task cannot be determined (e.g., task ID invalid or expired). (Effectively a terminal state from client's PoV for that ID)
```

| Value            | Description                                                                                              | Terminal?  |
| :--------------- | :------------------------------------------------------------------------------------------------------- | :--------- |
| `submitted`      | Task received by the server and acknowledged, but processing has not yet actively started.               | No         |
| `working`        | Task is actively being processed by the agent. Client may expect further updates or a terminal state.    | No         |
| `input-required` | Agent requires additional input from the client/user to proceed. The task is effectively paused.         | No (Pause) |
| `completed`      | Task finished successfully. Results are typically available in `Task.artifacts` or `TaskStatus.message`. | Yes        |
| `canceled`       | Task was canceled (e.g., by a `tasks/cancel` request or server-side policy).                             | Yes        |
| `failed`         | Task terminated due to an error during processing. `TaskStatus.message` may contain error details.       | Yes        |
| `unknown`        | The state of the task cannot be determined (e.g., task ID is invalid, unknown, or has expired).          | Yes        |

### 6.4. `Message` Object

Represents a single communication turn or a piece of contextual information within a `Task`. Messages are used for instructions, prompts, replies, and status updates.

```typescript
interface Message {
  // Indicates the sender of the message:
  // "user" for messages originating from the A2A Client (acting on behalf of an end-user or system).
  // "agent" for messages originating from the A2A Server (the remote agent).
  role: 'user' | 'agent';
  // An array containing the content of the message, broken down into one or more parts.
  // A message MUST contain at least one part.
  // Using multiple parts allows for rich, multi-modal content (e.g., text accompanying an image).
  parts: Part[];
  // Arbitrary key-value metadata associated with the message.
  // Keys SHOULD be strings; values can be any valid JSON type.
  // Useful for timestamps, source identifiers, language codes, etc.
  metadata?: Record<string, any> | null;
}
```

| Field Name | Type                            | Required | Description                                                                      |
| :--------- | :------------------------------ | :------- | :------------------------------------------------------------------------------- |
| `role`     | `"user"` \| `"agent"`           | Yes      | Indicates the sender: `"user"` (from A2A Client) or `"agent"` (from A2A Server). |
| `parts`    | [`Part[]`](#65-part-union-type) | Yes      | Array of content parts. Must contain at least one part.                          |
| `metadata` | `Record<string, any>` \| `null` | No       | Arbitrary key-value metadata associated with this message.                       |

### 6.5. `Part` Union Type

Represents a distinct piece of content within a `Message` or `Artifact`. A `Part` object is a discriminated union, identified by its mandatory `type` field. All `Part` types also include an optional `metadata` field (`Record<string, any> | null`) for part-specific metadata.

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

#### 6.5.1. `TextPart` Object

For conveying plain textual content.

```typescript
interface TextPart {
  type: 'text'; // Discriminator
  text: string; // The actual textual content.
  metadata?: Record<string, any> | null; // Optional metadata (e.g., language, formatting hints if any)
}
```

| Field Name | Type                            | Required | Description                                   |
| :--------- | :------------------------------ | :------- | :-------------------------------------------- |
| `type`     | `"text"` (literal)              | Yes      | Identifies this part as textual content.      |
| `text`     | `string`                        | Yes      | The textual content of the part.              |
| `metadata` | `Record<string, any>` \| `null` | No       | Optional metadata specific to this text part. |

#### 6.5.2. `FilePart` Object

For conveying file-based content.

```typescript
interface FilePart {
  type: 'file'; // Discriminator
  file: FileContent; // Contains the file details and data (or reference).
  metadata?: Record<string, any> | null; // Optional metadata (e.g., purpose of the file)
}
```

| Field Name | Type                                    | Required | Description                                   |
| :--------- | :-------------------------------------- | :------- | :-------------------------------------------- |
| `type`     | `"file"` (literal)                      | Yes      | Identifies this part as file content.         |
| `file`     | [`FileContent`](#66-filecontent-object) | Yes      | Contains the file details and data/reference. |
| `metadata` | `Record<string, any>` \| `null`         | No       | Optional metadata specific to this file part. |

#### 6.5.3. `DataPart` Object

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

```typescript
interface DataPart {
  type: 'data'; // Discriminator
  // The structured JSON data payload. This can be any valid JSON object or array.
  // The schema of this data is application-defined and may be implicitly understood
  // by the interacting agents or explicitly described (e.g., via a JSON Schema reference
  // in the `metadata` or associated `AgentSkill`).
  data: Record<string, any> | any[];
  metadata?: Record<string, any> | null; // Optional metadata (e.g., schema URL, version)
}
```

| Field Name | Type                             | Required | Description                                                                 |
| :--------- | :------------------------------- | :------- | :-------------------------------------------------------------------------- |
| `type`     | `"data"` (literal)               | Yes      | Identifies this part as structured data.                                    |
| `data`     | `Record<string, any>` \| `any[]` | Yes      | The structured JSON data payload (an object or an array).                   |
| `metadata` | `Record<string, any>` \| `null`  | No       | Optional metadata specific to this data part (e.g., reference to a schema). |

### 6.6. `FileContent` Object

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

```typescript
interface FileContent {
  // The original filename, if known (e.g., "document.pdf", "avatar.png").
  name?: string | null;
  // The [MIME type](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types)
  // of the file (e.g., "application/pdf", "image/png"). Strongly recommended for proper handling.
  mimeType?: string | null;
  // Base64 encoded string of the raw file content.
  // Use this for embedding small to medium-sized files directly.
  bytes?: string | null; // Base64 string
  // A URI (absolute URL is STRONGLY recommended) pointing to the file content.
  // Accessibility of this URI depends on the context (e.g., public URL, pre-signed URL, internal URL).
  // The client and server must have a way to resolve and access this URI if used.
  uri?: string | null;

  // Constraint: If file content is being transmitted, exactly one of `bytes` or `uri` MUST be non-null.
  // Both MAY be `null` or absent if the `FilePart` is merely representing a file reference
  // without transmitting its content in the current message (e.g., referring to a previously uploaded file).
}
```

| Field Name | Type               | Required                       | Description                                                                                                                         |
| :--------- | :----------------- | :----------------------------- | :---------------------------------------------------------------------------------------------------------------------------------- |
| `name`     | `string` \| `null` | No                             | Original filename (e.g., "report.pdf").                                                                                             |
| `mimeType` | `string` \| `null` | No                             | [MIME type](https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types) (e.g., `image/png`). Strongly recommended. |
| `bytes`    | `string` \| `null` | Conditionally (See Constraint) | Base64 encoded file content.                                                                                                        |
| `uri`      | `string` \| `null` | Conditionally (See Constraint) | URI (absolute URL strongly recommended) to file content. Accessibility is context-dependent.                                        |

**Constraint:** If file content is being transmitted, exactly one of `bytes` or `uri` **MUST** be provided and non-null. Both MAY be `null` or absent if the `FilePart` is only a reference or metadata about a file whose content is not being transferred in this specific part.

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

```typescript
interface Artifact {
  // A descriptive name for the artifact (e.g., "Quarterly Sales Report.pdf", "Generated Logo Design", "analysis_results.json").
  // This name might be used by the client for display or identification.
  name?: string | null;
  // A human-readable description of the artifact. [CommonMark](https://commonmark.org/) MAY be used.
  description?: string | null;
  // An array containing the content of the artifact, broken down into one or more parts.
  // An artifact MUST contain at least one part.
  // Using multiple parts allows for complex artifacts (e.g., a report with embedded images or data tables).
  parts: Part[];
  // A non-negative integer index for ordering artifacts or identifying artifact chunks during streaming.
  // Multiple artifacts (or artifact updates) can share the same index if they represent parts of the same logical output
  // that are being streamed or delivered separately.
  // Default: 0 if omitted.
  index?: number;
  // Used with streaming (`TaskArtifactUpdateEvent`):
  // If `true`, indicates this update's `parts` should be appended to the content of the artifact
  // currently identified by the same `index` value. This is useful for streaming textual data or
  // appending elements to a list in a `DataPart`.
  // If `false` or `null` (or omitted), this update replaces the artifact content at the given `index`.
  // This field is typically `false` for the first chunk of a streamed artifact.
  append?: boolean | null;
  // Used with streaming (`TaskArtifactUpdateEvent`):
  // If `true`, indicates this is the final update/chunk for the artifact at this `index`.
  // Signals the end of a streamed file or data structure.
  lastChunk?: boolean | null;
  // Arbitrary key-value metadata associated with the artifact.
  // Keys SHOULD be strings; values can be any valid JSON type.
  // Useful for creation timestamps, versioning info, checksums, etc.
  metadata?: Record<string, any> | null;
}
```

| Field Name    | Type                            | Required | Default | Description                                                                                                                  |
| :------------ | :------------------------------ | :------- | :------ | :--------------------------------------------------------------------------------------------------------------------------- |
| `name`        | `string` \| `null`              | No       | `null`  | Descriptive name for the artifact.                                                                                           |
| `description` | `string` \| `null`              | No       | `null`  | Human-readable description of the artifact.                                                                                  |
| `parts`       | [`Part[]`](#65-part-union-type) | Yes      |         | Content of the artifact, as one or more `Part` objects. Must have at least one.                                              |
| `index`       | `integer`                       | No       | `0`     | Non-negative index for ordering artifacts or identifying chunks during streaming.                                            |
| `append`      | `boolean` \| `null`             | No       | `false` | In streaming (`TaskArtifactUpdateEvent`), `true` means append parts to artifact at `index`; `false` (default) means replace. |
| `lastChunk`   | `boolean` \| `null`             | No       | `false` | In streaming (`TaskArtifactUpdateEvent`), `true` indicates this is the final update for the artifact at this `index`.        |
| `metadata`    | `Record<string, any>` \| `null` | No       | `null`  | Arbitrary key-value metadata associated with the artifact.                                                                   |

### 6.8. `PushNotificationConfig` Object

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

```typescript
interface PushNotificationConfig {
  // The absolute HTTPS webhook URL where the A2A Server should POST task updates.
  // This URL MUST be HTTPS for security.
  url: string;
  // An optional, client-generated opaque token (e.g., a secret, a task-specific identifier, or a nonce).
  // The A2A Server SHOULD include this token in the notification request it sends to the `url`
  // (e.g., in a custom HTTP header like `X-A2A-Notification-Token` or similar).
  // This allows the client's webhook receiver to validate the relevance and authenticity of the notification.
  token?: string | null;
  // Authentication details the A2A Server needs to use when calling the client's `url`.
  // The client's webhook endpoint defines these requirements. This tells the A2A Server how to authenticate *itself* to the client's webhook.
  authentication?: AuthenticationInfo | null;
}
```

| Field Name       | Type                                                                                   | Required | Description                                                                                                                                                               |
| :--------------- | :------------------------------------------------------------------------------------- | :------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `url`            | `string`                                                                               | Yes      | Absolute HTTPS webhook URL for the A2A Server to POST task updates to.                                                                                                    |
| `token`          | `string` \| `null`                                                                     | No       | Optional client-generated opaque token for the client's webhook receiver to validate the notification (e.g., server includes it in an `X-A2A-Notification-Token` header). |
| `authentication` | [`AuthenticationInfo`](#69-authenticationinfo-object-for-push-notifications) \| `null` | No       | Authentication details the A2A Server must use when calling the `url`. The client's webhook (receiver) defines these requirements.                                        |

### 6.9. `AuthenticationInfo` Object (for Push Notifications)

A generic structure for specifying authentication requirements, typically used within `PushNotificationConfig` to describe how the A2A Server should authenticate to the client's webhook.

```typescript
interface AuthenticationInfo {
  // Array of authentication scheme names the caller (i.e., the A2A Server, in the context of push notifications)
  // must use when sending the request to the webhook URL (e.g., "Bearer" for an OAuth token, "ApiKey" for a pre-shared key, "Basic").
  // Standard names SHOULD be used.
  schemes: string[];
  // Optional field for providing static credentials or scheme-specific information
  // that the A2A Server needs to use.
  // Examples:
  // - For "ApiKey": A JSON string like `{"in": "header", "name": "X-Client-Webhook-Key", "value": "actual_api_key_value"}`.
  // - For "Bearer": If the A2A Server is expected to use a specific pre-issued token, it could be provided here. More commonly, the server would obtain its own token using OAuth client credentials flow if this field specifies an OAuth scheme.
  // **CRITICAL**: Use with extreme caution if this field contains secrets. This configuration is sent from client to server.
  // Prefer mechanisms where the server fetches its own credentials dynamically (e.g., OAuth client credentials flow with a pre-configured client ID/secret on the server side for the webhook's audience)
  // rather than having the client provide secrets to the server.
  // If this field *must* carry a secret, the A2A communication channel itself must be exceptionally secure, and both client and server must handle this data with care.
  credentials?: string | null; // E.g., A JSON string parsable by the server.
}
```

| Field Name    | Type               | Required | Description                                                                                                                                                                                |
| :------------ | :----------------- | :------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `schemes`     | `string[]`         | Yes      | Array of auth scheme names the A2A Server must use when calling the client's webhook (e.g., "Bearer", "ApiKey").                                                                           |
| `credentials` | `string` \| `null` | No       | Optional static credentials or scheme-specific configuration info. **Handle with EXTREME CAUTION if secrets are involved.** Prefer server-side dynamic credential fetching where possible. |

### 6.10. `TaskPushNotificationConfig` Object

Used as the `params` object for the [`tasks/pushNotification/set`](#75-taskspushnotificationset) method and as the `result` object for the [`tasks/pushNotification/get`](#76-taskspushnotificationget) method.

```typescript
interface TaskPushNotificationConfig {
  // The ID of the task for which push notification settings are being configured or retrieved.
  id: string;
  // The push notification configuration details.
  // When used as params for `set`, this provides the configuration to apply.
  // When used as result for `get`, this reflects the currently active configuration (server MAY omit secrets).
  // If `null` when setting, it might indicate clearing existing configuration (server-dependent).
  pushNotificationConfig: PushNotificationConfig | null;
}
```

| Field Name               | Type                                                                    | Required | Description                                                                                                                                                               |
| :----------------------- | :---------------------------------------------------------------------- | :------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `id`                     | `string`                                                                | Yes      | The ID of the task to configure push notifications for, or retrieve configuration from.                                                                                   |
| `pushNotificationConfig` | [`PushNotificationConfig`](#68-pushnotificationconfig-object) \| `null` | Yes      | The push notification configuration. For `set`, the desired config. For `get`, the current config (secrets MAY be omitted by server). `null` might clear config on `set`. |

### 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., `"tasks/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.

```typescript
interface JSONRPCError {
  // A Number that indicates the error type that occurred.
  // This MUST be an integer.
  code: number;
  // A String providing a short description of the error.
  // The message SHOULD be limited to a concise single sentence.
  message: string;
  // A Primitive or Structured value that contains additional information about the error.
  // This may be omitted. The value of this member is defined by the Server (e.g. detailed error codes,
  // debugging information).
  data?: any;
}
```

| Field Name | Type            | Required | Description                                                                                                  |
| :--------- | :-------------- | :------- | :----------------------------------------------------------------------------------------------------------- |
| `code`     | `integer`       | Yes      | Integer error code. See [Section 8 (Error Handling)](#8-error-handling) for standard and A2A-specific codes. |
| `message`  | `string`        | Yes      | Short, human-readable summary of the error.                                                                  |
| `data`     | `any` \| `null` | No       | Optional additional structured information about the error.                                                  |

## 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. `tasks/send`

Sends a message to an agent to initiate a new task 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.

- **Request `params` type**: [`TaskSendParams`](#711-tasksendparams-object)
- **Response `result` type (on success)**: [`Task`](#61-task-object) (The current or final state of the task after processing the message).
- **Response `error` type (on failure)**: [`JSONRPCError`](#612-jsonrpcerror-object).

#### 7.1.1. `TaskSendParams` Object

```typescript
interface TaskSendParams {
  // The ID for the task.
  // - If this is the first message for a new task, the client generates this ID.
  // - If this message continues an existing task (e.g., providing more input after an `input-required` state),
  //   this ID MUST match the ID of the existing task.
  id: string;
  // Optional client-generated session ID to group this task with others.
  sessionId?: string | null;
  // The message to send to the agent. The `role` within this message is typically "user".
  message: Message;
  // Optional: If initiating a new task, the client MAY include push notification configuration.
  // If provided for an existing task, server behavior (e.g., update config, ignore) is server-dependent.
  // Requires `AgentCard.capabilities.pushNotifications: true`.
  pushNotification?: PushNotificationConfig | null;
  // Optional: If a positive integer `N` is provided, the server SHOULD include the last `N` messages
  // (chronologically) of the task's history in the `Task.history` field of the response.
  // If `0`, `null`, or omitted, no history is explicitly requested (server MAY still include some by default).
  historyLength?: number | null;
  // Arbitrary metadata for this specific `tasks/send` request.
  metadata?: Record<string, any> | null;
}
```

| Field Name         | Type                                                                    | Required | Description                                                                                                          |
| :----------------- | :---------------------------------------------------------------------- | :------- | :------------------------------------------------------------------------------------------------------------------- |
| `id`               | `string`                                                                | Yes      | Task ID. If new, the server SHOULD create the task. If existing, this message continues the task.                    |
| `sessionId`        | `string` \| `null`                                                      | No       | Optional client-generated session ID.                                                                                |
| `message`          | [`Message`](#64-message-object)                                         | Yes      | The message content to send. `Message.role` is typically `"user"`.                                                   |
| `pushNotification` | [`PushNotificationConfig`](#68-pushnotificationconfig-object) \| `null` | No       | Optional: sets push notification configuration for the task (usually on the first send). Requires server capability. |
| `historyLength`    | `integer` \| `null`                                                     | No       | If positive, requests the server to include up to `N` recent messages in `Task.history`.                             |
| `metadata`         | `Record<string, any>` \| `null`                                         | No       | Request-specific metadata.                                                                                           |

### 7.2. `tasks/sendSubscribe`

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

- **Request `params` type**: [`TaskSendParams`](#711-tasksendparams-object) (same as `tasks/send`).
- **Response (on successful subscription)**:
    - HTTP Status: `200 OK`.
    - HTTP `Content-Type`: `text/event-stream`.
    - HTTP Body: A stream of Server-Sent Events. Each SSE `data` field contains a [`SendTaskStreamingResponse`](#721-sendtaskstreamingresponse-object) JSON object.
- **Response (on initial subscription failure)**:
    - Standard HTTP error code (e.g., 4xx, 5xx).
    - The HTTP body MAY contain a standard `JSONRPCResponse` with an `error` object detailing the failure.

#### 7.2.1. `SendTaskStreamingResponse` 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 `tasks/sendSubscribe` or `tasks/resubscribe` stream. It's a `JSONRPCResponse` where the `result` is one of the event types.

```typescript
interface SendTaskStreamingResponse extends JSONRPCResponse {
  // The `id` MUST match the `id` from the originating `tasks/sendSubscribe` (or `tasks/resubscribe`)
  // JSON-RPC request that established this SSE stream.
  id: string | number; // Overrides JSONRPCResponse 'id' type for clarity and to emphasize it matches the original request.
  // The `result` field contains the actual event payload for this streaming update.
  // It will be either a TaskStatusUpdateEvent or a TaskArtifactUpdateEvent.
  result: TaskStatusUpdateEvent | TaskArtifactUpdateEvent;
  // For streaming events, `error` is typically `null` or absent.
  // If a fatal error occurs that terminates the stream, the server MAY send a final
  // SSE event with this `error` field populated before closing the connection.
  error?: JSONRPCError | null;
}
```

| Field Name | Type                                                                                                                                                 | Required | Description                                                                                                                                            |
| :--------- | :--------------------------------------------------------------------------------------------------------------------------------------------------- | :------- | :----------------------------------------------------------------------------------------------------------------------------------------------------- |
| `jsonrpc`  | `"2.0"` (literal)                                                                                                                                    | Yes      | JSON-RPC version string.                                                                                                                               |
| `id`       | `string` \| `number`                                                                                                                                 | Yes      | Matches the `id` from the originating `tasks/sendSubscribe` or `tasks/resubscribe` request.                                                            |
| `result`   | **Either** [`TaskStatusUpdateEvent`](#722-taskstatusupdateevent-object) <br> **OR** [`TaskArtifactUpdateEvent`](#723-taskartifactupdateevent-object) | Yes      | The event payload: either a status update or an artifact update.                                                                                       |
| `error`    | [`JSONRPCError`](#612-jsonrpcerror-object) \| `null`                                                                                                 | No       | Typically `null` or absent for stream events. If a fatal stream error occurs, this MAY be populated in the final SSE message before the stream closes. |

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

```typescript
interface TaskStatusUpdateEvent {
  // The ID of the task being updated. This MUST match the `TaskSendParams.id`
  // from the `tasks/sendSubscribe` request that initiated this stream.
  id: string;
  // The new status object for the task.
  status: TaskStatus;
  // If `true`, this `TaskStatusUpdateEvent` signifies the terminal status update for the current
  // `tasks/sendSubscribe` interaction cycle. This means the task has reached a state like
  // `completed`, `failed`, `canceled`, or `input-required`, and the server does not expect to send
  // more updates for *this specific* `sendSubscribe` request. The server typically closes the SSE
  // connection after sending an event with `final: true`.
  // Default: `false` if omitted.
  final?: boolean;
  // Arbitrary metadata for this specific status update event.
  metadata?: Record<string, any> | null;
}
```

| Field Name | Type                                  | Required | Default | Description                                                                                                                                      |
| :--------- | :------------------------------------ | :------- | :------ | :----------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`       | `string`                              | Yes      |         | Task ID being updated, matching the original request's task ID.                                                                                  |
| `status`   | [`TaskStatus`](#62-taskstatus-object) | Yes      |         | The new `TaskStatus` object.                                                                                                                     |
| `final`    | `boolean`                             | No       | `false` | If `true`, indicates this is the terminal status update for the current stream cycle. The server typically closes the SSE connection after this. |
| `metadata` | `Record<string, any>` \| `null`       | No       | `null`  | Event-specific metadata.                                                                                                                         |

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

```typescript
interface TaskArtifactUpdateEvent {
  // The ID of the task that generated this artifact. This MUST match the `TaskSendParams.id`
  // from the `tasks/sendSubscribe` request that initiated this stream.
  id: string;
  // The artifact data. This could be a complete artifact or an incremental chunk.
  // The client uses `artifact.index`, `artifact.append`, and `artifact.lastChunk`
  // to correctly assemble or update the artifact on its side.
  artifact: Artifact;
  // Arbitrary metadata for this specific artifact update event.
  metadata?: Record<string, any> | null;
}
```

| Field Name | Type                              | Required | Description                                                                                                                                                          |
| :--------- | :-------------------------------- | :------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ |
| `id`       | `string`                          | Yes      | Task ID that generated the artifact, matching the original request's task ID.                                                                                        |
| `artifact` | [`Artifact`](#67-artifact-object) | Yes      | The `Artifact` data. Could be a complete artifact or an incremental chunk. Use `index`, `append`, and `lastChunk` fields within `Artifact` for client-side assembly. |
| `metadata` | `Record<string, any>` \| `null`   | No       | `null`                                                                                                                                                               | Event-specific metadata. |

### 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 `tasks/send`, or for fetching the final state of a task after being notified via a push notification or after an SSE stream has ended.

- **Request `params` type**: [`TaskQueryParams`](#731-taskqueryparams-object)
- **Response `result` type (on success)**: [`Task`](#61-task-object) (A snapshot of the task's current state).
- **Response `error` type (on failure)**: [`JSONRPCError`](#612-jsonrpcerror-object) (e.g., if the task ID is not found, see [`TaskNotFoundError`](#82-a2a-specific-errors)).

#### 7.3.1. `TaskQueryParams` Object

```typescript
interface TaskQueryParams {
  // The ID of the task to retrieve.
  id: string;
  // Optional: If a positive integer `N` is provided, the server SHOULD include the last `N` messages
  // (chronologically) of the task's history in the `Task.history` field of the response.
  // If `0`, `null`, or omitted, no history is explicitly requested.
  historyLength?: number | null;
  // Arbitrary metadata for this specific `tasks/get` request.
  metadata?: Record<string, any> | null;
}
```

| Field Name      | Type                            | Required | Description                                                                              |
| :-------------- | :------------------------------ | :------- | :--------------------------------------------------------------------------------------- |
| `id`            | `string`                        | Yes      | The ID of the task whose current state is to be retrieved.                               |
| `historyLength` | `integer` \| `null`             | No       | If positive, requests the server to include up to `N` recent messages in `Task.history`. |
| `metadata`      | `Record<string, any>` \| `null` | No       | Request-specific metadata.                                                               |

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

- **Request `params` type**: [`TaskIdParams`](#741-taskidparams-object-for-taskscancel-and-taskspushnotificationget)
- **Response `result` type (on success)**: [`Task`](#61-task-object) (The state of the task after the cancellation attempt. Ideally, `Task.status.state` will be `"canceled"` if successful).
- **Response `error` type (on failure)**: [`JSONRPCError`](#612-jsonrpcerror-object) (e.g., [`TaskNotFoundError`](#82-a2a-specific-errors), [`TaskNotCancelableError`](#82-a2a-specific-errors)).

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

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

```typescript
interface TaskIdParams {
  // The ID of the task to which the operation applies (e.g., cancel, get push notification config).
  id: string;
  // Arbitrary metadata for this specific request.
  metadata?: Record<string, any> | null;
}
```

| Field Name | Type                            | Required | Description                |
| :--------- | :------------------------------ | :------- | :------------------------- |
| `id`       | `string`                        | Yes      | The ID of the task.        |
| `metadata` | `Record<string, any>` \| `null` | No       | Request-specific metadata. |

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

- **Request `params` type**: [`TaskPushNotificationConfig`](#610-taskpushnotificationconfig-object)
- **Response `result` type (on success)**: [`TaskPushNotificationConfig`](#610-taskpushnotificationconfig-object) (Confirms the configuration that was set. The server MAY omit or mask any sensitive details like secrets from the `authentication.credentials` field in the response).
- **Response `error` type (on failure)**: [`JSONRPCError`](#612-jsonrpcerror-object) (e.g., [`PushNotificationNotSupportedError`](#82-a2a-specific-errors), [`TaskNotFoundError`](#82-a2a-specific-errors), errors related to invalid `PushNotificationConfig`).

### 7.6. `tasks/pushNotification/get`

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

- **Request `params` type**: [`TaskIdParams`](#741-taskidparams-object-for-taskscancel-and-taskspushnotificationget)
- **Response `result` type (on success)**: [`TaskPushNotificationConfig`](#610-taskpushnotificationconfig-object) (The current push notification configuration for the task. If no configuration is set, `pushNotificationConfig` field might be `null` or an empty object. The server MAY omit or mask any sensitive details from the `authentication.credentials` field).
- **Response `error` type (on failure)**: [`JSONRPCError`](#612-jsonrpcerror-object) (e.g., [`PushNotificationNotSupportedError`](#82-a2a-specific-errors), [`TaskNotFoundError`](#82-a2a-specific-errors)).

### 7.7. `tasks/resubscribe`

Allows a client to reconnect to an SSE stream for an ongoing task after a previous connection (from `tasks/sendSubscribe` 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.

- **Request `params` type**: [`TaskQueryParams`](#731-taskqueryparams-object) (The `historyLength` parameter is typically ignored for resubscription, as the focus is on future events, but it's included for structural consistency).
- **Response (on successful resubscription)**:
    - HTTP Status: `200 OK`.
    - HTTP `Content-Type`: `text/event-stream`.
    - HTTP Body: A stream of Server-Sent Events, identical in format to `tasks/sendSubscribe`, carrying _subsequent_ [`SendTaskStreamingResponse`](#721-sendtaskstreamingresponse-object) events for the task.
- **Response (on resubscription failure)**:
    - Standard HTTP error code (e.g., 4xx, 5xx).
    - The HTTP body MAY contain a standard `JSONRPCResponse` with an `error` object. Failures can occur if the task is no longer active, doesn't exist, or streaming is not supported/enabled for it.

## 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 `JSONRPCResponse` 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/pushNotification/set`) but the server agent does not support them (i.e., `AgentCard.capabilities.pushNotifications` is `false`).                                    |
| `-32004` | `OperationNotSupportedError`        | 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 [MIME 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` | `StreamingNotSupportedError`        | Streaming is not supported         | Client attempted `tasks/sendSubscribe` or `tasks/resubscribe` but the server agent does not support streaming (i.e., `AgentCard.capabilities.streaming` is `false`).                                                                 |
| `-32007` | `AuthenticationRequiredError`       | Authentication required            | The request lacks necessary authentication credentials, or the provided credentials are invalid or insufficient. This often accompanies an HTTP `401 Unauthorized` status.                                                           |
| `-32008` | `AuthorizationFailedError`          | Authorization failed               | The authenticated identity is not authorized to perform the requested action or access the specified resource (e.g., a specific task or skill). This often accompanies an HTTP `403 Forbidden` status.                               |
| `-32009` | `InvalidTaskStateError`             | Invalid task state for operation   | The operation is not valid for the task's current `TaskState` (e.g., trying to send a message to a task that is already `completed`).                                                                                                |
| `-32010` | `RateLimitExceededError`            | Rate limit exceeded                | The client has made too many requests in a given amount of time.                                                                                                                                                                     |
| `-32011` | `ResourceUnavailableError`          | A required resource is unavailable | The server cannot complete the request because a necessary downstream resource or service is temporarily or permanently unavailable.                                                                                                 |

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, session 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. Basic Task Execution (Synchronous / Polling Style)

**Scenario:** Client asks a simple question, and the agent responds quickly.

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

   ```json
   {
     "jsonrpc": "2.0",
     "id": "req-001",
     "method": "tasks/send",
     "params": {
       "id": "task-abc-123",
       "sessionId": "session-xyz-789",
       "message": {
         "role": "user",
         "parts": [
           {
             "type": "text",
             "text": "What is the capital of France?"
           }
         ]
       }
     }
   }
   ```

2. **Server processes the request and responds (task completes quickly):**

   ```json
   {
     "jsonrpc": "2.0",
     "id": "req-001",
     "result": {
       "id": "task-abc-123",
       "sessionId": "session-xyz-789",
       "status": {
         "state": "completed",
         "message": {
           "role": "agent",
           "parts": [
             {
               "type": "text",
               "text": "The capital of France is Paris."
             }
           ]
         },
         "timestamp": "2024-03-15T10:00:05Z"
       },
       "artifacts": [
         {
           "name": "Answer",
           "index": 0,
           "parts": [
             {
               "type": "text",
               "text": "The capital of France is Paris."
             }
           ]
         }
       ]
     }
   }
   ```

   _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": "task-abc-123"}` until the task reaches a terminal state._

### 9.2. Streaming Task Execution (SSE)

**Scenario:** Client asks the agent to write a short story, and the agent streams the story incrementally.

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

   ```json
   {
     "jsonrpc": "2.0",
     "id": "req-002",
     "method": "tasks/sendSubscribe",
     "params": {
       "id": "task-story-456",
       "message": {
         "role": "user",
         "parts": [
           {
             "type": "text",
             "text": "Write a very short story about a curious robot exploring Mars."
           }
         ]
       }
     }
   }
   ```

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

   _Event 1: Task status update - working_

   ```sse
   id: sse-evt-101
   event: message
   data: {"jsonrpc":"2.0","id":"req-002","result":{"id":"task-story-456","status":{"state":"working","message":{"role":"agent","parts":[{"type":"text","text":"Okay, I'm starting to write that story for you..."}]},"timestamp":"2024-03-15T10:05:01Z"},"final":false}}
   ```

   _Event 2: Artifact update - first chunk of the story_

   ```sse
   id: sse-evt-102
   event: message
   data: {"jsonrpc":"2.0","id":"req-002","result":{"id":"task-story-456","artifact":{"name":"MarsStory.txt","index":0,"parts":[{"type":"text","text":"Unit 734, a small rover with oversized optical sensors, trundled across the ochre plains. "}]}}}
   ```

   _Event 3: Artifact update - second chunk (appended)_

   ```sse
   id: sse-evt-103
   event: message
   data: {"jsonrpc":"2.0","id":"req-002","result":{"id":"task-story-456","artifact":{"name":"MarsStory.txt","index":0,"append":true,"parts":[{"type":"text","text":"Its mission: to find the source of a peculiar signal. "}]}}}
   ```

   _Event 4: Artifact update - final chunk_

   ```sse
   id: sse-evt-104
   event: message
   data: {"jsonrpc":"2.0","id":"req-002","result":{"id":"task-story-456","artifact":{"name":"MarsStory.txt","index":0,"append":true,"lastChunk":true,"parts":[{"type":"text","text":"Olympus Mons loomed, a silent giant, as Unit 734 beeped excitedly."}]}}}
   ```

   _Event 5: Task status update - completed_

   ```sse
   id: sse-evt-105
   event: message
   data: {"jsonrpc":"2.0","id":"req-002","result":{"id":"task-story-456","status":{"state":"completed","message":{"role":"agent","parts":[{"type":"text","text":"The story is complete!"}]},"timestamp":"2024-03-15T10:05:05Z"},"final":true}}
   ```

   _(Server closes the SSE connection after the `final:true` event)._
   _(Note: SSE `id` and `event` fields are part of the SSE protocol itself, distinct from the JSON-RPC `id` within the `data` payload)._

### 9.3. Multi-Turn Interaction (Input Required)

**Scenario:** Client wants to book a flight, and the agent needs more information.

1. **Client `tasks/send` (initial request):**

   ```json
   {
     "jsonrpc": "2.0",
     "id": "req-003",
     "method": "tasks/send",
     "params": {
       "id": "task-flightbook-789",
       "message": {
         "role": "user",
         "parts": [{ "type": "text", "text": "I'd like to book a flight." }]
       }
     }
   }
   ```

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

   ```json
   {
     "jsonrpc": "2.0",
     "id": "req-003",
     "result": {
       "id": "task-flightbook-789",
       "status": {
         "state": "input-required",
         "message": {
           "role": "agent",
           "parts": [
             {
               "type": "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?"
             }
           ]
         },
         "timestamp": "2024-03-15T10:10:00Z"
       }
     }
   }
   ```

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

   ```json
   {
     "jsonrpc": "2.0",
     "id": "req-004",
     "method": "tasks/send",
     "params": {
       "id": "task-flightbook-789" /* Same task ID */,
       "message": {
         "role": "user",
         "parts": [
           {
             "type": "text",
             "text": "I want to fly from New York (JFK) to London (LHR) around October 10th, returning October 17th."
           }
         ]
       }
     }
   }
   ```

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": "task-flightbook-789",
       "status": {
         "state": "completed",
         "message": {
           "role": "agent",
           "parts": [
             {
               "type": "text",
               "text": "Okay, I've found a flight for you. Confirmation XYZ123. Details are in the artifact."
             }
           ]
         },
         "timestamp": "2024-03-15T10:11:00Z"
       },
       "artifacts": [
         {
           "name": "FlightItinerary.json",
           "parts": [
             {
               "type": "data",
               "data": {
                 "confirmationId": "XYZ123",
                 "from": "JFK",
                 "to": "LHR",
                 "departure": "2024-10-10T18:00:00Z",
                 "arrival": "2024-10-11T06:00:00Z",
                 "returnDeparture": "..."
               }
             }
           ]
         }
       ]
     }
   }
   ```

### 9.4. 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 `tasks/send` with `pushNotification` config:**

   ```json
   {
     "jsonrpc": "2.0",
     "id": "req-005",
     "method": "tasks/send",
     "params": {
       "id": "task-reportgen-aaa",
       "message": {
         "role": "user",
         "parts": [
           {
             "type": "text",
             "text": "Generate the Q1 sales report. This usually takes a while. Notify me when it's ready."
           }
         ]
       },
       "pushNotification": {
         "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": "task-reportgen-aaa",
       "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 (example, actual payload is server-defined, but SHOULD include `taskId` and `status`):**

   ```json
   {
     "eventType": "taskUpdate",
     "taskId": "task-reportgen-aaa",
     "status": { "state": "completed", "timestamp": "2024-03-15T18:30:00Z" },
     "summary": "Q1 sales report generated successfully."
     // Server MAY include more details or a link to fetch the full task.
   }
   ```

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

5. **Client (optionally, upon receiving and validating the push notification) calls `tasks/get` to retrieve full artifacts:**

   ```json
   {
     "jsonrpc": "2.0",
     "id": "req-006",
     "method": "tasks/get",
     "params": { "id": "task-reportgen-aaa" }
   }
   ```

   _(Server responds with the full `Task` object, including the generated report in `Task.artifacts`)_.

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

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

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

   ```json
   {
     "jsonrpc": "2.0",
     "id": "req-007",
     "method": "tasks/send",
     "params": {
       "id": "task-imageanalysis-bbb",
       "message": {
         "role": "user",
         "parts": [
           {
             "type": "text",
             "text": "Analyze this image and highlight any faces."
           },
           {
             "type": "file",
             "file": {
               "name": "input_image.png",
               "mimeType": "image/png",
               "bytes": "iVBORw0KGgoAAAANSUhEUgAAAAUA..." // Base64 encoded image data
             }
           }
         ]
       }
     }
   }
   ```

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": "task-imageanalysis-bbb",
       "status": { "state": "completed", "timestamp": "2024-03-15T12:05:00Z" },
       "artifacts": [
         {
           "name": "processed_image_with_faces.png",
           "index": 0,
           "parts": [
             {
               "type": "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..."
               }
             }
           ]
         }
       ]
     }
   }
   ```

### 9.6. Structured Data Exchange (Requesting and Providing JSON)

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

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

   ```json
   {
     "jsonrpc": "2.0",
     "id": "req-008",
     "method": "tasks/send",
     "params": {
       "id": "task-gettickets-ccc",
       "message": {
         "role": "user",
         "parts": [
           {
             "type": "text",
             "text": "List my open IT support tickets created in the last week.",
             "metadata": {
               "desiredOutputMimeType": "application/json",
               "desiredOutputSchemaRef": "https://schemas.example.com/supportTicketList_v1.json"
               // This metadata is a convention, not strictly enforced by A2A spec
             }
           }
         ]
       }
     }
   }
   ```

2. **Server responds with a `DataPart` containing the structured JSON data:**

   ```json
   {
     "jsonrpc": "2.0",
     "id": "req-008",
     "result": {
       "id": "task-gettickets-ccc",
       "status": { "state": "completed", "timestamp": "2024-03-15T12:15:00Z" },
       "artifacts": [
         {
           "name": "open_support_tickets.json",
           "index": 0,
           "parts": [
             {
               "type": "data",
               "metadata": {
                 "mimeType": "application/json", // Explicitly state MIME type
                 "schemaRef": "https://schemas.example.com/supportTicketList_v1.json" // Confirming schema
               },
               "data": [
                 {
                   "ticketId": "IT00123",
                   "summary": "Cannot connect to VPN",
                   "status": "Open",
                   "createdDate": "2024-03-14T09:30:00Z"
                 },
                 {
                   "ticketId": "IT00125",
                   "summary": "Printer not working on 3rd floor",
                   "status": "In Progress",
                   "createdDate": "2024-03-13T15:00:00Z"
                 }
               ]
             }
           ]
         }
       ]
     }
   }
   ```

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