Example: Multi-Upstream Gateway
A single tollbooth instance that routes to multiple backend APIs, each with its own pricing. One gateway, many upstreams.
Use case
Section titled “Use case”You aggregate several third-party APIs behind one paid gateway. Each upstream has different costs and value, so you price them independently. Clients hit a single domain and pay per-request — tollbooth handles routing, auth injection, and payment for all of them.
Config
Section titled “Config”gateway: port: 3000 discovery: true
wallets: base: "0xYourWalletAddress"
accepts: - asset: USDC network: base
upstreams: weather: url: "https://api.weatherapi.com/v1" headers: key: "${WEATHER_API_KEY}"
geocoding: url: "https://api.mapbox.com" headers: access_token: "${MAPBOX_TOKEN}"
ai: url: "https://api.openai.com" headers: authorization: "Bearer ${OPENAI_API_KEY}"
routes: # Cheap data endpoint "GET /weather/:city": upstream: weather path: "/current.json?q=${params.city}" price: "$0.005"
# Mid-tier geocoding "GET /geocode/:query": upstream: geocoding path: "/geocoding/v5/mapbox.places/${params.query}.json" price: "$0.01"
# Expensive AI — priced by model "POST /v1/chat/completions": upstream: ai type: token-based models: gpt-4o: "$0.05" gpt-4o-mini: "$0.005" fallback: "$0.01"What’s going on
Section titled “What’s going on”- Three upstreams — weather, geocoding, and AI — each with their own base URL and auth headers.
- Path-based routing sends requests to the right backend based on the public URL path.
- Independent pricing — weather is cheap ($0.005), geocoding is mid-tier ($0.01), AI uses per-model pricing via
type: token-based. - Path rewriting — each route maps the public-facing path to the upstream’s actual API format.
- One wallet collects payments from all routes.
Run it
Section titled “Run it”export WEATHER_API_KEY="..."export MAPBOX_TOKEN="..."export OPENAI_API_KEY="sk-..."npx tollbooth startExpected flow
Section titled “Expected flow”Client Tollbooth Upstreams │ │ │ │ GET /weather/london │ │ │─────────────────────────────>│ │ │ │ route → weather upstream │ │ │ price: $0.005 │ │ 402 + payment instructions │ │ │<─────────────────────────────│ │ │ │ │ │ (sign $0.005 USDC) │ │ │ │ │ │ GET /weather/london │ │ │ + payment-signature header │ │ │─────────────────────────────>│ │ │ │ GET /current.json?q=london │ │ │───────────────────────────> Weather API │ │ │ │ │ { temp: 12, ... } │ │ │<─────────────────────────── │ │ 200 + weather data │ │ │<─────────────────────────────│ │ │ │ │ ├──────────────────────────────┤ │ │ │ │ │ POST /v1/chat/completions │ │ │ { model: "gpt-4o" } │ │ │─────────────────────────────>│ │ │ │ route → ai upstream │ │ │ model: gpt-4o → $0.05 │ │ 402 + payment instructions │ │ │<─────────────────────────────│ │ │ │ │ │ ...pay and get response... │ │Try it with curl
Section titled “Try it with curl”# Weather — cheapcurl -s http://localhost:3000/weather/london
# Geocoding — mid-tiercurl -s http://localhost:3000/geocode/tokyo
# AI — model-based pricingcurl -s http://localhost:3000/v1/chat/completions \ -X POST \ -H "Content-Type: application/json" \ -d '{"model":"gpt-4o-mini","messages":[{"role":"user","content":"Hi"}]}'Each request returns a 402 with a price matching that route’s configuration. An x402-compatible client handles payment automatically.