The press · AI Agent Development · filed 2026-05-13 · updated 2026-07-10
Implement Google A2A: Bridge Your Agent Into Agent-to-Agent Commerce
A working A2A bridge: agent cards, task lifecycle, SSE streaming, push notifications, and the commerce-protocol translation layer.
The problem
This book gives you a working Google A2A bridge: Agent Card discovery, the six-method JSON-RPC surface, SSE streaming, push notifications, and the translation layer that routes A2A tasks into AP2 or ACP payments. The whole protocol surface is six JSON-RPC methods — small enough to implement deliberately, specific enough that improvising the framing gets the error codes wrong.
For three decades, software systems talked to each other through APIs designed, maintained, and invoked by humans — one endpoint, one schema, one expected response, a human fixing the integration when it broke. A2A replaces that: AI agents discover each other’s capabilities, delegate tasks, stream progress, and coordinate across organizational boundaries without a human in the middle. If your agent does not speak A2A, it cannot be discovered by, delegated to, or paid by the agents that do.
This walks through implementing an A2A bridge: the Agent Card discovery contract, the task lifecycle state machine, JSON-RPC method routing, SSE streaming for long-running tasks, push notifications for async results, and the translation layer that maps A2A tasks onto AP2 / ACP commerce protocols underneath.
What most people get wrong
Mistake one: building A2A as a wrapper around an existing REST API. A2A is not REST. There are no resource URLs, no HTTP verbs for CRUD, no GET /tasks/{id}. Every interaction is a JSON-RPC 2.0 method call: message/send, message/stream, tasks/get, tasks/cancel. The protocol picked JSON-RPC for three reasons — it is transport-agnostic (HTTP, WebSocket, gRPC), trivially parseable, and supports batch operations natively. Mapping POST /a2a to whatever REST endpoint already exists usually means inventing JSON-RPC framing manually, getting the error codes wrong (A2A defines specific codes: -32001 TASK_NOT_FOUND, -32002 TASK_NOT_CANCELABLE, -32004 UNSUPPORTED_OPERATION), and discovering on integration day that another vendor’s agent cannot speak with yours.
The architectural answer is a thin A2A handler that parses JSON-RPC, dispatches by method, and maps each method to a small set of internal operations. The A2A surface is six methods. The internal handlers stay clean.
Mistake two: streaming when you needed push, or sending when you needed streaming. The choice between message/send (synchronous, single response) and message/stream (Server-Sent Events with incremental updates) determines the entire interaction shape. Use send for operations under 30 seconds: price lookups, capability checks, simple fulfillments. Use stream for anything that produces incremental results: report generation, multi-step fulfillment, creative work. For truly long-running operations (hours or days), combine send with tasks/pushNotification/set so the client can disconnect and receive a webhook on completion. Picking the wrong one means agents time out, miss updates, or hold connections open that should have closed.
This article is the short version — Google A2A Bridge Implementation: Agent-to-Agent Commerce is the full playbook.
Get the ebook — $24A working approach
The build has four parts: the agent card, the message handler, the task store, and the commerce bridge.
1. The Agent Card — published at /.well-known/agent.json so other agents can discover you. JSON metadata with identity, capabilities, endpoint, authentication, and supported input types:
interface AgentCard {
name: string;
description: string;
url: string;
capabilities: string[];
authentication: {
type: 'bearer' | 'oauth2';
token_endpoint?: string;
};
supported_input_types: string[];
supported_output_types: string[];
version: string;
}
When a foreign agent wants to know what you can do, it makes one HTTP GET to your /.well-known/agent.json. Capabilities are short string identifiers — product_search, price_comparison, order_placement. The discovery contract is a single file.
2. The message handler — the heart of the bridge. Parses JSON-RPC, validates the method, dispatches:
export async function handleA2ARequest(
request: Request,
env: Env
): Promise<Response> {
const body = await request.json() as A2ARequest;
// Authenticate first
const authResult = await verifyBearerToken(request, env);
if (!authResult.ok) {
return jsonRpcError(body.id, -32401, 'Unauthorized');
}
// Route to method handler
switch (body.method) {
case 'message/send':
return handleMessageSend(body, env, authResult.agentId);
case 'message/stream':
return handleMessageStream(body, env, authResult.agentId);
case 'tasks/get':
return handleTaskGet(body, env, authResult.agentId);
case 'tasks/cancel':
return handleTaskCancel(body, env, authResult.agentId);
case 'tasks/pushNotification/set':
return handlePushSet(body, env, authResult.agentId);
default:
return jsonRpcError(body.id, -32004, 'UNSUPPORTED_OPERATION');
}
}
3. The task store — backs the seven-state lifecycle. Tasks transition submitted → working → input-required → working → completed | failed | canceled. Cloudflare KV is enough for typical commerce loads (low write throughput, durable, edge-local reads):
type TaskStatus =
| 'submitted' | 'working' | 'input-required'
| 'completed' | 'failed' | 'canceled';
interface Task {
id: string;
status: TaskStatus;
created_at: number;
updated_at: number;
agent_id: string;
messages: Message[];
artifacts: Artifact[];
metadata: Record<string, unknown>;
}
async function setTaskStatus(
env: Env,
taskId: string,
status: TaskStatus,
patch?: Partial<Task>
): Promise<Task> {
const task = await env.A2A_TASKS.get<Task>(taskId, 'json');
if (!task) throw new TaskNotFoundError(taskId);
const updated = { ...task, ...patch, status, updated_at: Date.now() };
await env.A2A_TASKS.put(taskId, JSON.stringify(updated));
return updated;
}
4. The commerce bridge — the translation layer where A2A meets your payment rails. The bridge parses intent and budget from the incoming A2A message, creates an AP2 Intent Mandate or an ACP Checkout Session, processes payment, and returns the result as an A2A task completion:
async function bridgeToCommerce(
task: Task,
env: Env
): Promise<Artifact> {
const intent = parseIntent(task.messages);
// Auto-detect protocol — see Book 09 for the detection middleware
const protocol = detectProtocol(intent);
let receipt: PaymentReceipt;
if (protocol === 'ap2') {
const mandate = await createIntentMandate(intent, env);
receipt = await processAP2Payment(mandate, env);
} else {
const session = await createCheckoutSession(intent, env);
receipt = await processACPPayment(session, env);
}
return {
type: 'data',
content_type: 'application/vnd.commerce.receipt+json',
data: receipt
};
}
The agents on the other side of the bridge never need to understand AP2 or ACP. They speak A2A. The bridge speaks both.
Streaming uses Server-Sent Events. Inside message/stream, the response body is a text/event-stream that emits incremental updates:
async function handleMessageStream(
body: A2ARequest,
env: Env,
agentId: string
): Promise<Response> {
const { readable, writable } = new TransformStream();
const writer = writable.getWriter();
const encoder = new TextEncoder();
// Kick off the task asynchronously
runTask(body, env, agentId, async (event) => {
const sse = `event: ${event.type}\ndata: ${JSON.stringify(event.data)}\n\n`;
await writer.write(encoder.encode(sse));
}).finally(() => writer.close());
return new Response(readable, {
headers: {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache'
}
});
}
Push notifications use tasks/pushNotification/set to register a webhook URL plus an HMAC secret. On completion, the bridge POSTs the result to the URL, signed with HMAC-SHA256 so the receiver can verify origin. The push handler is the simpler path for tasks that take minutes or hours.
This article is the short version — Google A2A Bridge Implementation: Agent-to-Agent Commerce is the full playbook.
Get the ebook — $24Where this scales
The walkthrough above is the bridge spine. The full book covers six more dimensions:
- Signed security cards (v0.3) — JWT-signed Agent Cards for trust verification, signature chain to a DID-anchored authority, and the validation flow that rejects unsigned cards in enterprise deployments.
- Three task patterns — Instant Fulfillment (sub-30s), Multi-Step Fulfillment (sequential sub-tasks), and Negotiation (input-required loops where the agent prompts the caller mid-task).
- Multi-agent orchestration — the orchestrator pattern that drives chain fulfillment across five agents on five platforms, including the $80-wish worked example that yields $18.44 ecosystem revenue (a 23% effective take rate vs. a marketplace baseline of 2.5%).
- Production deployment — Google Cloud Functions for the A2A endpoint (always-free 2M invocations/month), Cloudflare Workers for the commerce logic, Supabase for state, and the canary deployment pattern that lets you ship A2A v0.3 features incrementally.
- Rate limiting and security hardening — sliding-window rate limits keyed on agent ID, the auth chain that verifies both the bearer token and the signed Agent Card, and the abuse patterns A2A bridges actually see in production.
- Cost at scale — measured numbers: 1,000 tasks/day on the free tier, 100,000 tasks/day on the paid tier, what changes at each rung.
Every code example has been tested against Google’s reference A2A clients and against agents running on Salesforce, SAP, and the Pragma.Vision ecosystem. The 23% effective take rate, the $18.44 per $80 wish, the v0.3 protocol details — these are operational numbers from a running bridge, not estimates.
Included with the book
a2a-agent-card-template.json— a production-shaped Agent Card with all required fields, capability identifiers, authentication block, and signed-security-card structure. Drop in your endpoint URL and capabilities and publish to/.well-known/agent.json.
Get the full picture
Google A2A Bridge Implementation: Agent-to-Agent Commerce — everything this article compresses, worked through end to end.
Get the ebook — $24Readers of this also chose
Questions readers ask
Do I need Google Cloud to implement A2A?
No. A2A is an open protocol and works on any platform that can serve HTTP and respond to JSON-RPC 2.0. The book shows a hybrid deployment (Google Cloud Functions for the A2A endpoint, Cloudflare Workers for the commerce logic) because the Cloud Functions free tier is generous, but you can run the whole stack on Workers, on Lambda, on a bare VM. The protocol is platform-agnostic.
What's the relationship between A2A, MCP, and ACP?
Three different planes. MCP is for an agent to use tools (single-agent capability extension). A2A is for agents to coordinate with each other (multi-agent orchestration). ACP (and AP2) are for the commerce settlement underneath. A modern agent commonly speaks all three: MCP to its own tools, A2A to peer agents, AP2/ACP to merchants. The bridge in this book is the layer that translates A2A tasks into AP2/ACP payments.
Does the v0.3 signed security card require my own DID?
It works best with one. The signed Agent Card carries a JWT signature with the issuer's public key, and the most natural issuer model is a DID-anchored identity (covered in Book 14 / Book 15). For first-party deployments you can sign with a static keypair; for enterprise deployments where other agents need to verify, a DID-rooted signature path is the production shape.
How does A2A handle authentication between unknown agents?
The Agent Card declares the authentication scheme. Most common is bearer-token with a token endpoint specified in the card. Enterprise deployments add OAuth2 client credentials. The book covers both, plus the rate-limiting per agent ID once the token is verified, and the pattern for revoking compromised agents from the federation.
What's the refund policy?
Lemon Squeezy's standard refund window applies. The refund link is in the receipt email.