x402 payments
Keyless, pay-per-request access over USDC on Base — for autonomous agents with a wallet and no human to hold an API key.
An AI agent with a wallet and no human operator can pay per request instead of holding an API key.
POST to /extract, /bulk, /crawl, or /search with no Authorization header. The API
answers 402 with an x402 v2 challenge in the payment-required response header (base64 JSON).
Pay it in USDC on Base (network eip155:8453), then retry the same request with a PAYMENT
header.
A paid request runs with Enterprise privileges: every output format, no per-second spacing, top queue priority, and no monthly quota — the payment is the meter.
You probably don't need to implement this by hand
Standard x402 client middleware — x402-fetch for JavaScript, the x402 Python packages,
Stripe's purl — handles the 402 → pay → retry loop for you. WellMarked's own SDKs stay
key-based by design and never touch private keys.
Pricing
$0.01 per unit, charged up front.
| Endpoint | Units |
|---|---|
/extract | 1 |
/bulk | len(urls) — one payment covers the whole batch |
/search | 1 + num_results — the query, plus one per result |
/crawl | max_pages |
max_pages (an integer ≥ 1) is required on x402 crawls. The page count is unknown at
submission and payment precedes work, so you buy a page budget up front.
Refunds are automatic
Every paid unit that does not produce a successful extraction is refunded to the paying wallet in USDC — failed fetches, search results that error, crawl pages never visited, and any request rejected before work began. Same rule as metered billing: only successes cost money.
The flow
Probe
POST the request with no auth. You get 402, and the payment-required header decodes to an
x402 v2 challenge: scheme exact, the USDC asset on Base, an atomic amount, the payTo
deposit address, and extra.payment_intent identifying this payment.
curl -i -X POST https://api.wellmarked.io/extract \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com"}'Pay, then retry the same request
Send the PAYMENT header — base64 of a JSON object echoing the accepted block:
{ "accepted": { "extra": { "payment_intent": "pi_..." } } }Allow for settlement
On-chain settlement takes a few seconds. Retrying before it lands returns
payment_settlement_failed (402, retry: true) — the identical request succeeds moments
later.
Rules worth knowing
- One payment buys exactly one request or job. A replayed payment returns
payment_invalid(402,retry: false). - Never trust the challenge's echoed price. The server recomputes the price from your request body and validates the payment against that.
- The challenge path is rate-limited per IP (
challenge_rate_limited, 429). Every challenge mints a deposit address, so unauthenticated probes are capped the same way registration is. - Your wallet address is your identity. Paying again from the same wallet lands in the same account, so audit history carries across payments.
Polling a job without a key
x402 submissions to /bulk and /crawl return a job_token next to job_id. Send it as
X-Job-Token to check on work you already paid for:
curl https://api.wellmarked.io/bulk/9aaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee \
-H "X-Job-Token: jt_..."No payment, and no key, is needed for the poll.