fetch call.
What works unchanged
Responses come back in the standard shape:
choices[].message,
finish_reason, usage, and chatcmpl--prefixed ids.
What is different
reasoning_effort defaults to low, not the model's default
reasoning_effort defaults to low, not the model's default
The upstream’s own default spends multiple seconds thinking before the first
token on even trivial prompts, and reasoning is billed as output tokens. If you
want deeper reasoning, ask for it explicitly.
max_tokens decides what you are quoted
max_tokens decides what you are quoted
The hold against your balance is priced at
max_tokens, not at what the model
writes. On OpenAI an over-large max_tokens is free; here it locks up balance
until the request settles. Name a real ceiling — the default is 8,192.Web search is on by default when you bring no tools of your own
Web search is on by default when you bring no tools of your own
The relayed models have no internet access, so the router searches for them.
If your request includes its own
tools, the router’s are not injected. To
control it explicitly, pass "web_search": false / "web_fetch": false. See
Web search.Costs arrive in headers, and settle afterwards
Costs arrive in headers, and settle afterwards
x-nanorouter-request-id on every response;
x-nanorouter-authorized-usdc for what was held;
x-nanorouter-charged-usdc for what it cost — non-streaming, and only when
the response finishes inside 45 seconds.What is not supported
These return a400 rather than being silently ignored:
n > 1— one completion per call.- Non-text content parts. Message content must be a string or an array of
{"type": "text"}parts. Images and audio are refused. - Message roles outside
system·developer·user·assistant·tool. response_formattypes other thantext,json_object,json_schema.
/v1/chat/completions and
/v1/models:
/v1/embeddings/v1/completions/v1/responses/v1/images/*,/v1/audio/*,/v1/files,/v1/batches
top_p, presence_penalty,
frequency_penalty, seed, logprobs, stop, logit_bias, user — are
accepted by the request parser but not forwarded upstream. Do not rely on them
taking effect.
Model names
There is nogpt-4o here. The catalogue is:
404 with code: "model_not_found", not a fallback. Map
your model names at the boundary rather than letting an old constant fail in
production.
GET /v1/models is public — no key needed — so you can fetch the live list at
startup.
Error handling
The error envelope is OpenAI’s, soopenai.APIError and friends work as they
do today:
402 — your USDC balance
will not cover the quote. Catch it and top up; retrying will not help.
429 here also means something different from an OpenAI rate limit: too much
of your money is already in flight, unsettled. It clears on its own as requests
settle, so a short backoff works.
Full error reference
Every status the API returns, and whether a retry is worth attempting.