Skip to content

FAQ

Is Routeweiler non-custodial?

Yes. Keys never leave your process. Routeweiler never:

  • Proxies payments through a Routeweiler server.
  • Stores or transmits private keys.
  • Holds funds on your behalf.
  • Requires a Routeweiler account.

All signing happens locally in your Python process. The only data that leaves is the signed payment header sent directly to the server you're calling. This design keeps Routeweiler outside money-transmitter (FinCEN) and CASP (EU MiCA) regulatory scope.

Does Routeweiler work with any 402-capable API?

Yes, as long as the API uses one of the four supported rails:

Rail Wire format
x402 PAYMENT-REQUIRED: <base64 JSON>
L402 WWW-Authenticate: L402 macaroon="...", invoice="..."
MPP-Tempo WWW-Authenticate: Payment method="tempo", ...
MPP-SPT WWW-Authenticate: Payment method="stripe", ...

If the server returns a 402 with none of these formats, Routeweiler raises RailNotSupportedError.

What currencies are supported?

Rail Currency
x402 USDC, EURC on Base, Polygon, Arbitrum, World, Solana
L402 Sats (Bitcoin)
MPP-Tempo PathUSD, USDC on Tempo L2
MPP-SPT Any currency Stripe supports (usd, eur, etc.)

For budget enforcement, FMV conversion to usd, eur, gbp, or jpy is handled automatically via CoinGecko (crypto→USD) and ECB cross-rates (USD→other fiat). USDC and other dollar-pegged stablecoins use the stablecoin_peg quality (1:1).

Does Routeweiler require an internet connection?

For payments, yes — it needs to reach the API server. For FMV conversion (budget enforcement), it calls CoinGecko and ECB, both rate-limited and cached locally. All other operations (signing, policy evaluation, SQLite trace writes) are offline.

Can I use Routeweiler in a multi-threaded environment?

Routeweiler is fully async and designed for asyncio. Each async with Routeweiler(...) instance has its own connection pool and budget store. Use one instance per async task or pass agent_id and session_id to distinguish sessions sharing a single client.

Do not share a single Routeweiler instance across threads without an event loop.

What happens if payment fails mid-flow?

Routeweiler distinguishes pre-commit and post-commit failures:

  • Pre-commit (signing failed, budget exceeded, policy denied): no payment was attempted; the original 402 response is raised as an exception.
  • Post-commit (PostCommitPaymentError): the signed transaction was submitted and may have landed on-chain, but the server returned an error. Check the trace for the proofValue field to find the tx hash and investigate the on-chain state.

For L402, the preimage is the proof — if InvoicePaymentError is raised, the invoice was not paid. For x402, a PostCommitPaymentError means the ERC-3009 transaction may have been submitted; check the trace and Basescan.

Does Routeweiler support retries on non-402 failures?

No. Routeweiler only intercepts 402 Payment Required responses and handles the payment flow on retry. Network errors, 5xx responses, and other non-402 failures propagate as normal httpx exceptions. Add your own retry logic around client.get(url).

What is the SQLite database used for?

Three things share the same SQLite file:

  1. Trace events — one row per HTTP call (trace_events table).
  2. Budget draws — one row per draw attempt (draws table).
  3. Credentials — credential state machine for split-URL recovery (credentials table).

Pass trace_sink=TraceSink.sqlite("rw.db") to enable all three. Without a trace_sink, nothing is written to disk.

What license is Routeweiler under?

Apache 2.0. Free to use in commercial products.

How do I report a bug or request a feature?

Open an issue at github.com/nikoSchoinas/routeweiler-python-sdk/issues.

Contact

schoinas.nkls@gmail.com