POST /v1/decide
The exact contract for the Flux decision model: request and answer shapes, limits, errors, pricing and how to threshold the probabilities.
Ask typed questions about some text (and optionally images) and get a calibrated answer for each: a choice with a probability for every option, a score on a scale, or a yes/no probability. For a guided tour, see Decision mode.
Requests to the Flux decision model are processed by Cloudflare Workers AI, which acts as Flux's sub-processor and handles them under Cloudflare's own terms. Flux keeps no copy of your request or the answer; each call is billed from its input token count only.
| Endpoint | POST https://api.fluxrouter.ai/v1/decide. POST /v1/systemone is the same route under its other name. |
| Body | JSON |
| Auth | Authorization: Bearer sk-flux... on a paid plan |
| Model | flux-decide (required) |
| Streaming | No |
Only paid plans can use it. A key on a free plan, or a key limited to other models, is refused with 403 before anything is processed.
Request
| Field | Type | Required | Notes |
|---|---|---|---|
model | string | Yes | Must be exactly flux-decide. Any other id is refused with 422 model_not_supported, and so is a missing model. This includes the model id that an OpenMausBot-compatible client sends to its default vendor: when you point such a client at Flux, set its model to flux-decide. |
state | string, object or array | Yes | What the questions are about. Text is read as it is; an object or array is read as compact JSON with sorted keys. It must not be empty. At most 2,048 tokens: see The state limit. |
questions | object | Yes | Between 1 and 64 questions. Each key is a question id of letters, digits, _, . or -, up to 100 characters long. |
images | array | No | Between 1 and 4 images that the questions can refer to. Each is a data: URL or { "content_type": "image/png", "base64": "..." }. PNG, JPEG and WebP only, checked against the file's own bytes. Each image may be at most 4 MiB and all together at most 8 MiB. Links to remote images are refused. |
Other top-level fields and other question fields are ignored.
Every question has a type and non-empty instructions, then the part that depends on the type:
type | Extra field | Answer |
|---|---|---|
choice | criteria: an object of option key to a short meaning. Between 2 and 255 options. | The chosen key and a probability for every key. |
score | criteria: an array of level names. Between 2 and 10 levels. | A score between the levels, and a probability for every level. |
noul | criteria (optional): { "true": "...", "false": "..." } to say what yes and no mean. | The probability that the answer is yes. |
curl https://api.fluxrouter.ai/v1/decide \
-H "Authorization: Bearer $FLUX_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "flux-decide",
"state": "Checkout returns a 500 error since this morning.",
"questions": {
"team": {
"type": "choice",
"instructions": "Which team should handle this?",
"criteria": {
"billing": "Payments, invoices and refunds",
"technical": "Errors, bugs and outages",
"sales": "Pricing and new plans"
}
},
"urgent": { "type": "noul", "instructions": "Is this urgent?" },
"severity": {
"type": "score",
"instructions": "How severe is the problem?",
"criteria": ["minor", "moderate", "major", "critical"]
}
}
}'
Response
200 with one answer for every question you asked, under the same id:
{
"model": "flux-decide",
"answers": {
"team": {
"type": "choice",
"choice": "technical",
"probabilities": { "billing": 0.0197, "technical": 0.9728, "sales": 0.0075 },
"confidence": 0.9202
},
"urgent": { "type": "noul", "noul": 0.9279 },
"severity": {
"type": "score",
"score": 2.4414,
"probabilities": { "0": 0.0122, "1": 0.0284, "2": 0.4653, "3": 0.4941 },
"legend": { "0": "minor", "1": "moderate", "2": "major", "3": "critical" },
"confidence": 0.2822
}
},
"usage": { "input_tokens": 356 }
}
| Field | Meaning |
|---|---|
answers.<id>.choice | The chosen option key (choice questions). |
answers.<id>.score | The score (score questions). The keys of probabilities are the level positions, "0" upwards. legend maps each position to the level name you sent, when it is returned. |
answers.<id>.probabilities | One probability for each option or level. Already normalised to the four decimal places shown: use them as they are. |
answers.<id>.noul | The probability that the answer is yes (noul questions). |
answers.<id>.confidence | Optional. See the warning below. |
usage.input_tokens | The tokens billed for this call. |
Threshold on the probability, never on confidence
To decide whether to trust an answer, compare probabilities[choice] with your threshold (for a noul question, compare noul). Do not use confidence. It is not the probability of the chosen option: in the example above the chosen option has a probability of 0.9728 and a confidence of 0.9202, and the score question has a most likely level of 0.4941 against a confidence of 0.2822.
Response headers
| Header | Meaning |
|---|---|
x-flux-no-retain | applied on every response: Flux keeps no copy of the request or the answer. |
cache-control | no-store |
x-flux-alias and x-flux-routed-model | flux-decide |
x-flux-request-id | Starts with dec-. Keep it for support. |
Limits
| Limit | Value |
|---|---|
| Questions per call | 64 |
Options in a choice question | 2 to 255 |
Levels in a score question | 2 to 10 |
| Images per call | 4 |
| State length | 2,048 tokens |
| Request body | 13 MB |
The state limit
The model reads the first 2,048 tokens of the state and silently drops the rest. A long text would therefore be answered from its beginning alone, and the answer could be wrong without any sign of it. So Flux refuses instead: a state over the limit is answered with 422 state_too_long and nothing is billed. Shorten the state, or send only the part the questions are about. Images do not count toward the state limit.
Pricing
Each call is billed once, from its input tokens only, at 0.1008 USD per million input tokens. A typical decision of about 450 input tokens costs about 0.00005 USD. The same price applies on every paid plan. A call that fails is not billed.
Errors
The error body is the same on every endpoint that returns the standard shape:
{ "error": { "message": "The state is longer than 2048 tokens", "type": "invalid_request_error", "code": "state_too_long", "param": "state" } }
The message is fixed text written by Flux. It never repeats your state, instructions, option text, question ids or images. param, when present, names the request field at fault: model, state, questions, images or body.
| Status | code | Meaning | Fix |
|---|---|---|---|
401 | invalid_api_key | The key is missing or not accepted. | Check the key on your keys page. |
402 | credit_unresolved, or a credit code | Your prepaid credit or a spend cap stopped the call, or your balance could not be checked. Not charged. | See the chat error reference. Retry once if the balance could not be checked. |
403 | model_not_allowed | This key is limited to a list of models that does not include flux-decide. | Add flux-decide to the key on your keys page. |
403 | paid_plan_required | The plan or the key cannot use decision mode. | Upgrade in Billing. |
404 | not_found | Decision mode is not switched on. | Contact support. |
413 | request_too_large | The body is over the limit above. | Send less, or fewer images. |
422 | invalid_request | The body does not match the request shape. param says which field. | Fix the request. |
422 | model_not_supported | model is missing, or is not flux-decide. | Send "model": "flux-decide". |
422 | state_too_long | The state is over the limit. Not charged. | See The state limit. |
422 | upstream_rejected | The decision model refused the request, for example because of an image it could not read. Not charged. | Check the images and the questions. |
429 | rate_limit_exceeded | Your account is sending decisions too fast. Retry-After says when to try again. | Wait, then retry. |
529 | upstream_overloaded | The decision model is at capacity. Not charged. | Retry shortly, with backoff. |
503 | upstream_unavailable | The decision model did not answer in time or could not be reached. Not charged. | Retry shortly, with backoff. |
503 | capability_unavailable | Decision mode is temporarily unavailable. Not charged. | Retry later. |
A 403 means this key or plan cannot use decision mode; a 402 means a money check stopped the call. Every code is also in the error reference.