The quote is deliberately high
Before the model runs, the router prices the part that is predictable — your prompt and yourmax_tokens — and prices it as the worst case.
Input tokens are estimated at about 3 characters per token rather than the
usual 4, and about 90 tokens are added for system instructions the router
injects that you never see but the upstream bills for. Output is priced at the
full max_tokens you asked for, whether or not the model uses it.
Over-quoting is refunded. Under-quoting has to be collected from a later
request. Erring high is the cheaper direction to be wrong in, so that is the
direction it errs.
The hold, and the signature
The quote is held against your Circle Gateway balance, and the router signs an EIP-3009 transfer authorization on your behalf using your own embedded wallet. You submit nothing and you hold no native gas — on Arc, USDC is the gas token, and the router pays it. Authorizations are settled in batches rather than one transaction per request, which is what makes a fraction-of-a-cent request economic at all.The meter, and the refund
When the last token lands, the router meters what the request actually used: real input tokens, real output tokens, and whatever the web search provider billed. Quote minus charge is refunded to credit. Not to your wallet — to a credit balance that is netted into your next quote. So the first request on an account is charged the worst case and refunded; from the second onward you are charged approximately your true cost. Credit is withdrawable.When a turn costs more than its quote
Tool spend is the case the quote cannot cover. The router can search the web on the model’s behalf, and nothing knows whether it will until it does. A turn that lands above its quote books the difference as credit debt. It is collected on that payer’s next request, and until it is collected, it is held back from what you can withdraw. Nothing is written off.Reading the bill
Every response carriesx-nanorouter-request-id. A non-streaming response also
carries x-nanorouter-charged-usdc — a streamed one cannot, because the figure
is not known until long after the headers went out.
Read it back by id instead:
chargedUsd, refundedUsd, llmUsd and searchUsd are null until the
request settles — an in-flight row has not been metered yet, and reporting
zero there would claim a request was free when it has not finished.
llmUsd and searchUsd always sum to chargedUsd exactly. They are split
server-side so a row and the total above it can never round differently.
This endpoint authenticates with a dashboard session, not an API key — an
nr_ key there is a 401.stream: false returns x-nanorouter-charged-usdc on a fast request, but it is
dropped once a response takes longer than 45 seconds (the keepalive commits the
headers first). There is currently no dependable key-authenticated way to read a
settled cost.Why a request can be refused
429 is the exposure guard: a payer may have at most $1.00 of quoted,
unsettled requests in flight at once. It clears as requests settle, so a retry
after a moment usually succeeds. It is a solvency guard, not a rate limit —
concurrency is bounded by money at risk, not by requests per second.
All error codes
Full list, with which are worth retrying.