What's New in A2A Protocol v1.0
A2A Protocol v1.0.0 was released on March 12, 2026, followed by the v1.0.1 bug-fix release on May 28, 2026. This page walks through the key changes from v0.3.0 to v1.0 so you can assess the impact and plan a migration.
In one minute
- v1.0 is a maturity release:
a2a.protobecomes the single normative source of truth, and the JSON-RPC, gRPC, and HTTP+JSON/REST bindings share one data model with explicit equivalence guarantees. - There is a set of breaking changes: renamed operations, a single unified Part,
SCREAMING_SNAKE_CASEenum values, streaming events withoutkind, a restructured Agent Card interface declaration, and HTTP paths without the/v1prefix. - New enterprise capabilities arrive too: Agent Card signatures, multi-tenancy, version negotiation, cursor-based pagination, modernized OAuth flows, and a standardized error model.
- v1.0.1 is a bug-fix release with no new breaking changes (see the end of this page).
Four major themes
1. Protocol maturity and standardization
a2a.protois elevated from a gRPC-specific implementation file to the universal, normative source of truth.- Formal standards (RFC 8785, RFC 7515) and
google.rpc.Statusare used wherever possible. - Stricter adherence to industry-standard patterns for the REST, gRPC, and JSON-RPC bindings.
- An enhanced versioning strategy with explicit backward compatibility rules.
- A comprehensive error taxonomy with protocol-specific mappings.
2. Stronger type safety and clarity
- Discriminator
kindfields are removed in favor of JSON member-based polymorphism. - Breaking: Enum values change from
kebab-casetoSCREAMING_SNAKE_CASE, complying with the ProtoJSON specification. - Stricter field naming conventions (
camelCasefor JSON). - More precise timestamp specification (ISO 8601 with millisecond precision).
- Clearer optional-versus-required semantics.
3. A better developer experience
- Operations are renamed for consistency and clarity.
- The Agent Card structure is reorganized into more logical groups.
- A stronger extension mechanism with versioning and requirement declarations.
- More explicit service parameter handling (
A2A-VersionandA2A-Extensionsheaders). - Simplified ID format: compound IDs such as
tasks/{id}give way to simple UUIDs. - Protocol version per interface: each
AgentInterfacespecifies its own protocol version for better backward compatibility. - Multi-tenancy: native tenant scoping in requests.
4. Enterprise-ready features
- Agent Card signature verification using JWS and JSON canonicalization.
- Formal specification of all three protocol bindings with equivalence guarantees.
- Enhanced security scheme declarations, including mutual TLS.
- Modern OAuth 2.0 flows: the Device Code flow (RFC 8628) is added, and the implicit and password flows are deprecated (marked
deprecatedin the proto). - PKCE support: a
pkceRequiredfield on the Authorization Code flow. - Cursor-based pagination for scalable task listing.
Changes to core operations
| v0.3.0 | v1.0 | Notes |
|---|---|---|
message/send | SendMessage | More precise semantics for when a Task versus a Message is returned |
message/stream | SendStreamingMessage | Stream events no longer carry kind; the final field is removed; multiple concurrent streams are allowed and receive the same ordered events |
tasks/get | GetTask | More precise history inclusion behavior; servers must only return tasks visible to the caller |
| none | ListTasks | New, with filtering; task visibility is scoped to the authenticated caller |
tasks/cancel | CancelTask | More precise rules for when cancellation is allowed and the resulting state transitions |
agent/getAuthenticatedExtendedCard | GetExtendedAgentCard | supportsAuthenticatedExtendedCard moves to capabilities.extendedAgentCard |
tasks/resubscribe | SubscribeToTask | Formal subscription lifecycle; the stream closes when the task reaches a terminal state; multiple concurrent subscriptions per task |
tasks/pushNotificationConfig/set | CreateTaskPushNotificationConfig | Push notification payloads now use the StreamResponse format |
tasks/pushNotificationConfig/get | GetTaskPushNotificationConfig | TaskPushNotificationConfig is flattened |
tasks/pushNotificationConfig/list | ListTaskPushNotificationConfigs | |
tasks/pushNotificationConfig/delete | DeleteTaskPushNotificationConfig |
A few more protocol-level simplifications:
- ID format: All IDs are simple literals. Operations that used compound IDs (such as
tasks/{taskId}/pushNotificationConfigs/{configId}) now carry separatetask_idandidfields, so IDs map directly to database keys. - HTTP URL paths: The HTTP+JSON binding drops the
/v1prefix (POST /v1/message:sendbecomesPOST /message:send, plusGET /tasks/{id}). If a version is needed, it can live in the base URL and be managed at the interface level. - Multi-tenancy: A
tenantfield is added to all request messages, andAgentInterfacegains atenantfield for the default tenant. See Multi-Tenancy .
Changes to core data objects
TaskStatus and Message: enum values
| v0.3.0 | v1.0 |
|---|---|
"submitted" | "TASK_STATE_SUBMITTED" |
"working" | "TASK_STATE_WORKING" |
"completed" | "TASK_STATE_COMPLETED" |
"failed" | "TASK_STATE_FAILED" |
"canceled" | "TASK_STATE_CANCELED" |
"rejected" | "TASK_STATE_REJECTED" |
"input-required" | "TASK_STATE_INPUT_REQUIRED" |
"auth-required" | "TASK_STATE_AUTH_REQUIRED" |
"user" (role) | "ROLE_USER" |
"agent" (role) | "ROLE_AGENT" |
timestamp must now be ISO 8601 UTC with millisecond precision (YYYY-MM-DDTHH:mm:ss.sssZ).
// v0.3.0
{ "status": { "state": "completed", "timestamp": "2024-03-15T10:15:00Z" } }
// v1.0
{ "status": { "state": "TASK_STATE_COMPLETED", "timestamp": "2024-03-15T10:15:00.000Z" } }Message and Artifact gain an extensions[] array (the extension URIs that apply).
Part: a complete redesign
This is the most significant breaking change. The separate TextPart, FilePart, and DataPart types are removed and replaced by a single Part message whose content is chosen with a oneof.
v0.3.0 (separate types with a kind discriminator):
{ "kind": "text", "text": "Hello world" }
{ "kind": "file", "file": { "fileWithUri": "https://example.com/doc.pdf", "mimeType": "application/pdf" } }
{ "kind": "data", "data": {"key": "value"} }v1.0 (unified Part):
{ "text": "Hello world", "mediaType": "text/plain" }
{ "url": "https://example.com/doc.pdf", "filename": "doc.pdf", "mediaType": "application/pdf" }
{ "raw": "base64encodedcontent==", "filename": "image.png", "mediaType": "image/png" }
{ "data": {"key": "value"}, "mediaType": "application/json" }Key points:
- The separate
TextPart,FilePart, andDataParttypes, thekinddiscriminator, and the nestedfileobject are removed. - A single
Partdetermines the content type by which field is present:text,raw,url, ordata. mediaTypereplacesmimeTypeand is available for every Part type.filenameis available for every Part type (not just files).rawcarries inline binary content (base64 in JSON), andurlreplacesfile.fileWithUri.
// Discrimination changes from the kind field to member presence
if (part.kind === "text") { /* ... */ } // v0.3.0
if ("text" in part) { /* ... */ } // v1.0
Stream event objects
TaskStatusUpdateEvent and TaskArtifactUpdateEvent are no longer told apart by kind; the outer JSON member name does that job, and the final field is removed (closing the stream signals completion).
// v0.3.0
{ "kind": "status-update", "taskId": "...", "contextId": "...", "status": {}, "final": true }
// v1.0
{ "statusUpdate": { "taskId": "...", "contextId": "...", "status": {} } }// v1.0: artifact update
{ "artifactUpdate": { "taskId": "...", "contextId": "...", "artifact": {}, "index": 0 } }The new index field in artifactUpdate is the artifact’s position in the task’s artifacts array.
AgentCard: restructured interface declaration
| Removed field | Where it went |
|---|---|
protocolVersion | Moved into each AgentInterface |
preferredTransport, additionalInterfaces | Consolidated into supportedInterfaces[] |
url | The primary endpoint is now supportedInterfaces[0].url |
supportsAuthenticatedExtendedCard | Moved to capabilities.extendedAgentCard |
// v0.3.0
{
"protocolVersion": "0.3",
"url": "https://agent.example.com/a2a",
"preferredTransport": "JSONRPC",
"supportsAuthenticatedExtendedCard": true
}
// v1.0
{
"supportedInterfaces": [
{ "url": "https://agent.example.com/a2a", "protocolBinding": "JSONRPC", "protocolVersion": "1.0" }
],
"capabilities": { "extendedAgentCard": true }
}A new signatures[] field carries Agent Card signatures (JWS, with RFC 8785 canonicalization before signing).
OAuth 2.0 modernization
v1.0 updates security schemes in line with the OAuth 2.0 Security Best Current Practice (BCP):
- Deprecated:
ImplicitOAuthFlow(token leakage risk) andPasswordOAuthFlow(credential exposure risk) are markeddeprecatedina2a.protoand should not be used in new implementations. - Added:
DeviceCodeOAuthFlow(RFC 8628), for CLI tools, IoT devices, and other input-constrained scenarios. - Enhanced:
AuthorizationCodeOAuthFlowgainspkceRequired(RFC 7636). PKCE is recommended for all OAuth clients and required for public clients.
// v0.3.0: implicit flow (deprecated in v1.0)
{ "implicitFlow": { "authorizationUrl": "https://auth.example.com/authorize", "scopes": {"read": "Read access"} } }
// v1.0: use Authorization Code + PKCE instead
{
"authorizationCodeFlow": {
"authorizationUrl": "https://auth.example.com/authorize",
"tokenUrl": "https://auth.example.com/token",
"pkceRequired": true,
"scopes": {"read": "Read access"}
}
}Error model: google.rpc.Status
HTTP+JSON error responses now use the ProtoJSON representation of google.rpc.Status, replacing RFC 9457 (Problem Details). The JSON-RPC and HTTP+JSON bindings both use google.rpc.ErrorInfo inside the data / details array to carry A2A-specific error context:
- The HTTP+JSON Content-Type changes from
application/problem+jsontoapplication/json. - The error model uses the
google.rpc.Statusfields (code,message,details). - A2A errors must include a
google.rpc.ErrorInfoobject indetails, with areason(theUPPER_SNAKE_CASEform of the A2A error type) anddomain: "a2a-protocol.org".
// v0.3.0 (JSON-RPC)
"error": { "code": -32001, "message": "Task not found", "data": { "taskId": "123" } }
// v1.0 (JSON-RPC)
"error": {
"code": -32001,
"message": "Task not found",
"data": [
{
"@type": "type.googleapis.com/google.rpc.ErrorInfo",
"reason": "TASK_NOT_FOUND",
"domain": "a2a-protocol.org",
"metadata": { "taskId": "123" }
}
]
}HTTP/1.1 404 Not Found
Content-Type: application/json
{
"error": {
"code": 404,
"status": "NOT_FOUND",
"message": "The specified task ID does not exist",
"details": [
{
"@type": "type.googleapis.com/google.rpc.ErrorInfo",
"reason": "TASK_NOT_FOUND",
"domain": "a2a-protocol.org"
}
]
}
}New dependencies on other specifications
| Specification | Purpose and impact |
|---|---|
google.rpc.Status / google.rpc.ErrorInfo | A standardized error response model for the HTTP+JSON and JSON-RPC bindings |
| RFC 8785 (JCS) | Deterministic JSON serialization for Agent Card signature verification (canonicalized before signing, excluding the signatures field) |
| RFC 7515 (JWS) | The signature standard behind the Agent Card signatures field, supporting detached signatures and public key retrieval through jku or trusted keystores |
| Google API design guidelines | gRPC best practices, aligning better with gRPC ecosystem expectations |
| ISO 8601 | Timestamp format: UTC with millisecond precision |
Dependencies retained from v0.3.0 include JSON-RPC 2.0, gRPC / Protocol Buffers 3, HTTP/HTTPS, SSE, RFC 8615 (well-known URIs), OAuth 2.0 and OpenID Connect, and TLS.
The relationship with MCP is also clearer: MCP handles tool and resource integration, A2A handles agent-to-agent coordination, the two are complementary rather than competing, and agents may support both for different use cases. See A2A and MCP .
Impact on developers
Breaking changes that require code updates
1. Part type unification (critical impact)
// v0.3.0
if (part.kind === "text") {
return part.text;
} else if (part.kind === "file") {
if (part.file.fileWithUri) return fetchFile(part.file.fileWithUri);
return part.file.fileWithBytes;
} else if (part.kind === "data") {
return part.data;
}
// v1.0
if ("text" in part) return part.text;
if ("url" in part) return fetchFile(part.url);
if ("raw" in part) return decodeBase64(part.raw);
if ("data" in part) return part.data;2. Stream event discriminator (high impact)
// v0.3.0
if (event.kind === "status-update") handleStatusUpdate(event);
else if (event.kind === "artifact-update") handleArtifactUpdate(event);
// v1.0
if ("statusUpdate" in event) handleStatusUpdate(event.statusUpdate);
else if ("artifactUpdate" in event) handleArtifactUpdate(event.artifactUpdate);3. Agent Card structure (high impact)
// v0.3.0
const endpoint = agentCard.url;
const transport = agentCard.preferredTransport;
const supportsExtended = agentCard.supportsAuthenticatedExtendedCard;
// v1.0
const primaryInterface = agentCard.supportedInterfaces[0];
const endpoint = primaryInterface.url;
const transport = primaryInterface.protocolBinding;
const supportsExtended = agentCard.capabilities.extendedAgentCard;4. Pagination (medium impact): listing tasks moves from page-based to cursor-based.
// v0.3.0
const response = await listTasks({ page: 1, perPage: 50 });
// v1.0
let pageToken = undefined;
do {
const response = await listTasks({ pageToken, pageSize: 50 });
// process response.tasks
pageToken = response.nextPageToken;
} while (pageToken);5. Enum values (high impact): see the mapping table above.
6. Field names (low impact): file.mimeType becomes mediaType; operation names have aliases during the transition.
7. Error handling (high impact): switch to google.rpc.Status / ErrorInfo, as described above.
New capabilities worth adopting
- Execution mode control:
SendMessagecan usereturnImmediatelyto either wait for task completion (the default) or return at once and poll later. - Agent Card signature verification: when
signaturesis present, verify it, and refuse to use a card that fails verification. - Required extension checks: read the extensions marked
required: truein the Agent Card and confirm the client supports all of them. - Version negotiation: the client sends the
A2A-Versionheader, and the server rejects versions it does not support.
Migration strategy
Phase 1: compatibility layer
- Parse both the old and new discriminator patterns.
- Implement version detection based on the protocol version.
- Support both Agent Card structures during the transition.
Phase 2: dual support
- Update all APIs to emit the v1.0 format.
- Keep backward-compatible readers for v0.3.0.
- Add
A2A-Versionheader handling. - Implement cursor-based pagination alongside the legacy page-based one.
Phase 3: v1.0 only
- Deprecate the v0.3.0 compatibility code.
- Remove legacy discriminator parsing.
- Remove page-based pagination.
- Clean up the dual-format support code.
Backward compatibility strategy
v1.0 introduces a formal approach to protocol versioning that enables SDK backward compatibility:
- Each
AgentInterfacedeclares its ownprotocolVersion. - Agents can expose multiple interfaces to support several protocol versions at once.
- Clients negotiate the version by picking the appropriate interface from the Agent Card.
SDKs can use this to support multiple protocol versions, let agents migrate gradually, have clients select the best compatible version automatically, and deprecate old versions gracefully.
Testing considerations
- Test with both v0.3.0 and v1.0 formatted data.
- Validate Agent Card signature verification.
- Test cursor-based pagination edge cases (empty results, a single page, and so on).
- Verify proper handling of the new error types.
- Test extension requirement validation.
Recommended priority
| Priority | Items |
|---|---|
| Critical (do immediately) | Update Part and streaming event parsing (discriminator pattern); update Agent Card parsing (structure changes); add the A2A-Version header to all requests |
| High (within one month) | Implement cursor-based pagination; update enum value handling (the state field); support the returnImmediately parameter |
| Medium (within three months) | Implement Agent Card signature verification; add extension requirement checking; update timestamp handling to ISO 8601; implement the new error types |
| Low (nice to have) | Use the enhanced metadata capabilities; implement mutual TLS authentication support |
v1.0.1 fixes
v1.0.1 (released in May 2026) contains specification-level fixes only, with no new breaking changes:
- Prefer the
application/a2a+jsonmedia type in the HTTP binding. - Fix recent transcoding-related error handling changes.
- Fix the description of TaskStatus values in the specification.
The full record is on the GitHub release page .