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. 1
    Buy credits

    Visit the homepage and complete checkout via NowPayments (card or any of 100+ cryptos). $1 buys 5 credits. Credits never expire. Or skip this entirely — see x402 rail for autonomous per-call USDC.

  2. 2
    Save your API key

    NowPayments redirects you to a success page with an ap_live_... key. Save it — we won't show it again.

  3. 3
    Make 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.png

Authentication

Two parallel rails. Pick whichever fits your agent. Same business logic, different auth + URL prefix.

Rail #1 — Bearer (credits)
/api/v1/<name>
Authorization: Bearer
  ap_live_VyQ...

Pre-paid via NowPayments. Best for human devs giving keys to agents.

Rail #2 — x402 (USDC) ★
/api/x402/<name>
X-PAYMENT: <base64 of
  signed EIP-3009>

Per-call USDC settlement. No signup. Agent-native. See x402 section.

401invalid_api_key(Bearer rail only)

Header missing, malformed, or key not recognized.

402payment_required

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.

Dashboard (no signup)

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.

PackagePriceCredits$ / call
small$15$0.200
medium$530$0.167
large$20150$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. 1.Agent POSTs to /api/x402/<endpoint> without payment header.
  2. 2.Server returns 402 + spec body with accepts[] (network, asset, amount, payTo).
  3. 3.Agent signs EIP-3009 offline, base64-encodes the payload, retries with X-PAYMENT header.
  4. 4.Server verifies → does the work → settles on-chain → returns 200 + content + X-PAYMENT-RESPONSE (tx hash, payer).

Pricing

EndpointAtomic unitsUSDC / call
all (default)10000.001 USDC
/summarize (LLM cost)100000.01 USDC

Failed calls (4xx/5xx) skip on-chain settlement — buyer is not charged.

Network

Network:base (mainnet)— real USDC, real settlement
USDC contract:0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913
Chain ID:8453

Need 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.

EndpointUSDC costCredits issuedPer-call effective
POST /api/buy-credits/small$15$0.20
POST /api/buy-credits/medium$530$0.167
POST /api/buy-credits/large$20150$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.

MCP endpoint:https://402s.shop/api/mcp
Transport:streamable HTTP (POST, JSON-RPC 2.0)
Auth:Authorization: Bearer ap_live_...

Claude 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_price

Each 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

400bad_request

Invalid JSON, missing required fields, or out-of-range values.

401invalid_api_key

Missing or unrecognized Bearer token.

402payment_required

API key valid but credits = 0. Top up to continue.

422processing_failed

External fetch failed (URL unreachable, transcript not found, etc). No credit deducted.

500internal_error

Unexpected server error. No credit deducted.

503ai_unavailable

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

POST/api/v1/qr-code·1 credit

Generate a QR code PNG from any text or URL.

Request body

textstringrequired

Text to encode (1–2048 chars).

sizenumberoptional

Width 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

POST/api/v1/og-image·1 credit

Generate a 1200×630 social-media OG image with title and subtitle.

Request body

titlestringrequired

1–200 characters.

subtitlestringoptional

Up to 300 characters.

theme"dark" | "light"optional

Default "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

POST/api/v1/screenshot·1 credit

Render a webpage in headless Chromium and return a PNG screenshot.

Request body

urlstringrequired

http(s) URL to screenshot.

viewport{ width, height }optional

320–1920 × 240–2160. Default 1280×800.

fullPagebooleanoptional

Capture 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

POST/api/v1/pdf-from-url·1 credit

Render any URL to a print-ready PDF.

Request body

urlstringrequired

http(s) URL.

format"A4" | "Letter" | "Legal"optional

Default "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

POST/api/v1/word-count·1 credit

Count words on any webpage and estimate reading time.

Request body

urlstringrequired

http(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

POST/api/v1/extract-metadata·1 credit

Extract Open Graph, Twitter card, and standard meta tags.

Request body

urlstringrequired

http(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

POST/api/v1/extract-emails·1 credit

Find email addresses on a page (mailto links + body text). Deduplicated, max 100.

Request body

urlstringrequired

http(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

POST/api/v1/website-tech·1 credit

Detect framework, CMS, analytics, and hosting/CDN from HTML and response headers.

Request body

urlstringrequired

http(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

POST/api/v1/whois·1 credit

WHOIS lookup with normalized fields (registrar, dates, nameservers, status).

Request body

domainstringrequired

Domain 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

POST/api/v1/domain-check·1 credit

Heuristic availability check via WHOIS — best-effort, not authoritative.

Request body

domainstringrequired

Domain 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

POST/api/v1/youtube-transcript·1 credit

Fetch a YouTube video transcript with timestamps and computed word count.

Request body

urlstringrequired

YouTube watch / shorts / embed / youtu.be URL.

langstringoptional

BCP-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

POST/api/v1/summarize·1 credit

AI-powered summary of supplied text or fetched URL. Uses Claude Haiku 4.5.

Request body

textstringoptional

Provide either text (50–50000 chars) or url, not both.

urlstringoptional

http(s) URL to fetch and summarize.

length"short" | "medium" | "long"optional

Default "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

POST/api/v1/coin-price·1 credit

Crypto spot prices in USD via CoinGecko. Up to 25 symbols per call. Cached 30s.

Request body

symbolsstring[]optional

Default ["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

POST/api/v1/ens-resolve·1 credit

Resolve ENS name to address (forward) or address to primary name (reverse). Includes avatar where available. Cached 5 min.

Request body

namestringoptional

ENS name like "vitalik.eth". One of name OR address required.

addressstringoptional

0x... 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

POST/api/v1/wallet-balance·1 credit

Native + USDC balance for an EVM address across multiple chains. Default returns Base + Ethereum. Cached 15s.

Request body

addressstringrequired

0x... EVM address.

chainsstring[]optional

Default ["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

POST/api/v1/gas-price·1 credit

Live gas price across EVM chains in gwei. Default returns Base + Ethereum. Cached 10s.

Request body

chainsstring[]optional

Default ["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"]}'