> ## 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.

# Delegations

> Create scoped spending authorizations that control how much agents can charge, how many transactions they can make, and when the authorization expires.

## What Are Delegations?

A delegation is a **scoped spending authorization** tied to an enrolled payment card. It defines the boundaries of what an agent can charge: the maximum amount over the delegation's lifetime, how many transactions are allowed, and when the authorization expires.

Think of it as a controlled allowance: you're giving an agent permission to spend within strict limits, rather than handing over your card.

<Note>
  The Visa Agentic Tokens rollout retired the previous separate "Visa mandate" object. Visa is now one of three networks (`stripe`, `braintree`, `visa`) on the unified `nvm:card-delegation` scheme, with a single create endpoint and a single record shape. Visa delegations differ only in that they require a per-delegation device-binding ceremony at create time.
</Note>

## Delegation Properties

All three networks share the same core fields:

| Field                     | Description                                                                                                                                                 |
| ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `provider`                | `stripe`, `braintree`, `visa`, or `erc4337`                                                                                                                 |
| `providerPaymentMethodId` | PSP-side token: Stripe `pm_…`, Braintree `paymentMethodToken`, or Visa Agentic Token `vat_…`                                                                |
| `spendingLimitCents`      | Maximum total amount the delegation can charge over its lifetime, in cents                                                                                  |
| `durationSecs`            | How long the delegation is valid for, in seconds from creation                                                                                              |
| `maxTransactions`         | Optional cap on the number of charges. Omit the field to allow unlimited transactions.                                                                      |
| `currency`                | ISO 4217 lowercase (`usd`, `eur`, …)                                                                                                                        |
| `planId`                  | Optional plan binding. Required for Visa (Trusted Agent Protocol).                                                                                          |
| `merchantAccountId`       | PSP-side merchant routing. Stripe Connected Account ID, Braintree per-currency `merchantAccountId`, or seller's Stripe Connect account for Visa settlement. |
| `apiKeyId`                | Optional NVM API key link for [automatic selection](/docs/products/payments/mandate-selection)                                                              |
| `consumerPrompt`          | **Visa-only**: human-readable approval text shown during device binding                                                                                     |
| `assuranceData`           | **Visa-only**: opaque blob produced by the WebAuthn ceremony                                                                                                |

## Creating a Delegation

### Via the Nevermined App

