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.

EndpointPOST https://api.fluxrouter.ai/v1/decide. POST /v1/systemone is the same route under its other name.
BodyJSON
AuthAuthorization: Bearer sk-flux... on a paid plan
Modelflux-decide (required)
StreamingNo

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

FieldTypeRequiredNotes
modelstringYesMust 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.
statestring, object or arrayYesWhat 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.
questionsobjectYesBetween 1 and 64 questions. Each key is a question id of letters, digits, _, . or -, up to 100 characters long.
imagesarrayNoBetween 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:

typeExtra fieldAnswer
choicecriteria: an object of option key to a short meaning. Between 2 and 255 options.The chosen key and a probability for every key.
scorecriteria: an array of level names. Between 2 and 10 levels.A score between the levels, and a probability for every level.
noulcriteria (optional): { "true": "...", "false": "..." } to say what yes and no mean.The probability that the answer is yes.
bash
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:

json
{
  "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 }
}
FieldMeaning
answers.<id>.choiceThe chosen option key (choice questions).
answers.<id>.scoreThe 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>.probabilitiesOne probability for each option or level. Already normalised to the four decimal places shown: use them as they are.
answers.<id>.noulThe probability that the answer is yes (noul questions).
answers.<id>.confidenceOptional. See the warning below.
usage.input_tokensThe 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

HeaderMeaning
x-flux-no-retainapplied on every response: Flux keeps no copy of the request or the answer.
cache-controlno-store
x-flux-alias and x-flux-routed-modelflux-decide
x-flux-request-idStarts with dec-. Keep it for support.

Limits

LimitValue
Questions per call64
Options in a choice question2 to 255
Levels in a score question2 to 10
Images per call4
State length2,048 tokens
Request body13 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:

json
{ "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.

StatuscodeMeaningFix
401invalid_api_keyThe key is missing or not accepted.Check the key on your keys page.
402credit_unresolved, or a credit codeYour 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.
403model_not_allowedThis key is limited to a list of models that does not include flux-decide.Add flux-decide to the key on your keys page.
403paid_plan_requiredThe plan or the key cannot use decision mode.Upgrade in Billing.
404not_foundDecision mode is not switched on.Contact support.
413request_too_largeThe body is over the limit above.Send less, or fewer images.
422invalid_requestThe body does not match the request shape. param says which field.Fix the request.
422model_not_supportedmodel is missing, or is not flux-decide.Send "model": "flux-decide".
422state_too_longThe state is over the limit. Not charged.See The state limit.
422upstream_rejectedThe decision model refused the request, for example because of an image it could not read. Not charged.Check the images and the questions.
429rate_limit_exceededYour account is sending decisions too fast. Retry-After says when to try again.Wait, then retry.
529upstream_overloadedThe decision model is at capacity. Not charged.Retry shortly, with backoff.
503upstream_unavailableThe decision model did not answer in time or could not be reached. Not charged.Retry shortly, with backoff.
503capability_unavailableDecision 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.