> For the complete documentation index, see [llms.txt](/llms.txt).

# Pay for an x402 API with delegation

In this guide, you use a buyer account to access API data from an x402 server by creating an [open delegation](/smart-accounts-kit/development/reference/glossary#open-root-delegation) that authorizes token transfers on your behalf.

You set up an `x402Erc7710Client` with a delegation provider, register it with the x402 client, and use `wrapFetchWithPayment` to automatically handle payment when calling a protected API route.

## Prerequisites[​](#prerequisites "Direct link to Prerequisites")

- [Install and set up the Smart Accounts Kit.](/smart-accounts-kit/development/get-started/install/)

## Steps[​](#steps "Direct link to Steps")

### 1. Install the dependencies[​](#1-install-the-dependencies "Direct link to 1. Install the dependencies")

- npm
- Yarn
- pnpm
- Bun

```
npm install @x402/core @x402/fetch @metamask/x402

```

```
yarn add @x402/core @x402/fetch @metamask/x402

```

```
pnpm add @x402/core @x402/fetch @metamask/x402

```

```
bun add @x402/core @x402/fetch @metamask/x402

```

### 2. Create a buyer account[​](#2-create-a-buyer-account "Direct link to 2. Create a buyer account")

Create an account to represent the buyer, the [delegator](/smart-accounts-kit/development/reference/glossary#delegator-account)**Delegator account** The account that creates and signs a delegation to grant limited authority to another account. who creates a delegation.

The delegator must be a [MetaMask smart account](/smart-accounts-kit/development/reference/glossary#metamask-smart-account)**MetaMask smart account** A smart contract account created using the Smart Accounts Kit that supports programmable behavior, flexible signing options, and ERC-7710 delegations.. Use the toolkit's [toMetaMaskSmartAccount](/smart-accounts-kit/development/reference/smart-account/#tometamasksmartaccount) method to create the buyer account.

Important

Fund the smart account with USDC for the requested payment.

- example.ts
- config.ts

```
import { Implementation, toMetaMaskSmartAccount } from '@metamask/smart-accounts-kit'
import { publicClient, buyerAccount } from './config'

export const buyerSmartAccount = await toMetaMaskSmartAccount({
  client: publicClient,
  implementation: Implementation.Hybrid,
  deployParams: [buyerAccount.address, [], [], []],
  deploySalt: '0x',
  signer: { account: buyerAccount },
})

```

```
import { createPublicClient, http } from 'viem'
import { privateKeyToAccount } from 'viem/accounts'
import { base as chain } from 'viem/chains'

export const publicClient = createPublicClient({
  chain,
  transport: http(),
})

export const buyerAccount = privateKeyToAccount('0x<BUYER_PRIVATE_KEY>')

```

### 3. Create an x402 ERC-7710 client[​](#3-create-an-x402-erc-7710-client "Direct link to 3. Create an x402 ERC-7710 client")

Create an `x402Erc7710Client` with a `delegationProvider` callback. The x402 client calls this function automatically when it needs to pay for a request, passing in the payment requirements from the server.

Inside the provider, create an [open delegation](/smart-accounts-kit/development/concepts/delegation/overview/#open-root-delegation)using [createOpenDelegation](/smart-accounts-kit/development/reference/delegation/#createopendelegation). This example uses the [erc20TransferAmount](/smart-accounts-kit/development/guides/delegation/use-delegation-scopes/spending-limit/#erc-20-transfer-scope)scope to allow USDC transfers up to the requested amount, and the [timestamp](/smart-accounts-kit/development/reference/delegation/caveats/#timestamp) caveat to set a short expiry.

For ERC-7710, x402 requires the payload fields `delegationManager`, `permissionContext`, and `delegator`. Use [encodeDelegations](/smart-accounts-kit/development/reference/delegation/#encodedelegations) to encode the delegation chain.

```
import { CaveatType, createOpenDelegation, ScopeType } from '@metamask/smart-accounts-kit'
import { encodeDelegations } from '@metamask/smart-accounts-kit/utils'
import { x402Erc7710Client } from '@metamask/x402'
import { getAddress } from 'viem'

const erc7710Client = new x402Erc7710Client({
  delegationProvider: async requirements => {
    // Expires in 1 minute.
    const expiry = Math.floor(Date.now() / 1000) + 60

    const delegation = createOpenDelegation({
      environment: buyerSmartAccount.environment,
      from: buyerSmartAccount.address,
      scope: {
        type: ScopeType.Erc20TransferAmount,
        tokenAddress: getAddress(requirements.asset),
        maxAmount: BigInt(requirements.amount),
      },
      caveats: [
        {
          type: CaveatType.Timestamp,
          afterThreshold: 0,
          beforeThreshold: expiry,
        },
      ],
    })

    const signature = await buyerSmartAccount.signDelegation({
      delegation,
    })

    const signedDelegation = {
      ...delegation,
      signature,
    }

    return {
      delegationManager: buyerSmartAccount.environment.DelegationManager,
      permissionContext: encodeDelegations([signedDelegation]),
      delegator: buyerSmartAccount.address,
    }
  },
})

```

### 4. Register the client[​](#4-register-the-client "Direct link to 4. Register the client")

Register the ERC-7710 client with the x402 core client for all EVM networks. Create an HTTP client and a payment-aware `fetch` function using `wrapFetchWithPayment`.

```
import { x402Client, x402HTTPClient } from '@x402/core/client'
import { wrapFetchWithPayment } from '@x402/fetch'

const coreClient = new x402Client().register('eip155:*', erc7710Client)
const httpClient = new x402HTTPClient(coreClient)

const fetchWithPayment = wrapFetchWithPayment(fetch, httpClient)

```

### 5. Make the paid request[​](#5-make-the-paid-request "Direct link to 5. Make the paid request")

Call the protected endpoint using `fetchWithPayment`. It handles the x402 payment flow, calling your `delegationProvider`to create an open redelegation when the server returns a `402` response.

```
const paidResponse = await fetchWithPayment('https://api.example.com/paid-endpoint', {
  method: 'GET',
})

```
