3-step quickstart.
- 01top up usdcGo to /topup, connect a wallet, sign one EIP-3009 transferWithAuthorization. Credits your balance instantly on Base sepolia.
- 02mint a keyOpen /dashboard, hit new key. Shown once — copy it now, we only store an HMAC.
- 03point your tool hereSet
ANTHROPIC_BASE_URL(orOPENAI_BASE_URL) tohttps://api.x402prompt.comand paste the key. Sections below have copy-pasteable config for every popular tool.
Two payment modes.
Every request settles in USDC over x402. Pick the mode that fits the caller — same endpoints, same model list, same pricing.
Top up once, mint a key.
- 1sign EIP-3009/topup
- 2balance creditedon Base
- 3mint sk-x402-…/dashboard
- 4call ∞×Authorization: Bearer
/v1/chat/completions·per-key spend limits + allowlists at /dashboardSign one EIP-3009 per call.
- 1POST (no auth)/v1/chat/completions
- 2402 quote
PAYMENT-REQUIRED - 3signtransferWithAuthorization
- 4retry
PAYMENT-SIGNATURE - 5200 + tx hash
PAYMENT-RESPONSE
PAYG flow — curl walkthrough
Two requests: a probe to learn the price, then the same payload signed. ThePAYMENT-REQUIRED header carries a base64 JSON quote with the amount, USDC asset address, recipient (payTo), and avalidBefore deadline — sign exactly those fields with EIP-3009.
# 1. probe — no auth, no payment header → gateway quotes a price
curl -i -X POST "https://api.x402prompt.com/v1/chat/completions" \
-H "Content-Type: application/json" \
-d '{"model":"claude-haiku-4-5","messages":[{"role":"user","content":"hi"}]}'
# → HTTP/1.1 402 Payment Required
# → PAYMENT-REQUIRED: <base64-json quote: amount, asset, payTo, nonce, validBefore, …>
# → body: {"error":{"code":"payment_required","message":"send PAYMENT-SIGNATURE for …"}}
# 2. sign EIP-3009 transferWithAuthorization with the quoted params,
# then retry the SAME request with the signature attached:
curl -X POST "https://api.x402prompt.com/v1/chat/completions" \
-H "Content-Type: application/json" \
-H "PAYMENT-SIGNATURE: <base64-payload>" \
-d '{"model":"claude-haiku-4-5","messages":[{"role":"user","content":"hi"}]}'
# → HTTP/1.1 200, plus PAYMENT-RESPONSE header with the settlement tx hashReference signer: cmd/test-pay in the repo signs and submits in one shot. Browser clients use wagmi / viem — the dashboard's /topup page is the canonical implementation.
Pricing — flat ceiling per call
Live per-model prices at /models (also at GET /v1/pricing). The quote in PAYMENT-REQUIRED is the same number — the gateway will never charge more than the quoted amount on a given call.
Endpoints + auth.
Base URL — replace with your deployment hostname: https://api.x402prompt.com
| method | path | notes |
|---|---|---|
| POST | /v1/chat/completions | OpenAI-compatible chat. SSE via stream:true. 240s cap. |
| POST | /v1/messages | Anthropic-native. Claude models. Streaming + tool use. |
| POST | /v1/images/generations | OpenAI-compatible image gen. Flat per-model price. |
| POST | /v1/videos/generations | Async video. Returns task_id. |
| GET | /v1/videos/{task_id} | Poll video task status / fetch result. |
| GET | /v1/models | Public model catalog. No auth. |
Auth headers
Two equivalent forms — pick whichever your client defaults to. Both hit the same code path.
| openai-style | Authorization: Bearer sk-x402-… |
| anthropic-style | x-api-key: sk-x402-… |
| required for /v1/messages | anthropic-version: 2023-06-01 |
Without either header the gateway returns 402 with an x402 PAYG quote. See payment modes for the signature flow.
Available models.
43+ models across chat, image, and video — Claude, GPT-5.5, Gemini 3.1, Grok, Veo, Kling, nano-banana. Use canonical aliases (they survive provider rotations):
- claude-opus-4-7 — deepest reasoning
- claude-sonnet-4-6 — balanced default
- claude-haiku-4-5 — fast + cheap
- gpt-5.5-pro · gemini-3.1-pro-preview · grok-4.20-beta
- veo-3.1-generate-preview · kling-video-v3 · nano-banana-pro
Full catalog and live pricing at /models. Hit GET /v1/models for the raw JSON.
Claude Code.
Two env vars. The official Claude Code CLI honors both — no plugin, no wrapper.
export ANTHROPIC_BASE_URL="https://api.x402prompt.com" export ANTHROPIC_AUTH_TOKEN="sk-x402-…" export ANTHROPIC_MODEL="claude-sonnet-4-6" # then just: claude "refactor this function to use tanstack query"
If you ran claude /login previously, OAuth credentials override env vars — clear them with claude /logout first.
OpenAI Codex CLI.
Codex CLI is OpenAI-shape; point it at /v1/chat/completions via the provider block in config.toml.
# ~/.codex/config.toml [provider.x402] base_url = "https://api.x402prompt.com/v1" api_key = "sk-x402-…" [model] default = "gpt-5.5-pro" provider = "x402"
Equivalent env form: OPENAI_BASE_URL=https://api.x402prompt.com/v1 + OPENAI_API_KEY=sk-x402-….
Hermes Agent.
Pick Custom endpoint in the provider menu. Base URL ends at /v1 — Hermes appends /chat/completions itself.
# ~/.hermes/config.yaml provider: custom base_url: https://api.x402prompt.com/v1 api_key: sk-x402-… model: claude-sonnet-4-6
Works for any model in the catalog, not just Claude — Hermes speaks OpenAI shape across the board.
OpenClaw.
Simplest path — set the Anthropic env vars and run:
export ANTHROPIC_BASE_URL="https://api.x402prompt.com" export ANTHROPIC_API_KEY="sk-x402-…" openclaw
Or wire it through models.json for multi-provider routing:
// ~/.openclaw/models.json
{
"providers": {
"x402": {
"type": "anthropic",
"base_url": "https://api.x402prompt.com",
"api_key": "sk-x402-…",
"models": ["claude-opus-4-7", "claude-sonnet-4-6", "claude-haiku-4-5"]
}
},
"default": "x402/claude-sonnet-4-6"
}Cursor.
- Settings → Models → Anthropic API Key — paste
sk-x402-… - Add
ANTHROPIC_BASE_URL=https://api.x402prompt.comto your system environment (macOS:~/.zshrc; Windows: System Variables). - Quit Cursor fully and relaunch — env is read once at startup.
Cursor sends both x-api-key and the Anthropic version header on its own. No further config.
Cline / Continue / Aider.
These all expose a Provider dropdown and a Custom Base URL field. Same three values:
| provider | Anthropic |
| base url | https://api.x402prompt.com |
| api key | sk-x402-… |
| model | claude-sonnet-4-6 |
Aider CLI: aider --anthropic-api-base https://api.x402prompt.com --model claude-sonnet-4-6 with ANTHROPIC_API_KEY=sk-x402-….
anthropic SDK (Python).
pip install anthropic — same code as direct, just swap the constructor:
from anthropic import Anthropic
client = Anthropic(
base_url="https://api.x402prompt.com",
api_key="sk-x402-…",
)
msg = client.messages.create(
model="claude-sonnet-4-6",
max_tokens=1024,
messages=[{"role": "user", "content": "hi"}],
)
print(msg.content[0].text)@anthropic-ai/sdk (TypeScript).
npm i @anthropic-ai/sdk — same call shape:
import Anthropic from "@anthropic-ai/sdk";
const client = new Anthropic({
baseURL: "https://api.x402prompt.com",
apiKey: "sk-x402-…",
});
const msg = await client.messages.create({
model: "claude-sonnet-4-6",
max_tokens: 1024,
messages: [{ role: "user", content: "hi" }],
});
console.log(msg.content[0].text);openai SDK (Python).
Lets you call Claude / Gemini / Grok / etc. through OpenAI's SDK — useful for existing codebases already wired to openai.
from openai import OpenAI
client = OpenAI(
base_url="https://api.x402prompt.com/v1",
api_key="sk-x402-…",
)
# any model in the catalog — not just gpt-*
resp = client.chat.completions.create(
model="claude-opus-4-7",
messages=[{"role": "user", "content": "hi"}],
max_tokens=1024,
)
print(resp.choices[0].message.content)cURL.
OpenAI shape:
curl -sX POST https://api.x402prompt.com/v1/chat/completions \
-H "Authorization: Bearer sk-x402-…" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-4-6",
"messages": [{"role":"user","content":"hi"}],
"max_tokens": 256
}'Anthropic shape:
curl -sX POST https://api.x402prompt.com/v1/messages \
-H "x-api-key: sk-x402-…" \
-H "anthropic-version: 2023-06-01" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-opus-4-7",
"max_tokens": 1024,
"messages": [{"role":"user","content":"hi"}]
}'Streaming.
Set stream: true. SSE passes through end-to-end — no buffering. Hard wall-clock cap is 240s; client disconnect cancels the upstream request and refunds the reservation delta.
with client.messages.stream(
model="claude-sonnet-4-6",
max_tokens=1024,
messages=[{"role": "user", "content": "tell me a story"}],
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)curl -NsX POST https://api.x402prompt.com/v1/chat/completions \
-H "Authorization: Bearer sk-x402-…" \
-H "Content-Type: application/json" \
-d '{"model":"claude-sonnet-4-6","stream":true,
"messages":[{"role":"user","content":"hi"}],"max_tokens":256}'Prompt caching pass-through.
cache_controlmarkers on Claude requests pass straight through to Anthropic. Cache hits bill at Anthropic's discounted rate; we don't mark up the delta.
{
"model": "claude-opus-4-7",
"max_tokens": 1024,
"system": [
{
"type": "text",
"text": "<long system prompt …>",
"cache_control": {"type": "ephemeral"}
}
],
"messages": [{"role": "user", "content": "the actual question"}]
}Spend limits + model allowlists.
At key creation in /dashboard you can set:
- spend limit — hard cap in USDC; once spend + reservation would exceed it, the gateway returns
403 spend_limit_exceeded. - model allowlist — comma-separated canonical model IDs; anything else gets
403 model_not_allowed. - revoke — flip the key to revoked and any in-flight request fails fast with
401 key_revoked.
Limits enforce before reservation, so a blocked request never debits balance.
Error codes.
| http | code | meaning |
|---|---|---|
| 401 | invalid_key | unknown or revoked api key. mint a new one. |
| 402 | insufficient_balance | top up at /topup. response carries required_micro. |
| 402 | payment_required | no auth + no payment signature. PAYG quote in PAYMENT-REQUIRED header. |
| 403 | model_not_allowed | model not in this key's allowlist. |
| 403 | spend_limit_exceeded | key's USDC cap would be crossed. |
| 429 | rate_limited | per-ip token bucket tripped. backoff + retry. |
| 5xx | upstream_* | transient upstream error. one retry, then fall through. |
Every response carries X-Request-Id. Include it when reporting issues.
Frequently asked.
Can I use the same key in both header forms?+
Authorization: Bearer sk-x402-… and x-api-key: sk-x402-… hit the same code path. Pick whichever your client defaults to — Anthropic SDK and Claude Code use the latter, OpenAI SDK and Codex use the former.What's the rate limit?+
429 with Retry-After: 1. Per-key caps are separate (spend, not rate).How do I rotate a key?+
What models are supported?+
GET /v1/models.