Nevermined Payments integrates with Google A2A to enable heterogenous multi-agent sytems to authorize and charge per request between agents:
  • Discovery: publish your AI Agent Card at /.well-known/agent.json.
  • Streaming and re-subscribe: set capabilities.streaming: true for message/stream and tasks/resubscribe.
  • Authentication: credentials are sent in HTTP headers (e.g., Authorization: Bearer ...), not in the JSON‑RPC payload.
  • Authorization/charging: the agent emits a final event with metadata.creditsUsed; Nevermined validates and burns credits accordingly.

Features

The libraries provide an a2a module that enables seamless integration into new or existing A2A agents, including bearer token authentication, asynchronous task management, and push notification support. Main features:
  • Bearer Token Authentication: The server extracts bearer tokens from the Authorization header and injects them into the task context.
  • Credits Validation: Validates that the user has sufficient credits before executing a task.
  • Credits Burning/Redemption: Redeem the credits specified in the result after successful execution.
  • Push Notifications: Supports the A2A standard flow for push notification configuration and delivery.
  • Asynchronous Task Handling: Supports intermediate and final state events, compatible with polling and streaming.
  • Unified SDK: Provides both agent and client integration.

Quickstart

If you already have a Google A2A agent, or you are building a new one, add the Payments Library to your agent and obtain an API key:
1

1. Get Your API Key

To interact with the Nevermined API, you need an API key.
  1. Go to the Nevermined App.
  2. Log in via Web3Auth.
  3. Navigate to the Settings section in the user menu.
  4. Click on the API Keys tab.
  5. Generate a new key, give it a descriptive name, and copy it.
  6. Store this key securely as an environment variable (e.g., NVM_API_KEY).
2

2. Install and Initialize the Payments Library

Install the Payments Library and initialize the Payments client with your API key.
npm install @nevermined-io/payments

Initialize the Payments Library

import { Payments } from "@nevermined-io/payments"

const payments = Payments.getInstance({
  nvmApiKey,
  environment: 'sandbox',
})

A2A Server

Add the Payment Extension to the Agent Card

Because your AI agent charges for requests, add a payment extension to your agent card. Add a payment extension under capabilities.extensions carrying Nevermined metadata:
{
  "capabilities": {
    "streaming": true,
    "pushNotifications": true,
    "extensions": [
      {
        "uri": "urn:nevermined:payment",
        "description": "Dynamic cost per request",
        "required": false,
        "params": {
          "paymentType": "dynamic",
          "credits": 1,
          "planId": "<planId>",
          "agentId": "<agentId>"
        }
      }
    ]
  },
  "url": "https://your-agent.example.com/a2a/"
}
Important notes:
  • The url must match exactly the URL registered in Nevermined for the agent/plan.
  • The final streaming event must include metadata.creditsUsed with the consumed cost.

Define the Payment Agent Card in Your A2A Agent

const baseAgentCard = {
  name: 'My A2A Server',
  description: 'A2A test server that requires payment',
  capabilities: {
    streaming: true,
    pushNotifications: true,
    stateTransitionHistory: true,
  },
  defaultInputModes: ['text'],
  defaultOutputModes: ['text'],
  skills: [],
  url: 'http://localhost:3005/a2a/',
  version: '1.0.0',
}

const agentCard = payments.a2a.buildPaymentAgentCard(baseAgentCard, {
  paymentType: "dynamic",
  credits: 1,
  planId: process.env.PLAN_ID,
  agentId: process.env.AGENT_ID,
})

Start the A2A Server

The agent is initialized using the Nevermined Payments Library and the A2A protocol. The executor defines the business logic for each type of request.
  • The Executor class routes and handles all supported operations (greeting, calculation, weather, translation, streaming, push notification).
  • The handleTask method returns both the result and a boolean indicating if more updates are expected (for async flows).
  • The agent publishes the initial task, intermediate status updates, and the final event as per the A2A standard.
// Start server on port 3005 for A2A
class Executor implements AgentExecutor {
  async handleTask(context, eventBus) {
    // Returns { result: TaskHandlerResult, expectsMoreUpdates: boolean }
  }
  async cancelTask(taskId) { /* ... */ }

  // Publishes the final status-update event when no more updates are expected
  async execute(requestContext, eventBus) {
    const { result, expectsMoreUpdates } = await this.handleTask(requestContext, eventBus)
    if (expectsMoreUpdates) return
    // Publish final status-update event...
  }
}

serverResult = await paymentsBuilder.a2a.start({
  port: 3005,
  basePath: '/a2a/',
  agentCard: agentCard,
  // Use resubscribe-friendly executor with longer stream to ensure resubscribe has events to consume
  executor: A2AE2EFactory.createResubscribeStreamingExecutor(),
})

serverManager.addServer(serverResult)

A2A Client

The client interacts with the agent using JSON-RPC requests. It can send messages, poll for task status, and configure push notifications.

const paymentsSubscriber = Payments.getInstance({
  nvmApiKey,
  environment: 'sandbox',
})

const client = paymentsSubscriber.a2a.getClient({
  agentBaseUrl: 'http://localhost:3005/a2a/',
  agentId: process.env.AGENT_ID,
  planId: process.env.PLAN_ID
})

Sending a Task

After purchasing access to the payment plan associated with the AI agent, a client can generate an access token and start sending tasks:
// Purchase the Plan
const orderResult = await paymentsSubscriber.plans.orderPlan(planId)
// Get the credentials associated to the agent and plan
const credentials = await paymentsSubscriber.agents.getAgentAccessToken(planId, agentId)


// Test sending an A2A message with correct format
const response = await client.sendMessage(
  "Testing push notification!",
  credentials.accessToken
);
const taskId = response?.result?.id

Full example code

Find a complete working example in the repository: nevermined-io/a2a-agent-client-sample.