> ## Documentation Index
> Fetch the complete documentation index at: https://docs.flexinference.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Decision Models

A decision model answers questions about an input with probabilities. It writes no text. You send the input and named questions, and you get one answer back per question.

## Two endpoints

* `POST /v1/decisions` takes OpenAI's Decisions format.
* `POST /v1/systemone` takes the System One format, which Microsoft and Cloudflare use.

Any decision model works on either endpoint. When the model speaks the other format, we translate your request and its answer. The answer always comes back in the format of the endpoint you called.

## The models

| Model | Routes | Native format | Questions per request |
| - | - | - | - |
| `gpt-6-luna` | `openai`, `foundry` | Decisions | 1 to 400 |
| `microsoft-decision-1` | `foundry` | System One | No stated limit |
| `clef` | `cloudflare` | System One | 1 to 64 |
| `clef-flash` | `cloudflare` | System One | 1 to 64 |

`GET /v1/models` marks each one with a `decisions` block. It lists the routes, the question limit, and the price on each route.

`gpt-6-luna` is also a text model, so it keeps serving the text endpoints. The other three write no text, so a text endpoint refuses them with `400 model_surface_mismatch`. A text model sent to a decision endpoint gets the same error.

## Your own keys only

Decision models run on the provider keys you add in the dashboard.

* `openai` uses your OpenAI key.
* `foundry` uses your Azure AI Foundry key and resource.
* `cloudflare` uses your Workers AI token and account ID.

If your organization serves a route on managed keys, a decision request for that route returns `400 decisions_byok_only`. A missing key returns that route's own error, such as `400 no_foundry_key`.

On Foundry, the `model` field names a deployment, and we send the model ID you used. Name the deployment after the model: `gpt-6-luna` or `microsoft-decision-1`.

## No Flex Race

Decision requests never race. OpenAI's Decisions API refuses a flex tier, and System One has no tiers at all.

* Send `"start_within": "default"` in the body, or `x-start-within: default` as a header.
* A duration returns `400 flex_model_not_capable`.
* `priority` or `auto` returns `400 tier_unsupported_on_decisions`.
* An API key with a deadline default works. Its fallback tier applies.

`x-flexinference-routing-reason` reads `tier_direct`, or `chain_advanced` when a backup served. Name backups in `provider`, the same as on the text endpoints. A route that answers `429`, `5xx`, or no connection passes the request to the next one.

Neither endpoint streams. `"stream": true` returns `400 unsupported_parameter`.

## OpenAI's Decisions format

```bash theme={null}
curl https://api.flexinference.com/v1/decisions \
  -H "Authorization: Bearer $FLEX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-6-luna",
    "start_within": "default",
    "input": "I was charged twice for my subscription and want a refund.",
    "questions": [
      { "type": "predicate", "name": "billing", "instructions": "Is this about billing?" },
      {
        "type": "choice",
        "name": "team",
        "instructions": "Which team should handle this?",
        "choices": [
          { "value": "billing", "description": "Payments and refunds" },
          { "value": "tech", "description": "Bugs and outages" }
        ]
      }
    ]
  }'
```

The answer looks like this:

```json theme={null}
{
  "model": "gpt-6-luna",
  "answers": [
    { "type": "predicate", "name": "billing", "probability": 1.0 },
    {
      "type": "choice",
      "name": "team",
      "choice": "billing",
      "probabilities": [
        { "value": "billing", "probability": 1.0 },
        { "value": "tech", "probability": 0.0 }
      ],
      "confidence": 1.0
    }
  ],
  "usage": { "input_tokens": 161, "output_tokens": 0, "total_tokens": 161 }
}
```

## The System One format

```bash theme={null}
curl https://api.flexinference.com/v1/systemone \
  -H "Authorization: Bearer $FLEX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "clef",
    "start_within": "default",
    "state": "Checkout is down for all EU customers since 09:00.",
    "questions": {
      "outage": { "type": "noul", "instructions": "Is this an outage?" },
      "severity": {
        "type": "score",
        "instructions": "How severe is this?",
        "criteria": ["Cosmetic", "Minor", "Major", "Critical"]
      }
    }
  }'
```

The answer looks like this:

```json theme={null}
{
  "model": "clef",
  "answers": {
    "outage": { "type": "noul", "noul": 0.98 },
    "severity": {
      "type": "score",
      "score": 2.7,
      "legend": {
        "0": "Cosmetic",
        "1": "Minor",
        "2": "Major",
        "3": "Critical"
      },
      "probabilities": { "0": 0.01, "1": 0.04, "2": 0.2, "3": 0.75 },
      "confidence": 0.6
    }
  },
  "usage": { "input_tokens": 120, "output_tokens": 0 }
}
```

A score is the probability-weighted level, so it can land between two levels.

## How we translate

* A noul is a predicate. Its answer is a probability in both formats.
* A choice's `criteria` object becomes `choices`, one `value` per label.
* A score's `criteria` list becomes `levels`. Each level's label is its position, `"0"`, `"1"`, and so on, the same key the answer's `legend` and `probabilities` use.
* System One names each question with its key. OpenAI names it with `name` and answers in a list, in question order.
* A noul's true and false `criteria` have no OpenAI field, so we add them to the instructions.
* A System One question with no `instructions` gets one for its type, such as "Which option best fits the state?". OpenAI requires instructions.
* Structured state becomes one `input_json` part. OpenAI's text and JSON parts join into one state string, and a single JSON part stays structured.
* An OpenAI level becomes `"label: description"` in System One.
* OpenAI can refuse to answer a question. On `/v1/systemone` that answer is `{ "type": "refusal" }` under the question's name.
* For a System One model we drop `safety_identifier` and the three prompt-cache fields. None of them changes an answer.

We refuse a request that can't be translated with `400 decision_translation_unsupported`, before we call the provider.

* Images. Send them in the model's own format: `input_image` parts for `gpt-6-luna` on `/v1/decisions`, or `images` for `clef` on `/v1/systemone`.
* A field the other format has no place for.
* A choice with one option, or a score with one level, for an OpenAI model. OpenAI needs at least two.
* More than 255 options for a System One model.

When the request and the model share a format, we forward your body as you wrote it, minus our own fields: `start_within`, `provider`, `stream`, and `include_cost`. The answer is the provider's own body.

## What we check first

`400 invalid_decision_request` names the field that breaks a rule of its format:

* `input` or `state` is missing.
* A question count is outside the model's range.
* Two questions share a name.
* A choice offers `true` and `"true"` as two options.
* The body nests deeper than 64 levels, or holds a number JSON can't carry.

## Cost

Decision models bill input tokens only.

* `gpt-6-luna` on `openai`: $0.10 per million input tokens. Cache reads bill at $0.01 and cache writes at \$0.125. All three double above 272,000 input tokens. We report the cost in `x-flexinference-cost`.
* `clef` costs $0.24 and `clef-flash` $0.038 per million input tokens on Cloudflare's price list. A serve on your own Cloudflare account carries no cost header, the same as every cloud route.
* Microsoft publishes no rate for either Foundry model yet, so a Foundry serve carries no cost header.

A translated answer also carries `usage.cost` and `usage.routing` in its body. A same-format answer is the provider's own body, so it reports cost on the header only.

Errors on `/v1/systemone` come back as `{ "detail": "...", "param": ..., "flexinference": { ... } }`, where `param` names the field at fault. See [Errors](https://docs.flexinference.com/errors.md) for every code.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.