Code Examples

Ready-to-use code for making paid API calls with x402.

Python (Base/EVM)

Python - Pay Per Requestpython
import base64, json, os, requests
from web3 import Web3

def call_x402_endpoint(url: str) -> dict:
    """Call an x402-enabled endpoint with automatic payment."""
    
    private_key = os.getenv('PRIVATE_KEY')
    if not private_key:
        raise ValueError('PRIVATE_KEY not set')
    
    # Make initial request
    response = requests.get(url)
    if response.status_code != 402:
        return response.json()
    
    # Parse payment requirements
    accept = response.json()['accepts'][0]
    
    # Set up Web3
    w3 = Web3(Web3.HTTPProvider('https://mainnet.base.org'))
    account = w3.eth.account.from_key(private_key)
    
    # Build and sign transaction
    tx = {
        'to': accept['payTo'],
        'value': int(accept['maxAmountRequired']),
        'chainId': accept.get('chainId', 8453),
        'nonce': w3.eth.get_transaction_count(account.address),
        'gasPrice': w3.eth.gas_price,
        'gas': 21000
    }
    signed_tx = account.sign_transaction(tx)
    
    # Create payment payload
    payload = {
        'x402Version': 1,
        'scheme': 'exact',
        'network': 'base',
        'payload': {
            'serializedTransaction': base64.b64encode(
                signed_tx.rawTransaction
            ).decode()
        }
    }
    
    # Make paid request
    payment_header = base64.b64encode(json.dumps(payload).encode()).decode()
    return requests.get(url, headers={'X-Payment': payment_header}).json()

# Usage
result = call_x402_endpoint('https://api.x402layer.cc/api/public/endpoints/my-endpoint')
print(result)

TypeScript (Viem)

TypeScript - Pay Per Requesttypescript
import { createWalletClient, http, publicActions } from 'viem';
import { base } from 'viem/chains';
import { privateKeyToAccount } from 'viem/accounts';

async function callX402Endpoint<T>(url: string): Promise<T> {
  const privateKey = process.env.PRIVATE_KEY as `0x${string}`;
  if (!privateKey) throw new Error('PRIVATE_KEY not set');

  // Make initial request
  const response = await fetch(url);
  if (response.status !== 402) return response.json();

  // Parse payment requirements
  const { accepts } = await response.json();
  const accept = accepts[0];

  // Set up wallet
  const account = privateKeyToAccount(privateKey);
  const client = createWalletClient({
    account,
    chain: base,
    transport: http(),
  }).extend(publicActions);

  // Sign transaction
  const signedTx = await client.signTransaction({
    to: accept.payTo,
    value: BigInt(accept.maxAmountRequired),
  });

  // Create payment payload
  const payload = {
    x402Version: 1,
    scheme: 'exact',
    network: 'base',
    payload: { serializedTransaction: btoa(signedTx) },
  };

  // Make paid request
  const paidResponse = await fetch(url, {
    headers: { 'X-Payment': btoa(JSON.stringify(payload)) },
  });
  return paidResponse.json();
}

// Usage
const result = await callX402Endpoint('https://api.x402layer.cc/api/public/endpoints/my-endpoint');
console.log(result);

Credit-Based (Simpler)

When using credits, no per-call transaction is needed:

TypeScript - Credit-Basedtypescript
async function callWithCredits<T>(url: string, walletAddress: string): Promise<T> {
  const response = await fetch(url, {
    headers: { 'x-wallet-address': walletAddress },
  });

  if (response.status === 402) {
    throw new Error('Insufficient credits. Please purchase more.');
  }

  return response.json();
}

// Usage
const data = await callWithCredits(
  'https://api.x402layer.cc/api/public/endpoints/my-endpoint',
  '0x742d35Cc6634C0532925a3b844Bc9e7595f2bD87'
);