How to use Pay-Per-Use

Pay-Per-Use makes an on-chain payment directly for each API request, with no pre-funding or JWT authentication required. Any wallet is enough to get started, making it well-suited for low-frequency calls and prototyping.

Implementation follows three steps.

  1. Call API — receive 402 — Call the API without authentication; Nodit returns the payment conditions.
  2. Generate PAYMENT-SIGNATURE — Sign with your wallet according to the payment conditions and construct the payload.
  3. Retry — Resend the same API request with the PAYMENT-SIGNATURE header attached.

Step 1. Call API — 402 Payment Required

Send a request to the API endpoint without authentication. The server returns 402 Payment Required. The Payment-Required response header contains the payment conditions encoded in base64.

API TypeURL Pattern
Data API/pay-per-use/v1/{CHAIN}/{NETWORK}/{CATEGORY}/{METHOD}
RPC API (JSON-RPC)/pay-per-use/{CHAIN}/{NETWORK}/json-rpc

The example below shows the initial request, which returns 402 Payment Required.

curl --request POST \
     --url https://x402.nodit.io/pay-per-use/v1/ethereum/mainnet/blockchain/getBlockByHashOrNumber \
     --header 'Content-Type: application/json' \
     --data '{"block": "latest"}'
HTTP/1.1 402 Payment Required
Content-Type: application/json
PAYMENT-REQUIRED: eyJ4NDAyV...

The PAYMENT-REQUIRED header is base64-encoded JSON. Decode the value, parse the accepts array, and select the accept object for the network you want to use for payment.

The following is an example of a decoded accepts array.

{
  "x402Version": 2,
  "accepts": [
    {
      "scheme": "exact",
      "network": "eip155:8453",
      "amount": "1000",
      "asset": "0x...",
      "payTo": "0x...",
      "maxTimeoutSeconds": 60,
      "extra": {
        "name": "USDC",
        "version": "2",
        "mode": "ppu",
        "acceptId": "..."
      },
      "resource": "/pay-per-use/ethereum/mainnet/json-rpc"
    },
    {
      "scheme": "exact",
      "network": "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",
      "amount": "1000",
      "asset": "...",
      "payTo": "...",
      "maxTimeoutSeconds": 60,
      "extra": {
        "name": "USDC",
        "version": "1",
        "mode": "ppu",
        "acceptId": "...",
        "feePayer": "..."
      },
      "resource": "/pay-per-use/ethereum/mainnet/json-rpc"
    }
  ]
}

Step 2. Generate PAYMENT-SIGNATURE

Select the network from the accepts array and generate a signature. After signing, construct the payload using the JSON structure below and base64-encode it.

Sign using EIP-3009 TransferWithAuthorization.

{
  "x402Version": 2,
  "resource": { "url": "{API_URL}", "description": "Nodit API", "mimeType": "application/json" },
  "accepted": {
    "network": "{NETWORK}",
    "asset": "{ASSET_ADDRESS}",
    "payTo": "{PAYTO_ADDRESS}",
    "amount": "{AMOUNT}",
    "scheme": "exact",
    "extra": { "name": "USDC", "version": "{VERSION}" }
  },
  "payload": {
    "signature": "{EIP_712_SIGNATURE}",
    "authorization": {
      "from": "{WALLET_ADDRESS}",
      "to": "{PAYTO_ADDRESS}",
      "value": "{AMOUNT}",
      "validAfter": "0",
      "validBefore": "{VALID_BEFORE}",
      "nonce": "{NONCE}"
    }
  }
}

Step 3. Retry with PAYMENT-SIGNATURE

Resend the request to the same API URL with the PAYMENT-SIGNATURE header attached. Unlike Credit-based payment, no Authorization header is required.

curl --request POST \
     --url https://x402.nodit.io/pay-per-use/v1/ethereum/mainnet/blockchain/getBlockByHashOrNumber \
     --header 'Content-Type: application/json' \
     --header 'PAYMENT-SIGNATURE: {BASE64_ENCODED_PAYMENT_PAYLOAD}' \
     --data '{"block": "latest"}'

When payment is confirmed, the response includes a PAYMENT-RESPONSE header and the API result in the response body.

HTTP/1.1 200 OK
Content-Type: application/json
PAYMENT-RESPONSE: eyJ0eFhIYXNoIjoi...

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": "0x..."
}