The router
One base URL in front of every machine-payable endpoint. Point a client at it, name a provider in the path, and the request goes where it should — paid per call from your allowance.
Base URL
One host in front of every provider. Everything below is this base plus two more path segments.
https://openspender.com/v1The route
A provider slug, then whatever path that provider expects. Nothing is rewritten, and the body is passed through untouched.
POST {base}/{provider}/{endpoint}So a Messages call to Anthropic and a search call to Exa differ only in the two segments after the base:
POST https://openspender.com/v1/anthropic/messages
POST https://openspender.com/v1/exa/searchQuickstart
The fastest start is one command — it wires Claude Code, Codex, opencode, Gemini CLI and Cursor to the MCP server in one pass, and each connection mints its own capped card at a browser consent:
npx openspender connectNo terminal, or a chat-only model? One sentence does it the long way:
Read https://openspender.com/llms.txt and set up payments.Or point an existing client at the base URL yourself. Anything that speaks the OpenAI or Anthropic wire format works unmodified.
export ANTHROPIC_BASE_URL=https://openspender.com/v1/anthropic
export ANTHROPIC_AUTH_TOKEN=$OPENSPENDER_ALLOWANCE_TOKENcurl https://openspender.com/v1/anthropic/messages \
-H "Authorization: Bearer $OPENSPENDER_ALLOWANCE_TOKEN" \
-H "content-type: application/json" \
-d '{
"model": "claude-opus-5",
"max_tokens": 1024,
"messages": [{"role": "user", "content": "hello"}]
}'from openai import OpenAI
client = OpenAI(
base_url="https://openspender.com/v1/openai",
api_key=os.environ["OPENSPENDER_ALLOWANCE_TOKEN"],
)
client.chat.completions.create(
model="gpt-5.1",
messages=[{"role": "user", "content": "hello"}],
)How a route resolves
Three ways to name a destination, tried in order. The first one that matches wins, so an explicit path always beats inference.
- 1Explicit path.
/v1/anthropic/messagesgoes to Anthropic. No ambiguity, no lookup. - 2Prefixed model landing next. Post to
/v1/chat/completionswith"model": "anthropic/claude-opus-5"and the prefix picks the provider — the OpenRouter convention. - 3Catalog lookup landing next. A bare model or service name is resolved against the indexed catalog. Ambiguous names are rejected rather than guessed.
Providers
openspender never resells inference. Each slug forwards to the provider's own machine-payable endpoint.
| Slug | Example | Forwards to | Protocol |
|---|---|---|---|
anthropic | /v1/anthropic/messages | https://anthropic.mpp.tempo.xyz/v1 | MPP |
openai | /v1/openai/chat/completions | https://openai.mpp.tempo.xyz/v1 | MPP |
exa | /v1/exa/search | https://api.exa.ai | MPP |
tavily | /v1/tavily/search | https://x402.tavily.com | x402 |
Plus every x402 service in the Bazaar catalog and every service in the MPP registry, addressable by the same grammar.
Routes
The full paid surface behind the tier-1 slugs. Every route marked live answered an unauthenticated probe with a real payment challenge on 2026-08-21 — the price shown is what the provider's own challenge quoted, not a list price.
| Route | What it does | Rail | Price | Status |
|---|---|---|---|---|
| POST /v1/anthropic/messages | Claude messages (Sonnet, Opus, Haiku) | MPP · Tempo | model-priced, from $0.001 | live |
| POST /v1/openai/chat/completions | GPT chat completions | MPP · Tempo | model-priced, from ~$0.005 | live |
| POST /v1/openai/responses | OpenAI Responses API | MPP · Tempo | model-priced | live |
| POST /v1/openai/embeddings | text embeddings | MPP · Tempo | per request | live |
| POST /v1/openai/images/generations | image generation | MPP · Tempo | per image | live |
| POST /v1/exa/search | neural web search | MPP · Tempo | $0.007 / search | live |
| POST /v1/exa/contents | page contents for result ids | MPP · Tempo | per request | live |
| POST /v1/tavily/search | web search (advanced tier) | x402 · Base | $0.01 / search | live |
Exa's /findsimilar and /answer exist upstream but answer 401 (API-key only), not a payment challenge — not machine-payable today.
MPP is bigger than single charges. The spec at mpp.dev defines extensions — sessions (metered pay-as-you-go), streaming payments over SSE, subscriptions, a native MCP binding (pay inside tool calls), WebSocket transport and relays. openspender settles single charge intents today and adopts extensions as providers ship them. The discovery surface is already wide: the mpp.dev directory lists 141 MPP services (machine-readable at mpp.dev/api/services), and the Bazaar catalog indexes the x402 long tail — both are the router's expansion path.
Payment
Providers answer an unpaid request with a challenge — 402 Payment Required for x402, a WWW-Authenticate: Payment header for MPP. openspender reads the challenge, checks it against your allowance, pays, and replays the request. Your client sees one response.
→ POST /v1/anthropic/messages (unpaid probe)
← 402 WWW-Authenticate: Payment … (provider quotes)
· policy check against your allowance
→ POST /v1/anthropic/messages (payment attached)
← 200 {"content": [...], "usage": {...}}