Skip to main content

A2A Integration

The Agent-to-Agent (A2A) protocol integration enables AI agents to communicate with each other using payment-protected message streams. The Nevermined Payments Library provides complete A2A server functionality with automatic payment handling.

Overview of A2A Integration

The A2A integration provides:
  • Agent Card: Payment metadata extension for discovery
  • Streaming Support: Real-time task updates via Server-Sent Events
  • Task Management: Async execution with status tracking
  • Credit Burning: Automatic credit settlement after task completion
  • EventBus Pattern: Clean event-driven architecture for task execution

Build Payment Agent Card

The agent card is published at the canonical /.well-known/agent-card.json (A2A 0.3+), with the legacy /.well-known/agent.json kept as a backward-compat alias. It includes payment metadata. Before sending a paid request, clients should fetch and validate the target agent’s card to confirm the expected agentId, the capabilities, and the supported X402 schemes — this protects against routing payment tokens to a typosquatted or unauthorised endpoint:

Payment Extension Structure

The agent card declares two extensions in capabilities.extensions: the Nevermined payment extension (pricing metadata) and the official a2a-x402 extension (https://github.com/google-agentic-commerce/a2a-x402/blob/main/spec/v0.2), which signals support for the standards-compliant in-band x402 v2 flow (see below). Both are emitted for one release; urn:nevermined:payment will be dropped once clients migrate to v0.2 only.

x402 v2 In-Band Payments (Standards Flow)

Payment is signalled in band following the Coinbase x402 v2 A2A transport spec and the official a2a-x402 extension. No HTTP 402 is involved — the whole handshake rides on A2A task/message metadata, correlated by taskId. This is automatic when you use payments.a2a.start; nothing changes in your executor. Lifecycle:
  1. Payment required — a payment-gated message/send arrives with no payment. The server returns a Task with status.state = "input-required" and status.message.metadata:
  2. Payment submitted — the client sends a follow-up message/send whose message.metadata carries the payload, correlated via message.taskId:
  3. Completed / failed — on success the final Task carries x402.payment.status: "payment-completed" plus x402.payment.receipts (array of settle receipts). On failure it is failed / x402.payment.status: "payment-failed" with the error under x402.payment.error, and paid content is suppressed.
Metadata keys: x402.payment.status, x402.payment.required, x402.payment.payload, x402.payment.receipts, x402.payment.error.
Batch (deferred) settlement. If the server settles credits in batch, a successful call returns x402.payment.status: "payment-verified" (not payment-completed) plus the Nevermined marker x402.payment.settlement: "deferred" — the payment was verified but settled out-of-band, so there is no in-band receipt. Spec-only clients ignore the unknown key.
⚠️ Header flow deprecated. The legacy payment-signature HTTP header still works but is now a deprecated fallback, kept for one release. New integrations should rely on the in-band metadata flow above.

Implement Executor

The executor contains your agent’s business logic and emits events via the EventBus:

EventBus Events

The executor communicates via event publishing:

Task Event

Status Update Event

Message Event (Streaming)

Signal Completion

Start A2A Server

Start the complete A2A server with payment integration:
🔐 Run behind a reverse proxy with HTTPS in production. A2A peers exchange paid tokens — in band via x402.payment.payload, or over the deprecated payment-signature header — so never expose the raw server on a public hostname without TLS. Bind the dev server to 127.0.0.1 (e.g. by running it inside a container with no published port, or behind a localhost-bound proxy).

Credit Reporting

The executor reports credits used in the final status update:

Fixed Credits

Dynamic Credits

Calculate credits based on actual usage:

Streaming Example

For long-running tasks, stream partial results:

Complete Example: Weather A2A Agent

Server Configuration Options

Best Practices

  1. Always Report Credits: Include creditsUsed in final status updates
  2. Handle Errors: Emit ‘failed’ status on errors
  3. Signal Completion: Always call eventBus.finished()
  4. Streaming for Long Tasks: Use message events for real-time updates
  5. Graceful Shutdown: Implement proper server cleanup
  6. Descriptive Agent Cards: Provide clear descriptions and skills
  7. Version Control: Include version in agent card metadata

Source References:
  • RUN.md (A2A Server section, lines 88-156)
  • src/a2a/server.ts (PaymentsA2AServer)
  • src/a2a/agent-card.ts (buildPaymentAgentCard)
  • tests/integration/a2a/complete-message-send-flow.test.ts (executor patterns)
  • tests/e2e/helpers/a2a-setup-helpers.ts (setup examples)