Second opinion: have an answer checked
Ask Flux to check a single-turn flux-auto answer with flux_verify. It never runs on tool-calling or agent-loop turns, which are served normally and not charged.
It does not run on tool-calling or agent-loop turns. A request that carries tools, or that is one step inside an agent's loop, is served as a normal
flux-autoanswer. Nothing is checked and nothing extra is charged, and no error tells you so. Inside coding agents such as Claude Code, Codex and Cursor, almost every turn carries tools, soflux_verifydoes nothing there. Use it from your own code, on single questions. See When it does not run.
Status: Rolling out
Sometimes an answer matters enough to spend a little more on it. On a single-turn flux-auto request with no tools, set flux_verify: true and Flux checks the answer before you get it. It scores the answer against a fixed set of checks for that kind of task. If the answer falls short, it runs the task again on other models until one passes or the budget runs out. You pay for the extra attempts, up to a fixed ceiling per request, and the response carries a receipt of what happened.
It is opt-in and per request: Flux never charges for a check you did not ask for.
How to opt in
Send a single-turn flux-auto request to POST /v1/chat/completions, with no tools, and opt in any one of three ways:
- A body field:
"flux_verify": truenext tomodelandmessages. - Metadata:
"metadata": { "flux_verify": true }. - A header:
X-Flux-Verify: true.
curl -i https://api.fluxrouter.ai/v1/chat/completions \
-H "Authorization: Bearer sk-YOUR-FLUX-KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "flux-auto",
"flux_verify": true,
"messages": [
{ "role": "user", "content": "Write the SQL to keep only the newest row per email in the users table." }
]
}'
import requests
resp = requests.post(
"https://api.fluxrouter.ai/v1/chat/completions",
headers={"Authorization": "Bearer sk-YOUR-FLUX-KEY"},
json={
"model": "flux-auto",
"flux_verify": True, # single turn, no tools
"messages": [
{
"role": "user",
"content": "Write the SQL to keep only the newest row per email in the users table.",
}
],
},
)
resp.raise_for_status()
body = resp.json()
print(body["choices"][0]["message"]["content"])
receipt = body.get("flux", {})
print("Stamp:", receipt.get("stamp"), "Attempts:", receipt.get("attempts"))
print("Charged (USD):", resp.headers.get("x-flux-customer-charge-usd"))
const resp = await fetch('https://api.fluxrouter.ai/v1/chat/completions', {
method: 'POST',
headers: {
Authorization: 'Bearer sk-YOUR-FLUX-KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
model: 'flux-auto',
flux_verify: true, // single turn, no tools
messages: [
{
role: 'user',
content:
'Write the SQL to keep only the newest row per email in the users table.',
},
],
}),
});
if (!resp.ok) throw new Error(await resp.text());
const body = await resp.json();
console.log(body.choices[0].message.content);
console.log('Stamp:', body.flux?.stamp, 'Attempts:', body.flux?.attempts);
console.log('Charged (USD):', resp.headers.get('x-flux-customer-charge-usd'));
Streaming works too. With "stream": true, the stream stays open while the check runs, then sends the checked answer.
When it does not run
These requests get the normal flux-auto answer, with no check and no extra charge:
- Tool-calling turns. Any request with
tools. A tool-calling turn is one step inside a larger job, so Flux does not check it. - Agent-loop turns. A request that an outer agent loop has marked as its own (a
loop_ownermarker). - Multi-turn conversations, except an "are you sure?" follow-up to the previous answer.
- Pinned models and tier models.
flux_verifyapplies toflux-autoonly. A pinned model, orflux-fast,flux-standardorflux-reasoning, serves exactly what you asked for.
Nothing in the response says the check was skipped, except that the receipt fields below are missing. If you expected a check and see no flux object, one of these is why. See Second opinion did not run.
There is no account-level switch. The flag is read on each request, so nothing changes for traffic that does not set it.
What happens on an opted-in request
- Flux serves the request through normal routing.
- The answer is scored against a fixed set of checks for the kind of task it is.
- If the answer passes, you get it back straight away with the receipt, often at no extra cost.
- If it falls short, Flux runs the task again on other models from a fixed pool, checks each attempt, and keeps the best one.
If the budget runs out first, you get the best attempt, and the receipt says so. Two cases return an error instead:
413when the input alone would cost more than the ceiling.503when too many checks are running at once. Retry after theRetry-Afterdelay, or dropflux_verify.
The receipt
An opted-in response carries a flux object in the body and matching lowercase x-flux-* headers:
| Field | Header | Meaning |
|---|---|---|
stamp | x-flux-stamp | checked when the returned answer passed every check; otherwise unset |
checks_passed / checks_total | x-flux-checks-passed / x-flux-checks-total | How many checks the returned answer passed |
attempts | x-flux-attempts | How many attempts it took |
elevated_reason | x-flux-elevated-reason | What happened, such as probe_passed (the first answer passed) or climbed_to_green (a later attempt passed) |
customer_charge_usd | x-flux-customer-charge-usd | What you paid for this request, check included |
est_frontier_usd | x-flux-est-frontier-usd | For information: what the same tokens would cost at frontier rates |
models_used | x-flux-models-used | The models the check ran on |
stamp: "checked" means one thing only: the returned answer passed every check in the set. It is not a promise that the answer is true. If no attempt passed within budget, the stamp stays unset and elevated_reason says the check was best effort.
See Receipts for the x-flux-* headers on every response.
What it costs
The check is charged to you as a surcharge on the request, and each request has a fixed ceiling: Flux stops before an attempt that would cross it, however many attempts that leaves. customer_charge_usd in the receipt is the settled amount, and it lands on your bill like any other request. If the first answer passes, there is nothing more to run and usually nothing extra to pay.
- Ceiling per request: priced per call.
- What you paid:
customer_charge_usdin each receipt, always.
The suggestion header
When you have not opted in but your request reads as if you want a checked answer (for example "are you sure?" or "this must be exactly right"), Flux adds one response header:
x-flux-verify-available: true
Nothing about the response changes and nothing extra is charged. It is a hint that sending the request again with flux_verify: true would run the check. Your own code can watch for this header and decide, per task, whether the answer is worth checking.