Extensions
An extension is a URI that a card declares, a client activates per request with A2A-Extensions, and both sides carry as metadata keyed by that URI.
The three cards in 01-agent-cards.http declare no extension, so the planner sends plain requests. A reviewer that returned a citation with each finding would need data the core protocol lacks, and an extension adds it under a URI. When you finish this section, you can read an extension declaration, activate one on a request, and handle a missing required one.
AgentExtension in the card
Extension: an addition to the protocol, identified by a URI and defined by its own specification. An agent declares each one as an AgentExtension in capabilities.extensions, with four optional fields.
uri, the unique URI of the extension.description, how this agent uses it.required, true when the client must understand the extension and follow its rules.params, the configuration parameters of the extension, as a JSON object.
Section 4.6.1 puts the array on the AgentCard itself, and the migration guide reads agentCard.extensions. The proto puts it under capabilities, so read capabilities.extensions.
"capabilities": {
"streaming": false,
"pushNotifications": false,
"extensions": [
{
"uri": "https://standards.org/extensions/citations/v1",
"description": "Provides citation formatting and source verification",
"required": false
},
{
"uri": "https://example.com/extensions/geolocation/v1",
"description": "Location-based search capabilities",
"required": false
}
]
},Activating an extension on a request
The client lists the URIs it wants in the A2A-Extensions service parameter. A2A-Version and A2A-Extensions says how that parameter travels in each binding.
Message.extensions lists the URIs of the extensions that are present in the message or that added to it. The payload sits in metadata under the same URI as key. The specification shows that keying by example only. Artifact.extensions works the same way.
Host: agent.example.com
Content-Type: application/a2a+json
Authorization: Bearer token
A2A-Extensions: https://example.com/extensions/geolocation/v1,https://standards.org/extensions/citations/v1
{
"message": {
"role": "ROLE_USER",
"parts": [{"text": "Find restaurants near me"}],
"extensions": ["https://example.com/extensions/geolocation/v1"],
"metadata": {
"https://example.com/extensions/geolocation/v1": {
"latitude": 37.7749,
"longitude": -122.4194
}
}
}
}The guide adds a third step: the response should carry the A2A-Extensions header with every extension that the server activated for that request. The specification has no such rule, and the SDKs differ. The a2a-js server echoes the header on all three bindings. The a2a-go and a2a-java servers echo it only as gRPC response metadata. The a2a-python, a2a-dotnet, and a2a-rs servers never write it. Figure 6.2 shows the exchange.
A2A-Extensions and keys its data by the URI, and a missing required extension answers -32008. Read top to bottom. Steps 1 to 4 follow the §4.6.1 sample card and request, and the activation steps of the extensions guide. Steps 5 and 6 show the §3.3.4 rule for a card that marks an extension required, which the sample does not. The kit declares no extension, so no capture is shown. URIs are shortened to their last two path segments.Required extensions and versions
A card can mark an extension required: true. When the client does not declare that extension, the agent must return ExtensionSupportRequiredError: -32008, HTTP 400, or gRPC FAILED_PRECONDITION, as errors tables. Only a2a-java has the check built in. The reference SDK only exposes the requested URIs as requested_extensions and never raises the error.
An extension should put its version in its URI, and a breaking change must get a new URI. An agent ignores an unknown version of an optional extension and returns an error for a required one. It must not switch to an older version of the extension by itself.
Kinds, governance, and what exists
The extensions guide names four kinds. Data-only extensions add structured data to the card. Profile extensions narrow the values that core messages carry. Method extensions add RPC methods. State machine extensions add states, which task and task state rejects (conflict D29).
Two tiers govern extensions in the a2aproject organization: official ones in ext-{name} repositories under the URI prefix https://a2a-protocol.org/extensions/, and experimental ones in experimental-ext-{name}. For SDKs, extensions must be off by default and need an explicit opt-in. A conformant implementation does not have to support extensions.
On 2026-10-06 the organization had no ext- repository, so no official extension exists. One experimental extension exists: experimental-ext-oid4vp-auth, for in-task authorization with OpenID for Verifiable Presentations. Its agent moves the task to TASK_STATE_AUTH_REQUIRED and puts an authorization request in metadata under the extension URI, for a wallet to answer. It builds on in-task authorization, and its README allows breaking changes. The four example extensions that the guide lists are samples in a2a-samples, outside the tiers: timestamp, traceability, secure-passport, and agp.
A2A protocol 1.0.1 · 3303592 · 2026-05-28 · Edition 2026.10