Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.nevermined.app/llms.txt

Use this file to discover all available pages before exploring further.

The Problem

When a subscriber has multiple active delegations across their enrolled cards, the agent needs to know which one to use. Should it charge the 5VisadelegationonCardAorthe5 Visa delegation on Card A or the 10 Stripe delegation on Card B? NVM Pay solves this with a three-tier selection algorithm that automatically resolves the right delegation based on priority rules. The algorithm is the same for Visa, Stripe, and Braintree — apiKeyId and explicit delegationId work identically across all three networks.

Three-Tier Resolution

When the SDK or CLI requests an x402 access token, NVM Pay resolves the delegation in this order:
1

Mode 1: Explicit Delegation ID

If the caller passes a delegationId in delegationConfig, NVM Pay uses that delegation directly. No ambiguity, the caller knows exactly which authorization it wants.
const token = await payments.x402.getX402AccessToken(
  'plan_abc123',
  undefined, // agentId — pass when the plan has multiple agents
  {
    delegationConfig: {
      delegationId: 'deleg-8f14e45f-ce34-4797-b88e-968374b0d4b6',
    },
  },
)
NVM Pay validates:
  • The delegation exists and is Active (not expired, exhausted, or revoked)
  • The delegation has remaining budget and remaining transactions
  • If the delegation is linked to an API key, it must match the calling key
  • The associated card is active and belongs to the authenticated user
This is the only supported mode for Visa delegations. Auto-creation from the SDK requires consumerPrompt + assuranceData, which the SDK cannot produce — see the Visa enrollment notes.
2

Mode 2: Key-Linked Delegation

If no delegationId is passed, NVM Pay checks if any delegation is linked to the calling API key. If exactly one key-linked delegation matches, it’s selected automatically.This is the recommended approach for production setups with multiple delegations. Link each API key to a specific delegation and the routing is deterministic.NVM Pay collects all delegations where delegation.apiKeyId === calling_key.skId, then filters for Active, with remaining budget, remaining transactions, and a non-expired duration. Key-linked delegations always take priority over unlinked ones.
3

Mode 3: Unlinked Fallback

If no key-linked delegations exist, NVM Pay falls back to unlinked delegations (delegations with no apiKeyId set). If exactly one unlinked delegation matches, it’s selected.This mode is convenient when you only have one delegation. You don’t need to link anything.

Decision Flowchart

SDK / CLI requests an x402 access token
  |
  |- delegationId in delegationConfig?
  |   |- YES -> Use that delegation (validate ownership, status, budget, usage, expiry)
  |   |- NO  -> Continue to auto-resolution (Stripe / Braintree only)
  |
  |- Collect all user's delegations across all cards
  |   |- Key-linked: delegation.apiKeyId === current key's skId
  |   |- Unlinked: delegation.apiKeyId is null
  |
  |- Filter each group: Active, not expired, remaining budget > 0, remaining transactions > 0
  |
  |- Key-linked delegations found?
  |   |- Exactly 1 -> Use it
  |   |- Multiple  -> Error: "Multiple active delegations found"
  |   |- None      -> Fall through to unlinked
  |
  |- Unlinked delegations found?
      |- Exactly 1 -> Use it
      |- Multiple  -> Error: "Multiple active delegations found"
      |- None      -> Error: "No active delegation found"

When to Use Each Mode

Explicit ID

Multiple delegations, full control. Required for Visa.

Key-Linked

One delegation per API key. Set it once, forget it.

Unlinked

Single delegation, zero config. Just create and go.

Linking an API Key

API key linking works the same way for Visa, Stripe, and Braintree delegations through the shared apiKeyId field on POST /api/v1/delegation/create.

When Creating

In the Nevermined Pay dashboard, open the Create Delegation dialog and select an API key from the dropdown. Only active, non-browser API keys that aren’t already linked to another delegation are shown.

When Updating

Delegations cannot be updated in place. To change the linked API key, revoke the existing delegation and create a new one with the desired apiKeyId. For Visa, this requires a fresh device-binding ceremony.
Linking an API key is optional but recommended when you have two or more active delegations. Without it, NVM Pay can’t automatically determine which one to use and will return an error.

Error Handling

Multiple Delegations Found

"Multiple active delegations found.
 Pass a delegationId in delegationConfig, or link a delegation to your API key."
Fix: Either pass delegationId explicitly in delegationConfig, or link one of the delegations to your API key in the dashboard.

No Active Delegation Found

"No active delegation found (check remaining budget, expiry, status, and key restrictions)"
Possible causes:
  • All delegations are exhausted (amountSpentCents >= spendingLimitCents or transactionCount >= maxTransactions)
  • All delegations have expired (createdAt + durationSecs in the past)
  • Delegations are linked to a different API key

Delegation Linked to Different Key

"This delegation is linked to a different API key"
HTTP 403. The explicit delegationId you passed is linked to a different API key than the one you’re authenticating with. Use the correct API key, or revoke the delegation and recreate it with the API key you want.

API Reference

Generate Access Token

POST /api/v1/x402/access-token
Authorization: Bearer <NVM_API_KEY>
Content-Type: application/json
Request:
{
  "planId": "plan_abc123",
  "agentId": "80918427023170428029540261117198154464497879145267720259488529685089104529015",
  "delegationConfig": {
    "delegationId": "deleg-8f14e45f-ce34-4797-b88e-968374b0d4b6"
  }
}
FieldRequiredDescription
planIdYesThe plan you’re paying for
agentIdNoAgent identifier (for plans with multiple agents)
delegationConfig.delegationIdNoExplicit delegation ID (Mode 1). Omit to use auto-resolution. Required for Visa.
delegationConfig.spendingLimitCents + durationSecsNoAuto-create a delegation on the fly (Stripe / Braintree only)
Response (success):
{
  "accessToken": "eyJ4NDAyVmVyc2lvbiI6Mi...",
  "permissionHash": "0x1a2b3c..."
}
The accessToken value (a base64-encoded x402 PaymentPayload) goes in the payment-signature HTTP header when calling a protected resource. Error responses:
StatusReason
400Multiple delegations, delegation exhausted, missing required fields for Visa
403Delegation linked to a different API key, delegation doesn’t belong to user
404No active delegation found, delegation ID not found

Best Practices

  1. Start simple. If you have one delegation, you don’t need to link API keys or pass explicit IDs. Just create the delegation and call the API.
  2. Link keys for production. When you add a second delegation, link each API key to a specific delegation. This gives you deterministic routing without code changes.
  3. Use explicit IDs for Visa or for complex setups. Visa delegations require delegationId in delegationConfig. The same pattern is useful when an agent works with multiple delegations dynamically (e.g., different delegations for different pricing tiers).
  4. Monitor usage. Check amountSpentCents vs spendingLimitCents and transactionCount vs maxTransactions to know when delegations are close to exhaustion. Create new ones before the old ones run out.
  5. Set reasonable expiration times. Don’t create delegations that last indefinitely. Set durationSecs aligned with your billing cycles. For Visa, the assuranceData ceremony scales with the duration shown in the approval prompt — keep it short for higher-trust use cases.