Skip to main content

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
Web3 Data API/pay-per-use/v1/{CHAIN}/{NETWORK}/{CATEGORY}/{METHOD}
Node API (JSON-RPC)/pay-per-use/{CHAIN}/{NETWORK}/json-rpc

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

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

Base64-decode the PAYMENT-REQUIRED header and select the accept object for the network you want to use for payment.

Decode PAYMENT-REQUIRED Header
const paymentRequired = JSON.parse(
Buffer.from(res402.headers['payment-required'], 'base64').toString()
);

The following is an example of a decoded accepts array.

PAYMENT-REQUIRED Decoded Example
{
"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.

EVM PAYMENT-SIGNATURE
{
"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}"
}
}
}
Reference

Refer to the EIP-3009 specification for details on generating signatures.

PAYMENT-SIGNATURE Expiry

A PAYMENT-SIGNATURE is valid for 300 seconds. Submit the retry request within this window after generating the signature.


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.

Retry with PAYMENT-SIGNATURE
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.

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

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

Per-method pricing is available in Supported APIs & Pricing.


info

For Credit-based implementation, which is suited for high-frequency calls and predictable workloads, see How to use Credit.