Skip to content

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/agents

A2A 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:

bash
curl -H "X-API-Key: YOUR_API_KEY" \
  http://localhost:8080/api/v1/agents

Characteristics:

  • 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:

bash
curl -H "Authorization: Bearer YOUR_JWT_TOKEN" \
  http://localhost:8080/api/v1/agents

Characteristics:

  • Admin users can access all agents (no user group restrictions)
  • OAuth session tokens also work with Authorization: Bearer header
  • Required for agent management (create, update, delete)
  • Higher rate limits than API keys

3. Public Discovery (No Authentication)

Some A2A endpoints support unauthenticated discovery:

bash
# 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:

javascript
// 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 name
  • limit (optional): Number of results (default: 50, max: 100)
  • offset (optional): Pagination offset (default: 0)

Response:

json
{
  "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:

bash
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:

json
{
  "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:

bash
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):

json
{
  "name": "my-agent",
  "url": "http://127.0.0.1:9001"
}

Request Body (Manual AgentCard):

json
{
  "name": "my-agent",
  "agent_card": "{\"protocol_version\":\"1.0\",\"name\":\"My Agent\",...}"
}

Response:

json
{
  "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:

bash
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:

json
{
  "agent_card": "{\"protocol_version\":\"1.0\",\"name\":\"Updated Agent\",...}"
}

Response:

json
{
  "success": true,
  "data": {
    "id": 1,
    "name": "echo-agent",
    "status": "active",
    "agent_card": {...},
    "updated_at": "2025-12-10T12:30:00Z"
  }
}

Example:

bash
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:

json
{
  "success": true,
  "message": "Agent deleted successfully"
}

Example:

bash
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:

json
{
  "message": {
    "role": "user",
    "parts": [
      {
        "kind": "text",
        "text": "Hello, agent!"
      }
    ]
  },
  "streaming": false,
  "configuration": {
    "blocking": true,
    "history_length": 10
  }
}

Response (Non-Streaming):

json
{
  "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):

bash
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):

bash
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):

json
{
  "success": false,
  "error": "rate limit exceeded: 10 requests per minute",
  "error_code": "RATE_LIMIT_EXCEEDED"
}

Policy Violation (403):

json
{
  "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 ID
  • status (optional): Filter by task state
  • page_size (optional): Number of results (default: 50, max: 100)
  • page_token (optional): Pagination token
  • history_length (optional): Number of messages to include in history

Response:

json
{
  "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:

bash
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 ID
  • taskId (required): Task ID

Query Parameters:

  • history_length (optional): Number of messages to include in history

Response:

json
{
  "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:

bash
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 ID
  • taskId (required): Task ID

Response:

json
{
  "success": true,
  "data": {
    "id": "task-123",
    "status": {
      "state": "TASK_STATE_CANCELLED",
      "message": {...}
    }
  }
}

Example:

bash
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:

bash
curl http://localhost:8080/.well-known/agent-card.json

JSON-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):

json
{
  "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:

json
{
  "status": "active",
  "search": "echo",
  "limit": 50,
  "offset": 0
}

Response:

json
{
  "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:

bash
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:

json
{
  "agent_id": 1
}

Response:

json
{
  "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:

bash
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:

json
{
  "agent_id": 1,
  "message": {
    "role": "user",
    "parts": [
      {
        "kind": "text",
        "text": "Hello, agent!"
      }
    ]
  },
  "streaming": false
}

Response:

json
{
  "jsonrpc": "2.0",
  "id": 3,
  "result": {
    "messageId": "msg-123",
    "role": "agent",
    "parts": [
      {
        "kind": "text",
        "text": "Echo: Hello, agent!"
      }
    ]
  }
}

Example:

bash
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:

json
{
  "agent_id": 1,
  "message": {
    "role": "user",
    "parts": [
      {
        "kind": "text",
        "text": "Hello, agent!"
      }
    ]
  },
  "streaming": true
}

Headers:

  • Accept: text/event-stream (optional, can also use streaming: true in 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:

bash
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 \
  -N

Note: 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:

json
{
  "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:

bash
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:

json
{
  "user_group_id": 1,
  "rate_limit": 10,
  "active": true
}

Response:

json
{
  "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:

bash
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 ID
  • accessId (required): Access Control ID

Response:

json
{
  "success": true,
  "message": "Access control removed successfully"
}

Example:

bash
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:

json
{
  "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:

bash
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:

json
{
  "success": false,
  "error": "Error message",
  "error_code": "ERROR_CODE"
}

A2A Common Error Codes

  • BAD_REQUEST (400): Invalid request parameters
  • UNAUTHORIZED (401): Authentication required
  • FORBIDDEN (403): Access denied
  • NOT_FOUND (404): Resource not found
  • RATE_LIMIT_EXCEEDED (429): Rate limit exceeded
  • INTERNAL_ERROR (500): Internal server error
  • API_ERROR (500): API operation failed

A2A API Rate Limit Errors

When rate limits are exceeded:

Status Code: 429 Too Many Requests

Response:

json
{
  "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

Need Help? Check the Troubleshooting Guide or review the Agent Registry Guide for detailed usage instructions.