After enrolling a card, create a delegation from the [Nevermined App](https://nevermined.app):

<Tabs>
  <Tab title="Stripe / Braintree">
    1. Navigate to your enrolled card
    2. Click **Create Delegation**
    3. Set the spending limit (in dollars / euros)
    4. Set the duration (e.g. 7 days)
    5. Optionally set a max-transactions cap
    6. Optionally link an NVM API key
    7. Confirm to create
  </Tab>

  <Tab title="Visa">
    1. Navigate to your enrolled Visa Agentic Token
    2. Click **Create Delegation**
    3. Set the spending limit, duration, and (optionally) max transactions
    4. Select the plan this delegation binds to (Visa requires a `planId`)
    5. Optionally link an NVM API key
    6. Click **Continue to approval** — the embedded Visa VTS iframe starts the WebAuthn ceremony
    7. Complete the passkey approval (or fall back to the email OTP that VTS sends)
    8. The webapp captures the resulting `assuranceData` and submits the delegation

    <Warning>
      Visa device binding is single-use and tied to the spending limit + duration + merchant context shown in the approval prompt. Changing any of those values invalidates the captured `assuranceData` — restart the approval step.
    </Warning>

    <Note>
      Visa delegation creation is webapp-only. The backend rejects `POST /api/v1/delegation/create` with `provider: 'visa'` (`BCK.VISA.0014`) unless both `consumerPrompt` and `assuranceData` are present, and both can only be produced by the VTS-embedded ceremony running in a real browser.
    </Note>
  </Tab>
</Tabs>

### Via the API

All providers use the same endpoint and DTO. The Visa branch adds two required fields (`consumerPrompt`, `assuranceData`) and requires a `planId`.

<Tabs>
  <Tab title="Stripe Delegation">
    ```bash theme={null}
    POST /api/v1/delegation/create
    Authorization: Bearer <NVM_API_KEY>
    Content-Type: application/json
    ```

    ```json theme={null}
    {
      "provider": "stripe",
      "providerPaymentMethodId": "pm_1Abc2Def3Ghi4Jkl",
      "spendingLimitCents": 10000,
      "durationSecs": 604800,
      "maxTransactions": 100,
      "currency": "usd",
      "apiKeyId": "sk-abc123"
    }
    ```

    Response includes a `delegationId` and `delegationToken` (the signed JWT) for the new authorization.
  </Tab>

  <Tab title="Braintree Delegation">
    ```bash theme={null}
    POST /api/v1/delegation/create
    Authorization: Bearer <NVM_API_KEY>
    Content-Type: application/json
    ```

    ```json theme={null}
    {
      "provider": "braintree",
      "providerPaymentMethodId": "abc123token",
      "spendingLimitCents": 10000,
      "durationSecs": 604800,
      "maxTransactions": 100,
      "currency": "usd",
      "merchantAccountId": "seller-usd-merchant-account-id",
      "apiKeyId": "sk-abc123"
    }
    ```
  </Tab>

  <Tab title="Visa Delegation">
    ```bash theme={null}
    POST /api/v1/delegation/create
    Authorization: Bearer <NVM_API_KEY>
    Content-Type: application/json
    ```

    ```json theme={null}
    {
      "provider": "visa",
      "providerPaymentMethodId": "vat_01HXYZABCDEF",
      "spendingLimitCents": 5000,
      "durationSecs": 86400,
      "maxTransactions": 5,
      "currency": "usd",
      "planId": "80918427023170428029540261117198154464497879145267720259488529685089104529015",
      "consumerPrompt": "Allow up to USD 50.00 over 5 transactions at example.com",
      "assuranceData": [
        {
          "methodResults": { "id": "…" },
          "verificationType": "DEVICE"
        }
      ]
    }
    ```

    The `assuranceData` blob is the value returned by the VGS Agentic Auth browser SDK after the WebAuthn ceremony completes. It is opaque to Nevermined and forwarded verbatim to VGS `POST /intents`.

    <Warning>
      Calling this endpoint with `provider: 'visa'` from a non-browser context will fail with `BCK.VISA.0014` because `assuranceData` can only be produced by the in-browser ceremony. Trying to forge or replay one yields `BCK.VISA.0003` from upstream.
    </Warning>
  </Tab>
</Tabs>

## Spending Controls

All delegations enforce multiple layers of spending control:

### Lifetime Spending Limit

`spendingLimitCents` caps the **cumulative** amount charged over the delegation's lifetime, not per-transaction. Once `amountSpentCents >= spendingLimitCents`, the delegation transitions to `Exhausted`.

### Usage Limits

`maxTransactions` caps the total number of charges. Once reached, the delegation is `Exhausted` regardless of remaining budget.

### Time-Based Expiration

After `createdAt + durationSecs`, the delegation transitions to `Expired` regardless of remaining budget or usage.

### Card Spending Ceiling

Each card has a cumulative spending ceiling (default \$10.00). The sum of `spendingLimitCents` across all active delegations on a card can't exceed this ceiling.

**Example:**

| Card Ceiling | Delegation A | Delegation B | Remaining |
| ------------ | ------------ | ------------ | --------- |
| \$10.00      | \$5.00       | \$3.00       | \$2.00    |

If you try to create a third delegation for $3.00, it will be rejected because only $2.00 of ceiling remains.

## Updating a Delegation

Delegations are not updated in place. To change the limit, duration, or any other parameter, revoke the existing one and create a new one. For Visa, this requires a fresh device-binding ceremony.

```bash theme={null}
# 1. Revoke existing delegation
DELETE /api/v1/delegation/{delegationId}

# 2. Create new delegation with updated params
POST /api/v1/delegation/create
```

<Warning>
  Revoking and recreating a delegation means any unspent budget from the old delegation does not carry over.
</Warning>

## Cancelling a Delegation

```bash theme={null}
DELETE /api/v1/delegation/{delegationId}
Authorization: Bearer <NVM_API_KEY>
```

No additional authentication is required beyond your API credentials. Revocation is immediate: in-flight verify/settle calls against the delegation fail with `DELEGATION_INACTIVE`.

## Status Lifecycle

```
Active -> Exhausted (spending limit or transaction count reached)
  |
  |-> Expired (past createdAt + durationSecs)
  |
  |-> Revoked (manually removed via DELETE)
```

Only `Active` delegations can be used for payments. Nevermined checks status, usage, and expiration on every verify and settle request. Each delegation tracks `amountSpentCents`, `remainingBudgetCents`, and `transactionCount`.

## API Key Linking

You can optionally link a delegation to a specific NVM API key. This tells Nevermined "when this API key is used, charge this delegation."

This is especially useful when you have multiple active delegations and want deterministic routing. Instead of the agent guessing which one to use, the API key determines it automatically. All three networks support API key linking through the same `apiKeyId` field.

See [Delegation Selection](/docs/products/payments/mandate-selection) for the full resolution algorithm.

## Transaction History

Every settled charge is recorded as a transaction:

| Field                   | Description                                                                                                |
| ----------------------- | ---------------------------------------------------------------------------------------------------------- |
| `amount`                | Transaction amount                                                                                         |
| `currency`              | Currency code                                                                                              |
| `status`                | `completed` or `failed`                                                                                    |
| `providerTransactionId` | PSP charge identifier (Stripe `pi_…`, Braintree transaction id, Stripe Connect `pi_…` for Visa settlement) |
| `failureReason`         | Error details (if failed)                                                                                  |
| `createdAt`             | When the transaction occurred                                                                              |

```bash theme={null}
GET /api/v1/delegation/{delegationId}/transactions?offset=0
```

## Network Comparison

|                         | Visa                                                  | Stripe                                                  | Braintree                                                  |
| ----------------------- | ----------------------------------------------------- | ------------------------------------------------------- | ---------------------------------------------------------- |
| **Create endpoint**     | `POST /api/v1/delegation/create` (`provider: 'visa'`) | `POST /api/v1/delegation/create` (`provider: 'stripe'`) | `POST /api/v1/delegation/create` (`provider: 'braintree'`) |
| **Per-delegation auth** | WebAuthn/passkey device binding (browser-only)        | API credentials only                                    | API credentials only                                       |
| **Required extras**     | `consumerPrompt`, `assuranceData`, `planId`           | —                                                       | `merchantAccountId` matching `currency`                    |
| **Cancel**              | `DELETE /api/v1/delegation/{id}`                      | `DELETE /api/v1/delegation/{id}`                        | `DELETE /api/v1/delegation/{id}`                           |
| **Settlement**          | Stripe Connect against seller's connected account     | Stripe PaymentIntents                                   | Braintree `transaction.sale` against vaulted token         |

## What's Next?

If you have multiple delegations, learn how Nevermined decides which one to use for a given payment request.

<Card title="Delegation Selection" icon="route" href="/docs/products/payments/mandate-selection">
  How Nevermined resolves which delegation to charge
</Card>
