Charge per-request in USDC on Base. Payments settle on-chain directly to your wallet — no middleman, no monthly fees, no custodial risk.
$ curl -I https://paywall.wickedapi.com/wickedapi/weather
HTTP/2 402
x-payment-required: {"x402Version":2,"accepts":[{"scheme":"exact",
"network":"eip155:8453","maxAmountRequired":"10000",
"asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"payTo":"0x63EbccD826b874CE988e6498eAabB6Bd47AfC8A4"}]}
content-type: application/json
x-frame-options: SAMEORIGIN
# Client pays 0.01 USDC via EIP-3009 transferWithAuthorization
# No ETH needed — gasless, signed in-browser or server-side
$ curl https://paywall.wickedapi.com/wickedapi/weather \
-H "X-PAYMENT: <signed-eip3009-payload>"
HTTP/2 200
x-payment-response: {"success":true,"txHash":"0x0c6d48..."}
/try-it
No signup, no fake data — connect a wallet, sign a payment, and this calls a real backend live in your browser. Costs $0.01 in real USDC on Base mainnet.
/how-it-works
No SDK to integrate on the server side. No wallet infrastructure to run. Just configure routes and route traffic through the gateway.
Create a tenant account, then declare which API paths to monetize — set the price in USD, the on-chain payTo address, and the network. Updates are live within seconds.
Point your API consumers to paywall.wickedapi.com/{your-slug}/{path}. The gateway intercepts every request and enforces payment before forwarding to your response.
Valid payments settle on-chain via EIP-3009 transferWithAuthorization — USDC lands in your wallet instantly. Settlements are recorded and queryable by route.
/quickstart
All configuration is through the REST API or admin dashboard. No code changes required on your existing API.
https://paywall.wickedapi.com · Admin API: https://paywall-admin.wickedapi.com
Request access to get a tenant API key, or use the admin dashboard to create your account. Your key is shown once at creation — store it securely.
# Admin creates a tenant (requires ADMIN_MASTER_KEY) $ curl -X POST https://paywall-admin.wickedapi.com/admin/tenants \ -H "Authorization: Bearer <admin-master-key>" \ -H "Content-Type: application/json" \ -d '{"name":"My API","slug":"myapi"}' # Response — save this key, it is not recoverable { "tenant": { "id": "clx...", "slug": "myapi" }, "apiKey": "x402_live_..." }
Register which paths to paywall, the price in USD, and the wallet that receives payment. Route changes take effect on the gateway within ~20 seconds — no redeploy.
$ curl -X POST https://paywall-admin.wickedapi.com/tenants/me/routes \ -H "Authorization: Bearer x402_live_..." \ -H "Content-Type: application/json" \ -d '{ "method": "GET", "path": "/weather", "price": "$0.001", "network": "eip155:8453", "payTo": "0xYourWalletAddress", "scheme": "exact" }' # Route is now live at: # https://paywall.wickedapi.com/myapi/weather
Bulk-import multiple routes at once using POST /tenants/me/routes/import with a routes array.
A plain request returns 402 with the full payment requirements. An x402-aware client (browser wallet or server SDK) pays and retries automatically.
# Plain request — see the 402 $ curl -si https://paywall.wickedapi.com/myapi/weather | head -20 HTTP/2 402 x-payment-required: {"x402Version":2,"accepts":[{"scheme":"exact", "network":"eip155:8453","maxAmountRequired":"1000", "asset":"0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913", "payTo":"0xYourWalletAddress","resource":"https://..."}]}
// JavaScript — x402 fetch interceptor (auto-pays on 402) import { withPaymentInterceptor } from "@x402/fetch"; import { createWalletClient } from "viem"; const wallet = createWalletClient({ /* your viem wallet */ }); const fetch402 = withPaymentInterceptor(fetch, wallet); const res = await fetch402("https://paywall.wickedapi.com/myapi/weather"); // → Pays 0.001 USDC automatically, returns 200 with body
Every settled payment is recorded with tx hash, payer address, amount, network, and route. Query them via API or browse the dashboard.
$ curl https://paywall-admin.wickedapi.com/tenants/me/settlements \ -H "Authorization: Bearer x402_live_..." { "settlements": [{ "id": "clx...", "status": "settled", "amount": "1000", "asset": "0x833589...", "txHash": "0x0c6d48...", "payerAddress": "0x215Ef7...", "network": "eip155:8453", "settledAt": "2026-07-01T..." }] }
/api-reference
Two base URLs — the gateway handles paid traffic, the admin API handles configuration.
Authorization: Bearer x402_live_....
Admin endpoints require the ADMIN_MASTER_KEY bearer token.
| Method | Path | Auth | Description |
|---|---|---|---|
| POST | /admin/tenants | admin key | Create a new tenant. Returns the plaintext API key once — not recoverable. |
| GET | /admin/tenants | admin key | List all tenants with route counts and creation dates. |
| GET | /admin/settlements | admin key | Global settlement history across all tenants. Query param: ?limit=N (max 200). |
| GET | /tenants/me | tenant key | Get your tenant profile (name, slug, key hint). |
| GET | /tenants/me/routes | tenant key | List all configured routes for your tenant. |
| POST | /tenants/me/routes | tenant key | Create a single route. Fields: method, path, price, network, payTo, scheme, description?. |
| POST | /tenants/me/routes/import | tenant key | Bulk upsert routes from a {"routes":[...]} array. Idempotent — safe to re-run. |
| PATCH | /tenants/me/routes/:id | tenant key | Update price, payTo, network, or description on an existing route. Price/payTo changes apply within ~20s without a gateway restart. |
| DELETE | /tenants/me/routes/:id | tenant key | Remove a route. The gateway detects the removal and restarts within ~20s. |
| GET | /tenants/me/settlements | tenant key | Your settlement history. Query param: ?limit=N (max 200). |
| GET | /healthz | open | Service health check. |
| Method | Path | Auth | Description |
|---|---|---|---|
| GET POST | /{slug}/{path} | x402 payment | Protected endpoint. Returns 402 with payment requirements if no valid X-PAYMENT header. Returns 200 on successful payment. Replay attacks are rejected (idempotency key derived from payment payload). |
| GET | /healthz | open | Returns active networks, route count, and service status. |
{ "method": "GET" | "POST", "path": "/your-path", // must start with /, alphanumeric + ._-/ "price": "$0.001", // USD amount, e.g. "$0.001" or "0.01" "network": "eip155:8453", // Base mainnet | "eip155:84532" Base Sepolia "payTo": "0xYourWalletAddress", // EVM address to receive USDC "scheme": "exact", // currently only "exact" is supported "description": "optional label" // shown in dashboard }
/protocol
No proprietary payment rail. Every component is verifiable on-chain and auditable by anyone.
Payments use transferWithAuthorization — payers sign off-chain, the relayer submits the transaction. No ETH required in the payer's wallet.
Every payment payload is hashed and stored. Duplicate submissions are rejected before settlement — each successful payment corresponds to exactly one API response.
Payments settle on Base mainnet and are verifiable by tx hash. The gateway never holds funds — USDC moves directly from payer to your wallet.
The payment requirement is returned as a structured JSON header on a normal 402 response — compatible with any HTTP client that speaks the x402 protocol.
One gateway serves many API owners. Route changes (price, payTo, new paths) apply without redeploying — the gateway polls Postgres and reloads live.
Development and integration testing run on Base Sepolia (eip155:84532) with testnet USDC. Production traffic uses Base mainnet.