Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Skip to content

pay

Pay for an x402-protected resource on Base. The command operates in two mutually exclusive modes — provide exactly one of --url or --accepts. Requires a wallet. Pays from your smart wallet when one is configured, otherwise your EOA.

zora pay --url <url> [options]
zora pay --accepts <json> [options]

Modes

ModeTriggerWhat it does
Fetch (pay-and-go)--urlFetches the URL, automatically pays any 402 Payment Required challenge, and returns the resource.
Build (sign-only)--acceptsSigns a payment for a 402 challenge and prints the PAYMENT-SIGNATURE header to attach to a retry request.

Options

FlagDescription
--url <url>Fetch a URL, automatically paying any x402 402 challenge and returning the resource (fetch mode)
--accepts <json>x402 accepts array, 402 response body, or base64 PAYMENT-REQUIRED header. Accepts inline JSON, @file, or - for stdin (build mode)
--method <method>HTTP method for --url mode (default: GET)
--data <body>Request body (JSON) for --url mode
--asset <address>Prefer paying with this ERC-20 asset (0x...)
--max-value <atomic>Maximum payment in the asset's atomic units; refuse to pay above it (e.g. 1000000 = 1 USDC)
--eoaPay from the EOA instead of the smart wallet
--output <file>Write the response body to a file (raw bytes; works for binary resources)
--yesSkip confirmation prompt
--jsonMachine-readable JSON output

Examples

Pay and fetch a protected resource

npx @zoralabs/cli pay --url https://api.example.com/premium
 x402 request succeeded
 
 Status       200
 Type         application/json
 Paid         yes (from smart-wallet)
 Tx           0x789abc...
 
 Response:
 
 { "data": "..." }

POST with a request body

npx @zoralabs/cli pay --url https://api.example.com/generate --method POST --data '{"prompt":"hello"}'

Cap the payment amount

npx @zoralabs/cli pay --url https://api.example.com/premium --max-value 1000000

Save a binary resource to a file

npx @zoralabs/cli pay --url https://api.example.com/image --output ./out.png

Sign a payment without fetching (build mode)

npx @zoralabs/cli pay --accepts '<402 accepts JSON>'

The --accepts payload can also be piped in or read from a file:

# From a file
npx @zoralabs/cli pay --accepts @challenge.json
 
# From stdin
curl -s https://api.example.com/premium | npx @zoralabs/cli pay --accepts -
 Signed x402 payment
 
 Amount       1 USDC
 Pay to       0x...
 Paying from  smart-wallet
 
 Attach this header to the retry request:
 
 PAYMENT-SIGNATURE: <signed header>

JSON output

Fetch mode

For a text resource the body is inlined and also written to a durable file (savedTo). Binary resources are referenced by path only:

{
  "action": "pay",
  "mode": "fetch",
  "url": "https://api.example.com/premium",
  "status": 200,
  "contentType": "application/json",
  "paid": true,
  "settlement": {
    "success": true,
    "transaction": "0x789abc...",
    "network": "base",
    "payer": "0x..."
  },
  "encoding": "utf8",
  "body": { "data": "..." },
  "savedTo": "/tmp/...",
  "bytes": 1234
}

When no payment was required, paid is false and settlement is null.

Build mode

{
  "action": "pay",
  "mode": "build",
  "headerName": "PAYMENT-SIGNATURE",
  "header": "<signed header>",
  "requirement": {
    "scheme": "exact",
    "network": "base",
    "asset": "0x...",
    "payTo": "0x...",
    "amount": "1000000",
    "amountFormatted": "1",
    "symbol": "USDC",
    "resource": "https://api.example.com/premium",
    "description": "..."
  },
  "payerWallet": "smart-wallet"
}