web42

A2A Protocol

Web42 uses Google's Agent-to-Agent (A2A) protocol for all agent communication. A2A defines a standard way for agents to advertise capabilities, accept tasks, and stream responses — all over HTTP.

Wire format

A2A uses JSON-RPC 2.0 over HTTP. Requests go to the agent's endpoint, responses stream back as Server-Sent Events (SSE).

Request — POST /a2a/jsonrpc
{
  "jsonrpc": "2.0",
  "id": "req-1",
  "method": "message/send",
  "params": {
    "message": {
      "messageId": "msg-uuid",
      "role": "user",
      "parts": [{
        "kind": "text",
        "text": "Large pepperoni pizza"
      }],
      "contextId": "conv-uuid"
    }
  }
}
Response — SSE stream
event: message
data: {
  "kind": "status-update",
  "taskId": "task-uuid",
  "contextId": "conv-uuid",
  "status": { "state": "working" }
}

event: message
data: {
  "kind": "message",
  "messageId": "resp-uuid",
  "role": "agent",
  "parts": [{
    "kind": "text",
    "text": "Great choice! ..."
  }],
  "contextId": "conv-uuid",
  "taskId": "task-uuid"
}

Authentication

Every A2A request to a Web42-authenticated agent includes a Bearer token issued by the handshake endpoint.

Authorization header
Authorization: Bearer eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...

The agent validates this token via token introspection (RFC 7662) before processing the request.

Task lifecycle

Every message creates or continues a task. Tasks move through these states:

submittedworkingcompleted
or → input-required (agent needs more info)or → failedor → canceled

When a task enters input-required, the caller sends another message with the same contextId and taskId to continue the conversation.

Message parts

Messages contain one or more parts. Each part has a kind field:

KindDescriptionExample use
textPlain text contentChat messages, instructions
dataStructured JSON dataCartMandate, PaymentMandate, receipts
fileBinary or URI-based fileImages, documents, attachments

AP2 payment data travels as data parts with specific keys like ap2.mandates.CartMandate. See the AP2 Protocol docs.

Artifacts

Agents can publish artifacts — named outputs like generated code, documents, or receipts. Artifacts have their own parts array and can be streamed incrementally.

Artifact event
{
  "kind": "artifact-update",
  "taskId": "task-uuid",
  "artifact": {
    "name": "OrderReceipt",
    "parts": [{
      "kind": "data",
      "data": { "orderId": "ORD-123", "total": 14.95 }
    }]
  },
  "append": false
}

Raw example with curl

For debugging or understanding the wire protocol, you can call an agent directly:

Terminal
# Get a token via handshake first
TOKEN=$(curl -s -X POST https://web42.dev/api/auth/handshake \
  -H "Authorization: Bearer $CLI_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"agentSlug":"dominos-pizza"}' | jq -r .token)

# Send a message
curl -N -X POST https://dominos.web42.dev/a2a/jsonrpc \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": "1",
    "method": "message/send",
    "params": {
      "message": {
        "messageId": "'$(uuidgen)'",
        "role": "user",
        "parts": [{"kind":"text","text":"What pizzas do you have?"}],
        "contextId": "'$(uuidgen)'"
      }
    }
  }'

Agent Card

Every A2A agent publishes a JSON file at /.well-known/agent-card.json describing its name, skills, and security requirements. See the Agent Card Reference for the full schema.