Documentation
Pay-per-call HTTP 402 endpoints for AI agents. Two rails: classic Bearer credits or x402 USDC per call. Twelve endpoints, mirrored under both prefixes.
Quickstart
Get an API key and make your first call in under a minute.
- 1
- 2Save your API key
NowPayments redirects you to a success page with an
ap_live_...key. Save it — we won't show it again. - 3Make your first request
Bearer auth on every endpoint. 1 credit per successful call.
curl -X POST https://402s.shop/api/v1/qr-code \
-H "Authorization: Bearer ap_live_..." \
-H "Content-Type: application/json" \
-d '{"text":"Hello from my agent"}' \
--output result.pngAuthentication
Two parallel rails. Pick whichever fits your agent. Same business logic, different auth + URL prefix.
Authorization: Bearer ap_live_VyQ...
Pre-paid via NowPayments. Best for human devs giving keys to agents.
X-PAYMENT: <base64 of signed EIP-3009>
Per-call USDC settlement. No signup. Agent-native. See x402 section.
Header missing, malformed, or key not recognized.
Bearer rail: balance is 0 — top up at the URL in the WWW-Authenticate header.
x402 rail: X-PAYMENT missing/invalid — body contains spec accepts[] array with payment requirements.
For any Bearer key, a live dashboard at /dashboard/<api-key> shows credits remaining, total calls, success rate, and a real-time activity log (refreshes every 2s). No login or signup — possession of the key is the auth, the URL is the dashboard. Bookmark, share with the user the agent acts on behalf of, or poll programmatically. Same pattern works for keys minted via NowPayments checkout, autonomous x402 buy-credits, or future endpoints.
Pricing
Pay-per-call. 1 credit per successful endpoint call. Credits never expire.
| Package | Price | Credits | $ / call |
|---|---|---|---|
| small | $1 | 5 | $0.200 |
| medium | $5 | 30 | $0.167 |
| large | $20 | 150 | $0.133 |
4xx and 5xx responses do not deduct credits. Only successful 2xx responses are charged.
x402 — agent-autonomous USDC pay-per-call ★
The x402 rail mirrors every /api/v1/<name> endpoint at /api/x402/<name>. Instead of a Bearer key, the agent pays per call by signing a USDC EIP-3009 transferWithAuthorization — gasless, sub-second, no account.
This implements the open x402 protocol by Coinbase. Verification + on-chain settlement happens via the Coinbase facilitator (free, hosted).
The flow (4 steps)
- 1.Agent POSTs to
/api/x402/<endpoint>without payment header. - 2.Server returns
402+ spec body withaccepts[](network, asset, amount, payTo). - 3.Agent signs EIP-3009 offline, base64-encodes the payload, retries with
X-PAYMENTheader. - 4.Server verifies → does the work → settles on-chain → returns
200+ content +X-PAYMENT-RESPONSE(tx hash, payer).
Pricing
| Endpoint | Atomic units | USDC / call |
|---|---|---|
| all (default) | 1000 | 0.001 USDC |
| /summarize (LLM cost) | 10000 | 0.01 USDC |
Failed calls (4xx/5xx) skip on-chain settlement — buyer is not charged.
Network
0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913Need USDC on Base? Bridge from any chain via bridge.base.org, or buy directly on Coinbase / Bybit / Binance and withdraw to Base.
Example: probe the requirements
# Hit any x402 endpoint without payment to discover requirements: curl -X POST https://402s.shop/api/x402/qr-code \ -H "Content-Type: application/json" \ -d '{"text":"hi"}' # Response (HTTP 402): { "x402Version": 1, "error": "X-PAYMENT header required", "accepts": [{ "scheme": "exact", "network": "base", "maxAmountRequired": "1000", "asset": "0x833589fCD6eDb...", "payTo": "0xF17753bC761Cf...", "maxTimeoutSeconds": 300 }] }
Example: signed payment (Node.js + viem)
import { privateKeyToAccount } from 'viem/accounts'; const account = privateKeyToAccount(process.env.PRIVATE_KEY); const reqs = (await (await fetch(URL, { method:'POST', body:JSON.stringify({text:'hi'}) })).json()).accepts[0]; const sig = await account.signTypedData({ domain: { name:'USDC', version:'2', chainId: 8453, verifyingContract: reqs.asset }, types: { TransferWithAuthorization: [...] }, primaryType: 'TransferWithAuthorization', message: { from: account.address, to: reqs.payTo, value: BigInt(reqs.maxAmountRequired), ... }, }); const xPayment = Buffer.from(JSON.stringify({ x402Version:1, scheme:reqs.scheme, network:reqs.network, payload:{signature:sig, authorization:{...}} })).toString('base64'); const result = await fetch(URL, { method:'POST', headers: { 'X-PAYMENT': xPayment }, body: JSON.stringify({text:'hi'}) }); // → 200 OK + PNG + X-PAYMENT-RESPONSE header (tx hash, payer)
Full reference client: scripts/test-x402.mjs. For higher-level abstractions, see Coinbase's x402 SDK (Node, Python, Go).
Autonomous credits purchase — no signup, no human checkout ★
Agents can buy a credits API key fully on their own using x402. POST any of the three package URLs below, sign the EIP-3009 USDC payment for the package amount, retry with the X-PAYMENT header. On settlement, the response contains a fresh ap_live_... key with the package's credits — the agent can then use it on the credits rail (1 credit per call) for high-volume work or hand it to a human user.
| Endpoint | USDC cost | Credits issued | Per-call effective |
|---|---|---|---|
POST /api/buy-credits/small | $1 | 5 | $0.20 |
POST /api/buy-credits/medium | $5 | 30 | $0.167 |
POST /api/buy-credits/large | $20 | 150 | $0.133 |
Flow
# 1. Probe — empty body, no payment curl -X POST https://402s.shop/api/buy-credits/small # 2. Server returns 402 with x402 accepts[] { "x402Version": 1, "accepts": [{ "maxAmountRequired": "1000000", // $1 USDC, 6 decimals "asset": "0x833589fCD6...", // USDC on Base "payTo": "0xF177..." }]} # 3. Sign EIP-3009 transferWithAuthorization, retry with X-PAYMENT curl -X POST https://402s.shop/api/buy-credits/small \ -H "X-PAYMENT: <base64(signed payload)>" # 4. On settle → 200 with the new key { "ok": true, "api_key": "ap_live_xxxxxxxx...", "credits": 5, "package": "small", "paid_usd": 1 }
When to use this vs the per-call x402 rail:
- Per-call x402 (cheaper for low volume) — $0.001 per call, no key, sub-cent. Best for ad-hoc agent calls.
- Buy a credits package (better for human-flow) — get a persistent key. Best when an agent acts on a human's "buy me X credits" intent, or a reseller provisions keys for their users, or a multi-agent system needs separate keys per agent for accounting.
Reference signing client (the same EIP-3009 + X-PAYMENT flow as any other x402 endpoint): scripts/test-x402.mjs.
MCP server — one-click install for Claude / Cursor / Cline ★
402s.shop is also a hosted Model Context Protocol server. Add a single config entry to Claude Desktop, Cursor, or any MCP client and all 16 endpoints become native tools your agent can call by name. No SDK, no curl, no glue code.
https://402s.shop/api/mcpClaude Desktop
Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"402s-shop": {
"url": "https://402s.shop/api/mcp",
"headers": {
"Authorization": "Bearer ap_live_..."
}
}
}
}Cursor
Edit ~/.cursor/mcp.json (same JSON shape as Claude Desktop, above).
Cline (VS Code)
Edit cline_mcp_settings.json via the Cline panel → MCP Servers → Edit.
Older clients (stdio-only)
Use the mcp-remote shim to bridge stdio → HTTP:
{
"mcpServers": {
"402s-shop": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://402s.shop/api/mcp", "--header", "Authorization:Bearer ap_live_..."]
}
}
}Available tools
All 16 endpoints exposed as MCP tools (tool name = endpoint name with underscores):
qr_code · og_image · screenshot · pdf_from_url · word_count · extract_metadata · extract_emails · website_tech · whois · domain_check · youtube_transcript · summarize · coin_price · ens_resolve · wallet_balance · gas_priceEach call deducts 1 credit (failures don't charge). Image responses (qr, og, screenshot) return as native MCP image content; agents can render them in chat without extra steps.
Errors
Invalid JSON, missing required fields, or out-of-range values.
Missing or unrecognized Bearer token.
API key valid but credits = 0. Top up to continue.
External fetch failed (URL unreachable, transcript not found, etc). No credit deducted.
Unexpected server error. No credit deducted.
AI summarization endpoint is offline (missing ANTHROPIC_API_KEY).
HTTP 402 response example
HTTP/1.1 402 Payment Required WWW-Authenticate: Bearer realm="402s.shop", charge="$1", topup_url="https://402s.shop" X-Credits-Remaining: 0 Content-Type: application/json { "error": "payment_required", "message": "Out of credits. Top up to continue using the API.", "topup_url": "https://402s.shop", "credits_remaining": 0 }
Endpoints
16 endpoints, mirrored under both rails: /api/v1/<name> (Bearer, 1 credit) or /api/x402/<name> (USDC, 0.001 per call). All POST. The path docs below show the Bearer rail; for x402, swap the prefix and use X-PAYMENT instead.
/qr-code
/api/v1/qr-code·1 creditGenerate a QR code PNG from any text or URL.
Request body
textstringrequiredText to encode (1–2048 chars).
sizenumberoptionalWidth in pixels (100–1000, default 300).
Response
image/png with X-Credits-Remaining header.
Example
curl -X POST https://402s.shop/api/v1/qr-code \
-H "Authorization: Bearer ap_live_..." \
-H "Content-Type: application/json" \
-d '{"text":"Hello from my agent"}' \
--output result.png/og-image
/api/v1/og-image·1 creditGenerate a 1200×630 social-media OG image with title and subtitle.
Request body
titlestringrequired1–200 characters.
subtitlestringoptionalUp to 300 characters.
theme"dark" | "light"optionalDefault "dark".
Response
image/png with X-Credits-Remaining header.
Example
curl -X POST https://402s.shop/api/v1/og-image \
-H "Authorization: Bearer ap_live_..." \
-H "Content-Type: application/json" \
-d '{"title":"AgentPay","subtitle":"HTTP 402 for AI agents","theme":"dark"}' \
--output result.png/screenshot
/api/v1/screenshot·1 creditRender a webpage in headless Chromium and return a PNG screenshot.
Request body
urlstringrequiredhttp(s) URL to screenshot.
viewport{ width, height }optional320–1920 × 240–2160. Default 1280×800.
fullPagebooleanoptionalCapture full scrolling page. Default false.
Response
image/png with X-Credits-Remaining header.
Example
curl -X POST https://402s.shop/api/v1/screenshot \
-H "Authorization: Bearer ap_live_..." \
-H "Content-Type: application/json" \
-d '{"url":"https://402s.shop","viewport":{"width":1280,"height":800},"fullPage":false}' \
--output result.png/pdf-from-url
/api/v1/pdf-from-url·1 creditRender any URL to a print-ready PDF.
Request body
urlstringrequiredhttp(s) URL.
format"A4" | "Letter" | "Legal"optionalDefault "A4".
Response
application/pdf with X-Credits-Remaining header.
Example
curl -X POST https://402s.shop/api/v1/pdf-from-url \
-H "Authorization: Bearer ap_live_..." \
-H "Content-Type: application/json" \
-d '{"url":"https://en.wikipedia.org/wiki/HTTP_402","format":"A4"}' \
--output result.pdf/word-count
/api/v1/word-count·1 creditCount words on any webpage and estimate reading time.
Request body
urlstringrequiredhttp(s) URL.
Response
application/json with X-Credits-Remaining header.
{
"url": "https://en.wikipedia.org/wiki/HTTP_402",
"wordCount": 1247,
"readingTimeMinutes": 7,
"charCount": 8423
}Example
curl -X POST https://402s.shop/api/v1/word-count \
-H "Authorization: Bearer ap_live_..." \
-H "Content-Type: application/json" \
-d '{"url":"https://en.wikipedia.org/wiki/HTTP_402"}'/extract-metadata
/api/v1/extract-metadata·1 creditExtract Open Graph, Twitter card, and standard meta tags.
Request body
urlstringrequiredhttp(s) URL.
Response
application/json with X-Credits-Remaining header.
{
"url": "https://github.com",
"title": "GitHub",
"description": "GitHub is where over 100 million developers shape the future of software.",
"image": "https://github.githubassets.com/.../og-image.png",
"siteName": "GitHub",
"type": "object",
"favicon": "https://github.com/favicon.ico",
"locale": "en"
}Example
curl -X POST https://402s.shop/api/v1/extract-metadata \
-H "Authorization: Bearer ap_live_..." \
-H "Content-Type: application/json" \
-d '{"url":"https://github.com"}'/extract-emails
/api/v1/extract-emails·1 creditFind email addresses on a page (mailto links + body text). Deduplicated, max 100.
Request body
urlstringrequiredhttp(s) URL.
Response
application/json with X-Credits-Remaining header.
{
"url": "https://www.python.org/about/contact/",
"emails": [
"webmaster@python.org",
"psf@python.org"
],
"count": 2
}Example
curl -X POST https://402s.shop/api/v1/extract-emails \
-H "Authorization: Bearer ap_live_..." \
-H "Content-Type: application/json" \
-d '{"url":"https://www.python.org/about/contact/"}'/website-tech
/api/v1/website-tech·1 creditDetect framework, CMS, analytics, and hosting/CDN from HTML and response headers.
Request body
urlstringrequiredhttp(s) URL.
Response
application/json with X-Credits-Remaining header.
{
"url": "https://vercel.com",
"framework": "Next.js",
"cms": null,
"analytics": [
"Google Analytics"
],
"hosting": "Vercel",
"server": "Vercel",
"technologies": [
"Next.js",
"Google Analytics",
"Vercel"
]
}Example
curl -X POST https://402s.shop/api/v1/website-tech \
-H "Authorization: Bearer ap_live_..." \
-H "Content-Type: application/json" \
-d '{"url":"https://vercel.com"}'/whois
/api/v1/whois·1 creditWHOIS lookup with normalized fields (registrar, dates, nameservers, status).
Request body
domainstringrequiredDomain name like example.com.
Response
application/json with X-Credits-Remaining header.
{
"domain": "402s.shop",
"registrar": "Namecheap, Inc.",
"createdDate": "2026-04-30T00:00:00Z",
"expiresDate": "2027-04-30T00:00:00Z",
"updatedDate": "2026-04-30T00:00:00Z",
"nameservers": [
"ns1.example.com",
"ns2.example.com"
],
"status": [
"clientTransferProhibited"
],
"raw": {
"...": "full whois record"
}
}Example
curl -X POST https://402s.shop/api/v1/whois \
-H "Authorization: Bearer ap_live_..." \
-H "Content-Type: application/json" \
-d '{"domain":"402s.shop"}'/domain-check
/api/v1/domain-check·1 creditHeuristic availability check via WHOIS — best-effort, not authoritative.
Request body
domainstringrequiredDomain name like example.com.
Response
application/json with X-Credits-Remaining header.
{
"domain": "this-domain-is-probably-available-12345.com",
"available": true,
"registrar": null,
"expiresDate": null
}Example
curl -X POST https://402s.shop/api/v1/domain-check \
-H "Authorization: Bearer ap_live_..." \
-H "Content-Type: application/json" \
-d '{"domain":"this-domain-is-probably-available-12345.com"}'/youtube-transcript
/api/v1/youtube-transcript·1 creditFetch a YouTube video transcript with timestamps and computed word count.
Request body
urlstringrequiredYouTube watch / shorts / embed / youtu.be URL.
langstringoptionalBCP-47 language code (default "en").
Response
application/json with X-Credits-Remaining header.
{
"videoId": "dQw4w9WgXcQ",
"url": "https://www.youtube.com/watch?v=dQw4w9WgXcQ",
"language": "en",
"transcript": [
{
"text": "We're no strangers to love",
"offset": 0,
"duration": 3.5
},
{
"text": "You know the rules and so do I",
"offset": 3.5,
"duration": 3.5
}
],
"fullText": "We're no strangers to love You know the rules and so do I ...",
"wordCount": 312,
"durationSeconds": 213
}Example
curl -X POST https://402s.shop/api/v1/youtube-transcript \
-H "Authorization: Bearer ap_live_..." \
-H "Content-Type: application/json" \
-d '{"url":"https://www.youtube.com/watch?v=dQw4w9WgXcQ"}'/summarize
/api/v1/summarize·1 creditAI-powered summary of supplied text or fetched URL. Uses Claude Haiku 4.5.
Request body
textstringoptionalProvide either text (50–50000 chars) or url, not both.
urlstringoptionalhttp(s) URL to fetch and summarize.
length"short" | "medium" | "long"optionalDefault "medium".
Response
application/json with X-Credits-Remaining header.
{
"summary": "HTTP 402 Payment Required is a status code defined in the HTTP specification...",
"originalLength": 8423,
"summaryLength": 412,
"compressionRatio": 0.0489,
"model": "claude-haiku-4-5",
"length": "medium"
}Example
curl -X POST https://402s.shop/api/v1/summarize \
-H "Authorization: Bearer ap_live_..." \
-H "Content-Type: application/json" \
-d '{"url":"https://en.wikipedia.org/wiki/HTTP_402","length":"medium"}'/coin-price
/api/v1/coin-price·1 creditCrypto spot prices in USD via CoinGecko. Up to 25 symbols per call. Cached 30s.
Request body
symbolsstring[]optionalDefault ["BTC","ETH","USDC"]. Supports 25+ tickers (BTC, ETH, USDC, USDT, SOL, BNB, XRP, XMR, etc).
Response
application/json with X-Credits-Remaining header.
{
"currency": "USD",
"prices": {
"BTC": {
"usd": 92450.12,
"last_updated_at": 1730520000
},
"ETH": {
"usd": 3210.55,
"last_updated_at": 1730520000
},
"USDC": {
"usd": 1.001,
"last_updated_at": 1730520000
},
"XMR": {
"usd": 165.32,
"last_updated_at": 1730520000
}
},
"source": "coingecko"
}Example
curl -X POST https://402s.shop/api/v1/coin-price \
-H "Authorization: Bearer ap_live_..." \
-H "Content-Type: application/json" \
-d '{"symbols":["BTC","ETH","USDC","XMR"]}'/ens-resolve
/api/v1/ens-resolve·1 creditResolve ENS name to address (forward) or address to primary name (reverse). Includes avatar where available. Cached 5 min.
Request body
namestringoptionalENS name like "vitalik.eth". One of name OR address required.
addressstringoptional0x... EVM address for reverse lookup. One of name OR address required.
Response
application/json with X-Credits-Remaining header.
{
"name": "vitalik.eth",
"address": "0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045",
"avatar": "https://ipfs.io/ipfs/QmSP4nq9..."
}Example
curl -X POST https://402s.shop/api/v1/ens-resolve \
-H "Authorization: Bearer ap_live_..." \
-H "Content-Type: application/json" \
-d '{"name":"vitalik.eth"}'/wallet-balance
/api/v1/wallet-balance·1 creditNative + USDC balance for an EVM address across multiple chains. Default returns Base + Ethereum. Cached 15s.
Request body
addressstringrequired0x... EVM address.
chainsstring[]optionalDefault ["base","ethereum"]. Supported: ethereum, base, arbitrum, optimism, polygon. Max 5 per call.
Response
application/json with X-Credits-Remaining header.
{
"address": "0xF17753bC761Cf248b43Bed57d433254C6BDB5De7",
"balances": {
"base": {
"ok": true,
"native": {
"symbol": "ETH",
"value": "0.0123"
},
"usdc": {
"value": "0.001",
"contract": "0x833589fCD6..."
}
},
"ethereum": {
"ok": true,
"native": {
"symbol": "ETH",
"value": "0.0"
},
"usdc": {
"value": "0.0",
"contract": "0xA0b86991..."
}
}
}
}Example
curl -X POST https://402s.shop/api/v1/wallet-balance \
-H "Authorization: Bearer ap_live_..." \
-H "Content-Type: application/json" \
-d '{"address":"0xF17753bC761Cf248b43Bed57d433254C6BDB5De7","chains":["base","ethereum"]}'/gas-price
/api/v1/gas-price·1 creditLive gas price across EVM chains in gwei. Default returns Base + Ethereum. Cached 10s.
Request body
chainsstring[]optionalDefault ["base","ethereum"]. Supported: ethereum, base, arbitrum, optimism, polygon. Max 5 per call.
Response
application/json with X-Credits-Remaining header.
{
"gas": {
"base": {
"ok": true,
"gwei": "0.005",
"wei": "5000000"
},
"ethereum": {
"ok": true,
"gwei": "12.5",
"wei": "12500000000"
},
"arbitrum": {
"ok": true,
"gwei": "0.01",
"wei": "10000000"
}
},
"unit": "gwei"
}Example
curl -X POST https://402s.shop/api/v1/gas-price \
-H "Authorization: Bearer ap_live_..." \
-H "Content-Type: application/json" \
-d '{"chains":["base","ethereum","arbitrum"]}'