A2A API Reference
📘 Documentation Scope: This guide covers the 20 most commonly used A2A (Agent-to-Agent) endpoints for agent management and invocation. Advanced features (agent marketplace, versioning, federation) will be documented in future releases.
A2A API Base URL
All A2A endpoints are prefixed with /api/v1/agents:
http://localhost:8080/api/v1/agentsA2A API Authentication
A2A endpoints have different authentication requirements based on the operation:
Authentication Methods
1. API Key Authentication (Recommended for Agents)
For programmatic agent invocation and service accounts:
curl -H "X-API-Key: YOUR_API_KEY" \
http://localhost:8080/api/v1/agentsCharacteristics:
- Scoped to user groups with specific agent access permissions
- Subject to per-group rate limits
- Cannot access agents outside assigned user group
- Best for automation and agent-to-agent communication
2. JWT Authentication (Admin Access)
For administrative operations via web interface or scripts:
curl -H "Authorization: Bearer YOUR_JWT_TOKEN" \
http://localhost:8080/api/v1/agentsCharacteristics:
- Admin users can access all agents (no user group restrictions)
- OAuth session tokens also work with
Authorization: Bearerheader - Required for agent management (create, update, delete)
- Higher rate limits than API keys
3. Public Discovery (No Authentication)
Some A2A endpoints support unauthenticated discovery:
# Public AgentCard discovery
curl http://localhost:8080/.well-known/agent-card.json
# Public JSON-RPC discovery (agents/list method only)
curl -X POST http://localhost:8080/a2a/v1 \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "agents/list",
"params": {}
}'Important: Discovery is public, but agent invocation requires authentication.
WebSocket Authentication
For real-time agent communication via WebSocket:
// Include JWT token in WebSocket connection
const token = 'YOUR_JWT_TOKEN';
const ws = new WebSocket(`ws://localhost:8080/ws?token=${token}`);
// Or use API key in connection headers (implementation-specific)
const ws = new WebSocket('ws://localhost:8080/ws', {
headers: { 'X-API-Key': 'YOUR_API_KEY' }
});See Also: Authentication Guide for obtaining tokens and API keys.
Agent Management Endpoints
List Agents
List all agents accessible to the authenticated user.
Endpoint: GET /api/v1/agents
Authentication: Required (API Key or JWT)
Query Parameters:
status(optional): Filter by status (active,inactive,maintenance)search(optional): Search by agent namelimit(optional): Number of results (default: 50, max: 100)offset(optional): Pagination offset (default: 0)
Response:
{
"success": true,
"data": {
"agents": [
{
"id": 1,
"name": "echo-agent",
"status": "active",
"agent_card": {
"protocol_version": "1.0",
"name": "Echo Agent",
"description": "Echoes back messages",
"version": "1.0.0",
"supported_interfaces": [
{
"url": "http://127.0.0.1:9001",
"protocol_binding": "JSONRPC"
}
],
"capabilities": {
"streaming": true
},
"skills": [...]
},
"created_at": "2025-12-10T12:00:00Z",
"updated_at": "2025-12-10T12:00:00Z"
}
],
"total": 1,
"limit": 50,
"offset": 0
}
}Example:
curl -X GET "http://localhost:8080/api/v1/agents?status=active&limit=10" \
-H "X-API-Key: YOUR_API_KEY"Get Agent
Get detailed information about a specific agent.
Endpoint: GET /api/v1/agents/{id}
Authentication: Required (API Key or JWT)
Path Parameters:
id(required): Agent ID
Response:
{
"success": true,
"data": {
"id": 1,
"name": "echo-agent",
"status": "active",
"agent_card": {...},
"created_at": "2025-12-10T12:00:00Z",
"updated_at": "2025-12-10T12:00:00Z"
}
}Example:
curl -X GET http://localhost:8080/api/v1/agents/1 \
-H "X-API-Key: YOUR_API_KEY"Create Agent
Register a new agent in the registry.
Endpoint: POST /api/v1/agents
Authentication: Required (Admin JWT only)
Request Body (Auto-Discovery):
{
"name": "my-agent",
"url": "http://127.0.0.1:9001"
}Request Body (Manual AgentCard):
{
"name": "my-agent",
"agent_card": "{\"protocol_version\":\"1.0\",\"name\":\"My Agent\",...}"
}Response:
{
"success": true,
"data": {
"id": 1,
"name": "my-agent",
"status": "active",
"agent_card": {...},
"created_at": "2025-12-10T12:00:00Z",
"updated_at": "2025-12-10T12:00:00Z"
}
}Example:
curl -X POST http://localhost:8080/api/v1/agents \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-d '{
"name": "echo-agent",
"url": "http://127.0.0.1:9001"
}'Update Agent
Update an existing agent's AgentCard.
Endpoint: PUT /api/v1/agents/{id}
Authentication: Required (Admin JWT only)
Path Parameters:
id(required): Agent ID
Request Body:
{
"agent_card": "{\"protocol_version\":\"1.0\",\"name\":\"Updated Agent\",...}"
}Response:
{
"success": true,
"data": {
"id": 1,
"name": "echo-agent",
"status": "active",
"agent_card": {...},
"updated_at": "2025-12-10T12:30:00Z"
}
}Example:
curl -X PUT http://localhost:8080/api/v1/agents/1 \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-d '{
"agent_card": "{\"protocol_version\":\"1.0\",\"name\":\"Updated Agent\",...}"
}'Delete Agent
Delete an agent from the registry.
Endpoint: DELETE /api/v1/agents/{id}
Authentication: Required (Admin JWT only)
Path Parameters:
id(required): Agent ID
Response:
{
"success": true,
"message": "Agent deleted successfully"
}Example:
curl -X DELETE http://localhost:8080/api/v1/agents/1 \
-H "Authorization: Bearer YOUR_JWT_TOKEN"Agent Invocation Endpoints
Invoke Agent
Send a message to an agent and receive a response.
Endpoint: POST /api/v1/agents/{id}/invoke
Authentication: Required (API Key or JWT)
Path Parameters:
id(required): Agent ID
Request Body:
{
"message": {
"role": "user",
"parts": [
{
"kind": "text",
"text": "Hello, agent!"
}
]
},
"streaming": false,
"configuration": {
"blocking": true,
"history_length": 10
}
}Response (Non-Streaming):
{
"success": true,
"data": {
"task": {
"id": "task-123",
"context_id": "context-456",
"status": {
"state": "TASK_STATE_COMPLETED",
"message": {...}
},
"artifacts": [...],
"history": [...]
}
}
}Response (Streaming): Returns Server-Sent Events (SSE) stream:
data: {"task": {...}}
data: {"message": {...}}
data: {"status_update": {...}}Example (Non-Streaming):
curl -X POST http://localhost:8080/api/v1/agents/1/invoke \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY" \
-d '{
"message": {
"role": "user",
"parts": [{"kind": "text", "text": "Hello"}]
},
"streaming": false
}'Example (Streaming):
curl -X POST http://localhost:8080/api/v1/agents/1/invoke \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY" \
-H "Accept: text/event-stream" \
-d '{
"message": {
"role": "user",
"parts": [{"kind": "text", "text": "Hello"}]
},
"streaming": true
}'Error Responses:
Rate Limit Exceeded (429):
{
"success": false,
"error": "rate limit exceeded: 10 requests per minute",
"error_code": "RATE_LIMIT_EXCEEDED"
}Policy Violation (403):
{
"success": false,
"error": "Request blocked by security policy",
"error_code": "POLICY_VIOLATION"
}Task Management Endpoints
List Tasks
List tasks for an agent.
Endpoint: GET /api/v1/agents/{id}/tasks
Authentication: Required (API Key or JWT)
Path Parameters:
id(required): Agent ID
Query Parameters:
context_id(optional): Filter by context IDstatus(optional): Filter by task statepage_size(optional): Number of results (default: 50, max: 100)page_token(optional): Pagination tokenhistory_length(optional): Number of messages to include in history
Response:
{
"success": true,
"data": {
"tasks": [
{
"id": "task-123",
"context_id": "context-456",
"status": {
"state": "TASK_STATE_COMPLETED",
"message": {...},
"timestamp": "2025-12-10T12:00:00Z"
},
"artifacts": [...],
"history": [...]
}
],
"next_page_token": "...",
"page_size": 50,
"total_size": 100
}
}Example:
curl -X GET "http://localhost:8080/api/v1/agents/1/tasks?status=TASK_STATE_COMPLETED" \
-H "X-API-Key: YOUR_API_KEY"Get Task
Get detailed information about a specific task.
Endpoint: GET /api/v1/agents/{id}/tasks/{taskId}
Authentication: Required (API Key or JWT)
Path Parameters:
id(required): Agent IDtaskId(required): Task ID
Query Parameters:
history_length(optional): Number of messages to include in history
Response:
{
"success": true,
"data": {
"id": "task-123",
"context_id": "context-456",
"status": {
"state": "TASK_STATE_COMPLETED",
"message": {...},
"timestamp": "2025-12-10T12:00:00Z"
},
"artifacts": [...],
"history": [...],
"metadata": {...}
}
}Example:
curl -X GET "http://localhost:8080/api/v1/agents/1/tasks/task-123?history_length=20" \
-H "X-API-Key: YOUR_API_KEY"Cancel Task
Cancel a running task.
Endpoint: POST /api/v1/agents/{id}/tasks/{taskId}/cancel
Authentication: Required (API Key or JWT)
Path Parameters:
id(required): Agent IDtaskId(required): Task ID
Response:
{
"success": true,
"data": {
"id": "task-123",
"status": {
"state": "TASK_STATE_CANCELLED",
"message": {...}
}
}
}Example:
curl -X POST http://localhost:8080/api/v1/agents/1/tasks/task-123/cancel \
-H "X-API-Key: YOUR_API_KEY"A2A Protocol JSON-RPC Endpoints
The Gateway exposes A2A-compliant JSON-RPC endpoints for agent discovery and invocation. These endpoints follow the A2A protocol specification and can be used with standard A2A SDKs.
Gateway Discovery
Discover the Gateway as an A2A hub:
Endpoint: GET /.well-known/agent-card.json
Authentication: Not required (public endpoint)
Response: Returns the Gateway's AgentCard describing its capabilities as an A2A hub.
Example:
curl http://localhost:8080/.well-known/agent-card.jsonJSON-RPC Endpoint
All A2A protocol methods are available via a single JSON-RPC endpoint:
Endpoint: POST /a2a/v1
Authentication: Optional for discovery, required for invocation
Content-Type: application/json
Request Format (JSON-RPC 2.0):
{
"jsonrpc": "2.0",
"id": 1,
"method": "agents/list",
"params": {}
}agents/list
List available agents that the authenticated user can access.
Method: agents/list
Authentication: Optional (API Key recommended for access filtering)
Parameters:
{
"status": "active",
"search": "echo",
"limit": 50,
"offset": 0
}Response:
{
"jsonrpc": "2.0",
"id": 1,
"result": [
{
"name": "Echo Agent",
"description": "A simple test agent",
"version": "1.0.0",
"protocol_version": "1.0",
"supported_interfaces": [
{
"url": "http://127.0.0.1:9001/invoke",
"protocol_binding": "JSONRPC"
}
],
"capabilities": {
"streaming": true
},
"skills": [...]
}
]
}Example:
curl -X POST http://localhost:8080/a2a/v1 \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "agents/list",
"params": {
"status": "active"
}
}'agents/get
Get the AgentCard for a specific agent.
Method: agents/get
Authentication: Required (API Key or Admin JWT)
Parameters:
{
"agent_id": 1
}Response:
{
"jsonrpc": "2.0",
"id": 2,
"result": {
"name": "Echo Agent",
"description": "A simple test agent",
"version": "1.0.0",
"protocol_version": "1.0",
"supported_interfaces": [...],
"capabilities": {
"streaming": true
},
"skills": [...]
}
}Example:
curl -X POST http://localhost:8080/a2a/v1 \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY" \
-d '{
"jsonrpc": "2.0",
"id": 2,
"method": "agents/get",
"params": {
"agent_id": 1
}
}'agents/invoke (Non-Streaming)
Invoke an agent through the Gateway (non-streaming).
Method: agents/invoke
Authentication: Required (API Key or Admin JWT)
Parameters:
{
"agent_id": 1,
"message": {
"role": "user",
"parts": [
{
"kind": "text",
"text": "Hello, agent!"
}
]
},
"streaming": false
}Response:
{
"jsonrpc": "2.0",
"id": 3,
"result": {
"messageId": "msg-123",
"role": "agent",
"parts": [
{
"kind": "text",
"text": "Echo: Hello, agent!"
}
]
}
}Example:
curl -X POST http://localhost:8080/a2a/v1 \
-H "Content-Type: application/json" \
-H "X-API-Key: YOUR_API_KEY" \
-d '{
"jsonrpc": "2.0",
"id": 3,
"method": "agents/invoke",
"params": {
"agent_id": 1,
"message": {
"role": "user",
"parts": [{"kind": "text", "text": "Hello, agent!"}]
},
"streaming": false
}
}'agents/invoke (Streaming)
Invoke an agent with streaming responses via Server-Sent Events (SSE).
Method: agents/invoke
Authentication: Required (API Key or Admin JWT)
Parameters:
{
"agent_id": 1,
"message": {
"role": "user",
"parts": [
{
"kind": "text",
"text": "Hello, agent!"
}
]
},
"streaming": true
}Headers:
Accept: text/event-stream(optional, can also usestreaming: truein params)
Response Format: Server-Sent Events (SSE) stream
Each event is a JSON-RPC 2.0 response:
data: {"jsonrpc":"2.0","id":3,"result":{"kind":"task","id":"task-123","status":{"state":"working"}}}
data: {"jsonrpc":"2.0","id":3,"result":{"kind":"message","messageId":"msg-1","role":"agent","parts":[{"kind":"text","text":"Processing..."}]}}
data: {"jsonrpc":"2.0","id":3,"result":{"kind":"task","id":"task-123","status":{"state":"completed"}}}Example:
curl -X POST http://localhost:8080/a2a/v1 \
-H "Content-Type: application/json" \
-H "Accept: text/event-stream" \
-H "X-API-Key: YOUR_API_KEY" \
-d '{
"jsonrpc": "2.0",
"id": 3,
"method": "agents/invoke",
"params": {
"agent_id": 1,
"message": {
"role": "user",
"parts": [{"kind": "text", "text": "Hello, agent!"}]
},
"streaming": true
}
}' \
--no-buffer \
-NNote: The --no-buffer and -N flags are important for curl to properly handle SSE streams.
Error Responses (in SSE stream):
data: {"jsonrpc":"2.0","id":3,"error":{"code":-32000,"message":"Rate limit exceeded","data":"rate limit exceeded: 10 requests per minute"}}Access Control Endpoints
List Access Controls
List access controls for an agent.
Endpoint: GET /api/v1/agents/{id}/access
Authentication: Required (Admin JWT only)
Path Parameters:
id(required): Agent ID
Response:
{
"success": true,
"data": [
{
"id": 1,
"agent_id": 1,
"user_group_id": 1,
"user_group_name": "Engineering",
"rate_limit": 10,
"active": true,
"created_at": "2025-12-10T12:00:00Z",
"updated_at": "2025-12-10T12:00:00Z"
}
]
}Example:
curl -X GET http://localhost:8080/api/v1/agents/1/access \
-H "Authorization: Bearer YOUR_JWT_TOKEN"Create Access Control
Create a new access control entry for an agent.
Endpoint: POST /api/v1/agents/{id}/access
Authentication: Required (Admin JWT only)
Path Parameters:
id(required): Agent ID
Request Body:
{
"user_group_id": 1,
"rate_limit": 10,
"active": true
}Response:
{
"success": true,
"data": {
"id": 1,
"agent_id": 1,
"user_group_id": 1,
"rate_limit": 10,
"active": true,
"created_at": "2025-12-10T12:00:00Z",
"updated_at": "2025-12-10T12:00:00Z"
}
}Example:
curl -X POST http://localhost:8080/api/v1/agents/1/access \
-H "Content-Type: application/json" \
-H "Authorization: Bearer YOUR_JWT_TOKEN" \
-d '{
"user_group_id": 1,
"rate_limit": 10,
"active": true
}'Delete Access Control
Remove an access control entry.
Endpoint: DELETE /api/v1/agents/{id}/access/{accessId}
Authentication: Required (Admin JWT only)
Path Parameters:
id(required): Agent IDaccessId(required): Access Control ID
Response:
{
"success": true,
"message": "Access control removed successfully"
}Example:
curl -X DELETE http://localhost:8080/api/v1/agents/1/access/1 \
-H "Authorization: Bearer YOUR_JWT_TOKEN"Audit Logs Endpoints
Get Agent Logs
Get invocation logs for an agent.
Endpoint: GET /api/v1/agents/{id}/logs
Authentication: Required (Admin JWT only)
Path Parameters:
id(required): Agent ID
Query Parameters:
limit(optional): Number of results (default: 50, max: 100)offset(optional): Pagination offset (default: 0)
Response:
{
"success": true,
"data": [
{
"id": 1,
"agent_id": 1,
"agent_name": "echo-agent",
"user_id": "apikey:123",
"user_type": "apikey",
"user_identity": "my-api-key",
"task_id": "task-123",
"invocation_type": "send_message",
"response_status": 200,
"duration_ms": 150,
"blocked": false,
"risk_score": 5,
"rate_limit_exceeded": false,
"rate_limit_applied": 10,
"source_ip": "127.0.0.1",
"user_agent": "curl/7.68.0",
"created_at": "2025-12-10T12:00:00Z"
}
]
}Example:
curl -X GET "http://localhost:8080/api/v1/agents/1/logs?limit=50&offset=0" \
-H "Authorization: Bearer YOUR_JWT_TOKEN"A2A Error Responses
All endpoints return errors in a consistent format:
{
"success": false,
"error": "Error message",
"error_code": "ERROR_CODE"
}A2A Common Error Codes
BAD_REQUEST(400): Invalid request parametersUNAUTHORIZED(401): Authentication requiredFORBIDDEN(403): Access deniedNOT_FOUND(404): Resource not foundRATE_LIMIT_EXCEEDED(429): Rate limit exceededINTERNAL_ERROR(500): Internal server errorAPI_ERROR(500): API operation failed
A2A API Rate Limit Errors
When rate limits are exceeded:
Status Code: 429 Too Many Requests
Response:
{
"success": false,
"error": "rate limit exceeded: 10 requests per minute",
"error_code": "RATE_LIMIT_EXCEEDED"
}A2A API Rate Limiting
Rate limits are enforced per user group per agent:
- Window: 1 minute rolling window
- Unit: Requests per minute
- Enforcement: Applied before agent invocation
- Error: HTTP 429 when exceeded
Headers (when rate limit exceeded):
Retry-After: Suggested retry time (in seconds)
A2A API Best Practices
Authentication Best Practices
- Use API Keys: For programmatic access, use API keys
- Secure Storage: Store API keys securely, never commit to version control
- Rotate Keys: Regularly rotate API keys for security
A2A API Error Handling
- Check Status Codes: Always check HTTP status codes
- Handle Rate Limits: Implement retry logic with exponential backoff
- Log Errors: Log all errors for debugging
Performance
- Use Streaming: For long-running operations, use streaming mode
- Pagination: Use pagination for large result sets
- Caching: Cache agent information when possible
A2A API Security
- Validate Input: Validate all input before sending to agents
- Monitor Logs: Regularly review audit logs
- Rate Limits: Configure appropriate rate limits
A2A API Related Documentation
- A2A Agent Registry Guide - User guide for agent management
- A2A Protocol Technical Guide - Technical implementation details
- API Key Authentication - Managing API keys
Need Help? Check the Troubleshooting Guide or review the Agent Registry Guide for detailed usage instructions.