A2A Protocol
The A2A (Agent-to-Agent) Protocol enables secure delegation between agents across sandboxes and organizations. This is a Linux Foundation standard (April 2026).
Agent Discovery
Get Agent Card
Discover a Caged-hosted A2A agent's capabilities.
curl https://api.caged.dev/.well-known/agent.json \
-H "Accept: application/json"
Response 200 OK
{
"agents": [
{
"name": "Code Analyzer",
"description": "Analyzes code for security vulnerabilities",
"url": "https://api.caged.dev/v1/a2a/agents/agent_abc123",
"version": "1.0.0",
"capabilities": ["streaming", "push"],
"input_modes": ["text", "json"],
"output_modes": ["text", "json", "file"],
"skills": [
{
"id": "analyze",
"name": "Code Analysis",
"description": "Static analysis for security issues",
"tags": ["security", "static-analysis"]
}
],
"authentication": {
"type": "bearer",
"schemes": ["api_key"]
},
"provider": {
"name": "Caged",
"organization": "Bytangle Ltd",
"url": "https://caged.dev"
}
}
],
"protocol_version": "1.0"
}
Get Specific Agent Card
curl https://api.caged.dev/.well-known/agent/{agentId}.json \
-H "Accept: application/json"
Agent Registration
Create Agent Registration
Register your agent to be discoverable via A2A.
curl -X POST https://api.caged.dev/v1/a2a/agents \
-H "Authorization: Bearer caged_sk_..." \
-H "Content-Type: application/json" \
-d '{
"name": "Security Auditor",
"description": "Scans repositories for security vulnerabilities",
"pipeline_id": "pipe_abc123",
"template": "python-3.12",
"skills": [
{
"id": "scan",
"name": "Security Scan",
"description": "Full security audit of codebase",
"tags": ["security", "audit", "cve"],
"input_schema": {
"type": "object",
"properties": {
"repo": { "type": "string", "description": "Repository URL" },
"branch": { "type": "string", "default": "main" }
},
"required": ["repo"]
}
}
],
"public": true,
"max_cost_per_task": 10.00,
"rate_limit_rpm": 60
}'
Response 201 Created
{
"id": "agent_x1y2z3",
"account_id": "acc_abc123",
"name": "Security Auditor",
"description": "Scans repositories for security vulnerabilities",
"pipeline_id": "pipe_abc123",
"template": "python-3.12",
"skills": [...],
"public": true,
"enabled": true,
"max_cost_per_task": 10.00,
"rate_limit_rpm": 60,
"created_at": "2026-08-02T10:00:00Z",
"updated_at": "2026-08-02T10:00:00Z"
}
List Agent Registrations
curl https://api.caged.dev/v1/a2a/agents \
-H "Authorization: Bearer caged_sk_..."
Response 200 OK
{
"agents": [
{
"id": "agent_x1y2z3",
"name": "Security Auditor",
"enabled": true,
"public": true,
"skills": [...]
}
]
}
Get Agent Registration
curl https://api.caged.dev/v1/a2a/agents/{id} \
-H "Authorization: Bearer caged_sk_..."
Update Agent Registration
curl -X PUT https://api.caged.dev/v1/a2a/agents/{id} \
-H "Authorization: Bearer caged_sk_..." \
-H "Content-Type: application/json" \
-d '{
"description": "Updated description",
"enabled": true,
"max_cost_per_task": 20.00
}'
Delete Agent Registration
curl -X DELETE https://api.caged.dev/v1/a2a/agents/{id} \
-H "Authorization: Bearer caged_sk_..."
Response 204 No Content
Task Management
Create Task
Delegate a task to an A2A agent.
curl -X POST https://api.caged.dev/v1/a2a/agents/{agentId}/tasks \
-H "Authorization: Bearer caged_sk_..." \
-H "Content-Type: application/json" \
-d '{
"skill_id": "scan",
"input": {
"repo": "https://github.com/org/repo",
"branch": "main"
},
"priority": 5
}'
Response 201 Created
{
"id": "task_abc123",
"agent_id": "agent_x1y2z3",
"status": "pending",
"skill_id": "scan",
"input": {
"repo": "https://github.com/org/repo",
"branch": "main"
},
"priority": 5,
"created_at": "2026-08-02T10:00:00Z",
"updated_at": "2026-08-02T10:00:00Z"
}
Get Task
curl https://api.caged.dev/v1/a2a/tasks/{taskId} \
-H "Authorization: Bearer caged_sk_..."
Response 200 OK
{
"id": "task_abc123",
"agent_id": "agent_x1y2z3",
"status": "running",
"status_message": "Analyzing dependencies...",
"progress": {
"percentage": 45,
"current_step": "dependency_scan",
"message": "Scanning 234/520 files"
},
"skill_id": "scan",
"input": {...},
"started_at": "2026-08-02T10:00:05Z",
"created_at": "2026-08-02T10:00:00Z",
"updated_at": "2026-08-02T10:01:30Z"
}
Task Status Values
| Status | Description |
|---|---|
pending |
Task created, awaiting execution |
running |
Task is being executed |
completed |
Task finished successfully |
failed |
Task failed with error |
canceled |
Task was canceled |
input_needed |
Task requires additional input |
List Tasks
curl "https://api.caged.dev/v1/a2a/tasks?status=running&limit=10" \
-H "Authorization: Bearer caged_sk_..."
Query Parameters
| Parameter | Type | Description |
|---|---|---|
status |
string | Filter by status |
agent_id |
string | Filter by agent |
limit |
int | Max results (default 20) |
offset |
int | Pagination offset |
Send Message
Send a message to a task (for input_needed tasks or ongoing conversation).
curl -X POST https://api.caged.dev/v1/a2a/tasks/{taskId}/messages \
-H "Authorization: Bearer caged_sk_..." \
-H "Content-Type: application/json" \
-d '{
"parts": [
{
"type": "text",
"text": "Yes, include the dev dependencies in the scan."
}
]
}'
Response 201 Created
{
"id": "msg_xyz789",
"task_id": "task_abc123",
"role": "user",
"parts": [
{
"type": "text",
"text": "Yes, include the dev dependencies in the scan."
}
],
"created_at": "2026-08-02T10:02:00Z"
}
Message Part Types
| Type | Description | Fields |
|---|---|---|
text |
Plain text | text |
data |
Structured JSON | data, name |
file |
File reference | name, mime_type, data (base64) |
Cancel Task
curl -X POST https://api.caged.dev/v1/a2a/tasks/{taskId}/cancel \
-H "Authorization: Bearer caged_sk_..." \
-H "Content-Type: application/json" \
-d '{
"reason": "No longer needed"
}'
Response 200 OK
{
"id": "task_abc123",
"status": "canceled",
"status_message": "No longer needed"
}
Task Streaming
Stream Task Events (SSE)
Subscribe to real-time task updates via Server-Sent Events.
curl -N https://api.caged.dev/v1/a2a/tasks/{taskId}/stream \
-H "Authorization: Bearer caged_sk_..." \
-H "Accept: text/event-stream"
Event Types
event: status
data: {"status": "running", "message": "Starting execution..."}
event: progress
data: {"percentage": 25, "current_step": "clone", "message": "Cloning repository..."}
event: message
data: {"role": "agent", "parts": [{"type": "text", "text": "Found 3 security issues"}]}
event: artifact
data: {"id": "art_123", "name": "report.json", "mime_type": "application/json"}
event: complete
data: {"status": "completed", "output": {"findings": 3, "severity": "medium"}}
event: error
data: {"status": "failed", "error": "Repository not accessible"}
Webhook Push Notifications
Subscribe to Task Events
Register a webhook to receive task updates.
curl -X POST https://api.caged.dev/v1/a2a/webhooks \
-H "Authorization: Bearer caged_sk_..." \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-server.com/webhook/a2a",
"events": ["task.completed", "task.failed", "task.input_needed"],
"secret": "whsec_..."
}'
Webhook Payload
{
"event": "task.completed",
"timestamp": "2026-08-02T10:05:00Z",
"task": {
"id": "task_abc123",
"status": "completed",
"output": {...}
},
"signature": "sha256=..."
}
Error Responses
All A2A endpoints return standard error responses:
{
"error": {
"code": "task_not_found",
"message": "Task task_abc123 not found",
"details": {}
}
}
Error Codes
| Code | HTTP Status | Description |
|---|---|---|
agent_not_found |
404 | Agent registration not found |
agent_disabled |
403 | Agent is disabled |
task_not_found |
404 | Task not found |
skill_not_found |
400 | Requested skill doesn't exist |
rate_limited |
429 | Rate limit exceeded |
budget_exceeded |
402 | Task would exceed cost limit |
invalid_input |
400 | Input doesn't match skill schema |
Rate Limits
A2A endpoints have the following rate limits:
| Endpoint | Limit |
|---|---|
| Agent Card discovery | 100/min (unauthenticated) |
| Task creation | Per-agent rate_limit_rpm setting |
| Task polling | 60/min per task |
| Streaming | 1 connection per task |