A2A protocol features in Apicurio Registry
Apicurio Registry implements the A2A (Agent-to-Agent) protocol for AI agent discovery, orchestration, and lifecycle management.
A2A protocol overview
With the A2A protocol, AI agents can discover and communicate with each other through standardized endpoints. Apicurio Registry serves as both an A2A agent and an agent registry.
- Apicurio Registry as an A2A agent
-
Apicurio Registry provides its own capabilities, including schema validation, search, and artifact management.
- Apicurio Registry as an agent registry
-
Apicurio Registry stores and discovers other agents' Agent Cards.
| Apicurio Registry as an A2A agent | Apicurio Registry as an agent card registry |
|---|---|
Endpoint: Built-in skills:
|
Endpoints:
Capabilities:
|
A2A configuration properties
You can control A2A features by using the following configuration properties.
| Property | Default | Description |
|---|---|---|
|
|
Enable or disable A2A protocol support |
|
|
Name of the registry as an A2A agent |
|
|
Description of the registry agent |
|
app version |
Agent version (defaults to application version) |
|
registry base URL |
URL reported in the Agent Card |
|
|
Provider organization name |
|
Provider organization URL |
|
|
|
Whether streaming is supported |
|
|
Whether push notifications are supported |
|
|
A2A protocol version reported in the Agent Card and in its supported interfaces |
|
not set |
URL of the registry agent documentation, reported as |
|
not set |
URL of the registry agent icon, reported as |
|
|
Advertise API key authentication with the |
A2A well-known endpoints
Apicurio Registry provides the following well-known endpoints for A2A agent discovery and retrieval.
- GET /.well-known/agent.json
-
Retrieves the Agent Card for the Apicurio Registry instance. This endpoint requires no authentication. The same card is available at
/.well-known/agent-card.json.Response: Agent Card JSON document
{ "name": "Apicurio Registry", "description": "API and Schema Registry with A2A Agent support", "version": "3.3.3", "protocolVersion": "1.0", "supportedInterfaces": [ { "url": "http://localhost:8080", "protocolBinding": "http+json", "protocolVersion": "1.0" } ], "provider": { "organization": "Apicurio", "url": "https://www.apicur.io" }, "capabilities": { "streaming": false, "pushNotifications": false, "extendedAgentCard": false }, "skills": [ { "id": "schema-validation", "name": "Schema Validation", "description": "Validate schemas against format specifications (Avro, JSON Schema, Protobuf, OpenAPI, etc.)", "tags": ["schema", "validation", "avro", "json-schema", "protobuf", "openapi"] }, { "id": "schema-search", "name": "Schema Search", "description": "Search for schemas and APIs in the registry by name, description, labels, or content", "tags": ["schema", "search", "discovery"] } ], "defaultInputModes": ["text/plain"], "defaultOutputModes": ["text/plain"], "securitySchemes": { "bearer": { "type": "httpAuth", "scheme": "Bearer" } } }The example shows two of the five built-in skills. The
securitySchemesobject lists only the mechanisms that are enabled:bearerwhen OIDC authentication is enabled,basicwhen basic authentication is enabled, andapiKeywhenapicurio.a2a.agent.auth.api-key.enabledistrue. The Agent Card includesdocumentationUrlandiconUrlonly when you configure the corresponding properties. - GET /.well-known/agents
-
Searches for registered Agent Cards with filtering support. This endpoint requires no authentication. When OIDC or basic authentication is enabled, the search returns only the Agent Cards that the caller has permission to view, based on the
apicurio.agent.visibilitylabel.Table 3. Query parameters for /.well-known/agents Parameter Type Description namestring
Filter by artifact name or artifact ID. A value without
matches anywhere in the name or ID. Useas a prefix or suffix wildcard, for exampleweather*.skillstring (repeatable)
Filter by skill ID
capabilitystring (repeatable)
Filter by capability (for example,
streaming:true). Append:falseto require that a capability is absent or disabled.inputModestring (repeatable)
Filter by input mode (for example,
text,image)outputModestring (repeatable)
Filter by output mode
offsetinteger
Pagination offset (default: 0)
limitinteger
Pagination limit (default: 20, maximum: 500)
Example requestcurl "http://localhost:8080/.well-known/agents?skill=translation&capability=streaming:true"Example response: AgentSearchResults{ "count": 1, "agents": [ { "groupId": "ai-agents", "artifactId": "translator-agent", "name": "Translation Agent", "description": "Translates text between languages", "owner": "alice", "createdOn": 1756720530000, "supportedInterfaces": [ { "url": "http://translator:9001", "protocolBinding": "http+json", "protocolVersion": "1.0" } ], "skills": ["translation"], "capabilities": { "streaming": true, "pushNotifications": false } } ] }The
countfield is the total number of matching Agent Cards, not the number of entries in the current page. Theskillsarray lists skill IDs only. To get skill names and descriptions, retrieve the full Agent Card from/.well-known/agents/{groupId}/{artifactId}. - GET /.well-known/agents/{groupId}/{artifactId}
-
Retrieves a specific registered Agent Card.
Path parameters
-
groupId- The group containing the agent card -
artifactId- The artifact ID of the agent cardQuery parameters
-
version(optional) - Specific version (defaults to latest)Response: Agent Card JSON document
-
Agent visibility model
Agent Cards support three visibility levels, controlled by the apicurio.agent.visibility artifact label. When OIDC or basic authentication is enabled, GET /.well-known/agents and the AI Catalog and ARD endpoints described in AI Catalog and ARD discovery enforce visibility.
| Visibility | Behavior |
|---|---|
|
Visible to everyone, including unauthenticated clients |
|
Visible to any authenticated user (this is the default) |
|
Visible only to the artifact owner and registry administrators |
curl -X PUT "http://localhost:8080/apis/registry/v3/groups/my-agents/artifacts/my-agent" \
-H "Content-Type: application/json" \
-d '{"labels": {"apicurio.agent.visibility": "public"}}'
How entitlements work: Apicurio Registry maps the A2A community entitlement concept to its existing RBAC model:
-
Groups act as organizational namespaces
-
Entitling a client = granting read access to the group containing the Agent Card artifacts
-
Client authentication happens in an external identity provider, such as Keycloak or another OIDC provider
-
No new authorization primitives are required
| Property | Default | Description |
|---|---|---|
|
|
Default visibility for new Agent Card artifacts ( |
Visibility labels control which Agent Cards appear in /.well-known/agents search results and in the AI Catalog and ARD responses. When you retrieve a card by ID through /.well-known/agents/{groupId}/{artifactId} or the core REST API, only read authorization applies. Apicurio Registry does not check the visibility label.
| When neither OIDC nor basic authentication is configured, Apicurio Registry skips visibility filtering and all agents are visible to all users. |
Agent Card artifact type
Apicurio Registry stores Agent Cards as artifacts with type AGENT_CARD. You can create Agent Cards by using the REST API and you can validate them against the A2A specification JSON schema.
curl -X POST "http://localhost:8080/apis/registry/v3/groups/ai-agents/artifacts" \
-H "Content-Type: application/json" \
-d '{
"artifactId": "my-agent",
"artifactType": "AGENT_CARD",
"firstVersion": {
"version": "1.0.0",
"content": {
"contentType": "application/json",
"content": "{\"name\": \"My Agent\", \"skills\": [{\"id\": \"task\", \"name\": \"Task Execution\"}]}"
}
}
}'
Agent Cards must conform to the A2A specification:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": ["name"],
"properties": {
"name": {"type": "string"},
"description": {"type": "string"},
"version": {"type": "string"},
"url": {"type": "string", "format": "uri"},
"provider": {
"type": "object",
"properties": {
"organization": {"type": "string"},
"url": {"type": "string", "format": "uri"}
}
},
"capabilities": {
"type": "object",
"properties": {
"streaming": {"type": "boolean"},
"pushNotifications": {"type": "boolean"}
}
},
"skills": {
"type": "array",
"items": {
"type": "object",
"required": ["id", "name"],
"properties": {
"id": {"type": "string"},
"name": {"type": "string"},
"description": {"type": "string"},
"tags": {"type": "array", "items": {"type": "string"}},
"examples": {"type": "array", "items": {"type": "string"}}
}
}
},
"defaultInputModes": {"type": "array", "items": {"type": "string"}},
"defaultOutputModes": {"type": "array", "items": {"type": "string"}},
"authentication": {
"type": "object",
"properties": {
"schemes": {"type": "array", "items": {"type": "string"}}
}
}
}
}
Agent Card validation rules
Agent Cards have three validation levels that control how much validation occurs when you create or update an Agent Card.
| Level | Description |
|---|---|
|
No validation. |
|
Validates that the content is syntactically valid JSON and is a JSON object. |
|
Complete schema validation including:
|
Agent Card compatibility rules
When you version Agent Cards, Apicurio Registry enforces compatibility rules to ensure that changes do not break existing clients.
Compatible changes (allowed):
-
Adding new skills
-
Adding new capabilities
-
Adding authentication schemes
-
Adding input or output modes
Incompatible changes (can break clients):
-
Removing skills
-
Removing or disabling capabilities
-
Removing supported interfaces (matched by URL and protocol binding)
-
Changing the protocol version on an existing interface
-
Removing security schemes
-
Removing input or output modes
Automatic label extraction for Agent Cards
Apicurio Registry automatically extracts labels from Agent Cards for search. You can use these labels for efficient capability-based discovery by using the Apicurio Registry label search.
| Label pattern | Source |
|---|---|
|
Each skill ID in the |
|
Each enabled capability in the |
|
Each value in the |
|
Each value in the |
|
Each |
|
Each key in the |
|
Each value in the |
Apicurio Registry built-in A2A skills
Apicurio Registry operates as an A2A agent with the following built-in skills.
| Skill ID | Description |
|---|---|
|
Validate schemas against format specifications (Avro, JSON Schema, Protobuf, OpenAPI, AsyncAPI, GraphQL, Thrift, WSDL, XSD) |
|
Search for schemas and APIs in the registry by name, labels, or content |
|
Create, update, and manage schema artifacts with full versioning |
|
Check schema compatibility between versions by using configurable rules |
|
Discover and manage A2A agent cards stored in the registry |
LLM lifecycle management
A2A integration includes full LLM lifecycle management with additional artifact types, including MODEL_SCHEMA and PROMPT_TEMPLATE.
The MODEL_SCHEMA artifact type defines input and output schemas for LLM agents:
{
"$schema": "https://apicurio.io/schemas/model-schema/v1",
"modelId": "sentiment-analysis-output",
"provider": "a2a-demo",
"version": "1.0.0",
"output": {
"type": "object",
"required": ["sentiment", "confidence"],
"properties": {
"sentiment": {"type": "string", "enum": ["positive", "negative", "neutral"]},
"confidence": {"type": "number", "minimum": 0, "maximum": 1}
}
}
}
The PROMPT_TEMPLATE artifact type stores versioned prompt templates with variable support:
templateId: sentiment-analysis
name: Sentiment Analysis Prompt
version: "1.0.0"
template: |
Analyze the sentiment of the following message:
MESSAGE: {{customerMessage}}
Respond with JSON containing sentiment and confidence.
variables:
customerMessage:
type: string
required: true
description: The message to analyze
metadata:
outputSchema: urn:apicurio:llm-agents.schemas/sentiment-output
Agent Cards can reference their schemas and prompts by using URN references:
{
"name": "Sentiment Agent",
"skills": [
{
"id": "sentiment-analysis",
"name": "Sentiment Analysis",
"outputSchema": "urn:apicurio:llm-agents.schemas/sentiment-agent-output",
"promptTemplate": "urn:apicurio:llm-agents.prompts/sentiment-agent-prompt"
}
]
}
Multi-agent workflow example
You can chain context across multiple agents in a pipeline. The a2a-real-world-integration example in the Apicurio Registry repository demonstrates this pattern.
| Step | Input context | Output |
|---|---|---|
1. Sentiment agent |
|
|
2. Issue analyzer |
|
|
3. Response generator |
|
|
4. Translation agent |
|
|
To run the example application locally, clone the Apicurio Registry repository and run the following commands:
cd examples/a2a-real-world-integration
docker-compose up -d
mvn clean compile exec:java
The Web UI is available at localhost:9000.
Java SDK usage for A2A
You can use the Java SDK to discover agents and register Agent Cards programmatically.
RegistryClient client = RegistryClientFactory.create(
RegistryClientOptions.create("http://localhost:8080/apis/registry/v3"));
// Search for agents with specific skill
var agents = client.wellKnown().agents()
.get(config -> {
config.queryParameters.skill = List.of("translation");
config.queryParameters.limit = 10;
});
for (var agent : agents.getAgents()) {
System.out.println("Found: " + agent.getName() + " @ " + agent.getUrl());
}
CreateArtifact artifact = new CreateArtifact();
artifact.setArtifactId("my-agent");
artifact.setArtifactType("AGENT_CARD");
CreateVersion version = new CreateVersion();
version.setVersion("1.0.0");
VersionContent content = new VersionContent();
content.setContentType("application/json");
content.setContent(agentCardJson);
version.setContent(content);
artifact.setFirstVersion(version);
client.groups().byGroupId("ai-agents").artifacts()
.post(artifact, config -> {
config.queryParameters.ifExists = IfArtifactExists.FIND_OR_CREATE_VERSION;
});
A2A REST API endpoints
The following table describes the core A2A endpoints available in Apicurio Registry.
| Endpoint | Method | Description |
|---|---|---|
|
GET |
Get the registry’s own Agent Card |
|
GET |
Search registered Agent Cards |
|
GET |
Get a specific Agent Card by artifact ID |
|
POST |
Create an Agent Card artifact (type: AGENT_CARD) |
|
GET |
Get Agent Card artifact metadata |
|
GET |
Get Agent Card content |
A2A troubleshooting
Use the following information to troubleshoot common issues with A2A features in Apicurio Registry.
- A2A endpoints return 404
-
Set
apicurio.a2a.enabled=truein your configuration:apicurio.a2a.enabled=true - Agent Card validation fails
-
Verify the following conditions:
-
The
namefield is present and non-empty. -
Skills have both
idandnamefields. -
Capabilities are boolean values.
-
The JSON is well-formed.
-
- Search returns no results
-
Verify the following conditions:
-
Agent Cards are stored with type
AGENT_CARD. -
The registry extracted labels correctly (check artifact labels).
-
Search filters match stored values exactly.
-
