Looking for MPP? The Machine Payments Protocol is a second framing over this same plan/credits/delegation core — see 15. MPP Protocol.This guide covers the x402 payment protocol for verifying permissions and settling payments.
Overview
x402 is a payment protocol that enables:- Permission Generation: Subscribers create access tokens for agents
- Permission Verification: Agents verify tokens without burning credits
- Permission Settlement: Agents burn credits after completing work
Supported Schemes
Nevermined supports two x402 payment schemes:
The scheme is determined by the plan’s pricing configuration. Plans with
isCrypto: false use nvm:card-delegation; all others use nvm:erc4337. The SDK auto-detects the scheme via resolve_scheme(). The network value within nvm:card-delegation is determined by which provider issued the delegation being consumed (stripe, braintree, or visa).
Visa support
Visa delegations use the samenvm:card-delegation scheme and SDK surface as Stripe and Braintree, but two steps must happen in a browser before the SDK can consume them:
- Card enrolment — the cardholder enrols a Visa card through VGS Collect (PCI-compliant iframe) in the Nevermined webapp. The card is bound to a Visa Agentic Token via the VGS Credential Management Platform.
- Delegation creation — the cardholder approves a delegation via a WebAuthn/passkey (FIDO) device-binding ceremony embedded by Visa VTS. This produces a single-use
assuranceDatablob bound to the spending limit + duration + merchant context.
delegation_id to DelegationConfig and call get_x402_access_token as usual:
delegation_id reuse is the only supported pattern for Visa — create_delegation(provider="visa", ...) is rejected by the backend without the browser-only consumer_prompt + assurance_data blobs the SDK has no way to produce. When a Visa creation call fails this way, PaymentsError.code carries the backend BCK.VISA.0014 so consumers can branch programmatically.
Generate Payment Permissions
From Nevermined App
The easiest way to generate permissions is through the Nevermined App Permissions page:- Navigate to the permissions page
- Select your plan and agent
- Configure limits (optional)
- Generate the access token
From SDK
Deprecated: passingspending_limit_cents/duration_secsdirectly toget_x402_access_token(inline create-on-the-fly, aDelegationConfigwith nodelegation_id) emits aDeprecationWarningand will be removed in a future release. Create the delegation first as shown above, then pass onlydelegation_id.
Card-Delegation Token Generation
For fiat plans usingnvm:card-delegation, create the card delegation once
(currency is required), then request the token by delegation_id:
Auto Scheme Resolution
Useresolve_scheme() to auto-detect the correct scheme from plan metadata:
DelegationAPI
Create delegations and list enrolled payment methods:list_payment_methods() accepts an optional provider keyword argument
('stripe' | 'braintree' | 'visa' | 'erc4337'). When set, it is forwarded as a
?provider= query string and only methods backed by that provider are returned.
Omit it (the default) to return methods from every provider.
PaymentMethodSummary fields:
Token Structure
The x402 token is a base64-encoded JSON document:Access Token Versions (v2 and v3)
A v2 token — what the backend mints by default today — is a bearer credential. Its EIP-712 signature covers only[from, sessionKeysProvider, sessionKeys, planId]: agentId, resource.url
and httpVerb sit outside the signature and there is no nonce. Consequences:
any seller holding a token minted for plan P can present it to another seller
on the same plan, and the same token can be settled more than once.
A v3 token additionally signs agentId, resourceUrl, httpVerb and a
one-time nonce. That binds it to one seller and one endpoint, and makes it
single-use: the first POST /x402/settle consumes it. verify() never
consumes, so the standard verify-then-settle flow is unchanged and verify stays
repeatable.
v3 is opt-in. Request it with token_version=3, and give the token the
resource and http_verb it should be bound to:
resource accepts a URL string or an X402Resource (which also carries
description / mime_type).
Which URL do I bind?
The one the seller advertises in its 402resource.url. The backend
compares the two by origin + path and falls back to exact string equality
when either side does not parse as an absolute URL — so a relative /ask on
one side and https://seller.example/ask on the other can never match, and the
settle fails. Sellers built on this SDK’s middleware advertise whatever
endpoint they pass to build_payment_required, which is commonly the
request’s relative path. Check what your seller sends before binding.
Never infer the version from what you asked for. The backend’sValidationPiperuns withwhitelist: trueand withoutforbidNonWhitelisted, sotokenVersion: 3sent to a deployment that predates v3 support is dropped without an error and you get a v2 token back. Read the version off the token you received — that is exactly what thetokenVersionkey of the response reports:
BCK.X402.0005), so
relay the token byte-for-byte — never re-encode, trim or normalise it.
Single-use means: mint per paid request
Do not cache a v3 token across paid requests. A second settle of the same token fails withBCK.X402.0059, surfaced by the SDK as its own error type:
AccessTokenAlreadyUsedError subclasses PaymentsError, so existing
except PaymentsError handlers keep working; is_access_token_already_used(err)
checks the wire code (BCK.X402.0059) rather than the class, which also works
across a process boundary.
The A2A client follows the same rule automatically: PaymentsClient caches a v2
token for its lifetime but mints a v3 token per paid request. Pass
token_version=3 to payments.a2a["get_client"] to opt in.
MPP carries no token version at all. The two protocols stopped sharing a
version ladder (nvm-monorepo#3266) because their single-use unit differs: for
x402 it is the token (the v3 nonce), for MPP it is the challenge, whose id
doubles as the burn idempotency key. One MPP access token is presented across
many challenges by design, so a per-token nonce would kill every buyer’s second
challenge.
payments.mpp.get_mpp_access_token therefore takes an MppTokenOptions — the
same fields minus token_version — and refuses any version before the request;
the backend answers BCK.MPP.0007 for any value, 2 included, since that
ordinal belongs to x402’s ladder. Its response carries no tokenVersion key
either: there is no version to report. payments.mpp.fetch is unaffected — it
never asked for one.
Verify Payment Permissions
Verification checks if a subscriber has valid permissions without burning credits:Verification Response
Settle Payment Permissions
Settlement burns credits after successfully processing a request:Settlement Response
Payment Required Object
TheX402PaymentRequired object specifies what payment is required. The scheme and network fields vary by payment type:
Using the Helpers
build_payment_required_for_plans delegates to build_payment_required internally. When scheme is omitted, the network defaults to eip155:84532 (Base Sepolia). When scheme="nvm:card-delegation", the network is automatically set to stripe.
Complete Workflow Example
HTTP Flow
Best Practices
- Always verify before processing: Don’t do expensive work without verification
- Only settle on success: Don’t burn credits if processing fails
- Use agent_request_id: Include request IDs for tracking and debugging
- Handle 402 responses: Return proper payment required responses with scheme info
- Cache verifications carefully: a v2 token can be used multiple times until limits are reached; a v3 token is single-use and must be re-minted per paid request (see Access Token Versions)
Error Codes
Next Steps
Request Validation
More validation patterns
MCP Integration
x402 with MCP servers
OAuth 401 vs. payment-required
In-band x402 v2 MCP signaling