> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.mixlayer.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.mixlayer.com/_mcp/server.

# Decisions

> Classify, route, and score content with TypeSafe-compatible SystemOne and OpenAI-compatible Decisions

Decisions evaluate content against questions you define and return typed answers:
a probability that a condition holds, a choice from your options, or a score on
an ordered rubric. Use them when your application needs a judgment it can act on
directly, such as assigning a category or prioritizing a record.

Mixlayer exposes two decision endpoints. Both accept a classification model and
multiple independent questions about shared content; neither generates output
text.

## Common use cases

* **Routing:** select a handler, queue, or workflow from a fixed set of options.
* **Filtering:** estimate whether a document meets a condition before processing it.
* **Prioritization:** score records against an explicit urgency or relevance rubric.
* **Content review:** evaluate separate policy conditions and combine the answers
  in your application's logic.

## Choose an endpoint

|                 | TypeSafe-compatible SystemOne                           | OpenAI-compatible Decisions                                             |
| --------------- | ------------------------------------------------------- | ----------------------------------------------------------------------- |
| Endpoint        | `POST /v1/systemone`                                    | `POST /v1/decisions`                                                    |
| Shared content  | `state`: text, a JSON object, or a JSON array           | `input`: text or an array of user messages                              |
| Questions       | Object keyed by your question IDs                       | Ordered array with optional `name` fields                               |
| Yes/no question | `noul`                                                  | `predicate`                                                             |
| Choice options  | `criteria`: object mapping option names to descriptions | `choices`: array of string or boolean values with optional descriptions |
| Score rubric    | `criteria`: ordered array of level descriptions         | `levels`: ordered array of labels with optional descriptions            |
| Answers         | Object with the same question IDs                       | Array in request question order                                         |

Choose SystemOne for compatibility with the
[TypeSafe System One API](https://docs.typesafe.ai/api), supplying structured
records and retrieving answers by key. Choose Decisions when integrating with the
[OpenAI Decisions request and response format](https://developers.openai.com/api/reference/resources/decisions/methods/create).
Compatibility describes the format; Mixlayer's accepted inputs, limits, and
scoring behavior are documented below.

## Select a model

Use a **classification model** available to your organization. A generation or
embedding model is not a substitute. Check the [Mixlayer console](https://console.mixlayer.com)
or your organization's [model list](/api-reference/platform-api/organizations/list-models)
for identifiers and model kinds.

The examples use `mixlayer/jini-qwen3.8-27b` as the classification model and
`$MIXLAYER_API_KEY` for an [API key](/api-keys) with `inference` permission.
Set the API key environment variable before running the requests.

## SystemOne

Mixlayer's SystemOne endpoint uses the same request and response format as
TypeSafe's System One API. Use the Mixlayer endpoint, API key, and model
identifier shown below with your existing SystemOne request structure.

### Send state and keyed questions

All three top-level fields, `model`, `state`, and `questions`, are required.
Each question needs `type` and `instructions`. This request evaluates a
delivery note for missing items, routing, and urgency:

```bash
curl https://mixlayer.ai/v1/systemone \
  -H "Authorization: Bearer $MIXLAYER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "model": "mixlayer/jini-qwen3.8-27b",
  "state": {
    "delivery_note": "Received 9 of the 12 cable kits listed on the packing slip. We need the remaining kits before Friday."
  },
  "questions": {
    "missing_items": {
      "type": "noul",
      "instructions": "Does the delivery note report fewer items received than expected?",
      "criteria": {
        "true": "The received quantity is lower than the expected quantity.",
        "false": "No quantity shortfall is reported."
      }
    },
    "route": {
      "type": "choice",
      "instructions": "Which queue best matches the delivery note?",
      "criteria": {
        "inventory": "Missing items or incorrect quantities.",
        "shipping": "Transit delays or tracking questions.",
        "other": "Anything outside these categories."
      }
    },
    "urgency": {
      "type": "score",
      "instructions": "How urgent is resolving the issue?",
      "criteria": [
        "Routine: no deadline or operational impact is stated.",
        "Time-sensitive: a deadline is stated, but operations can continue.",
        "Critical: operations are already stopped."
      ]
    }
  }
}'
```

`state` accepts a string, object, or array. Top-level numbers, booleans, and
`null` are rejected. `instructions` and rubric descriptions can themselves be
text, objects, arrays, or `null`; use clear text descriptions to start.

### Read the answers

Answers use the same IDs as the request. An illustrative response is shown below;
probabilities and token counts will vary:

```json
{
  "model": "mixlayer/jini-qwen3.8-27b",
  "answers": {
    "missing_items": {"type": "noul", "noul": 0.95},
    "route": {
      "type": "choice",
      "choice": "inventory",
      "probabilities": {"inventory": 0.7, "shipping": 0.2, "other": 0.1},
      "confidence": 0.55
    },
    "urgency": {
      "type": "score",
      "score": 1.0,
      "legend": {
        "0": "Routine: no deadline or operational impact is stated.",
        "1": "Time-sensitive: a deadline is stated, but operations can continue.",
        "2": "Critical: operations are already stopped."
      },
      "probabilities": {"0": 0.1, "1": 0.8, "2": 0.1},
      "confidence": 0.7
    }
  },
  "usage": {"input_tokens": 180, "output_tokens": 0}
}
```

* **Noul:** `noul` is the conditional probability of yes versus no, from 0 to 1.
  It is a number, not a boolean.
* **Choice:** `choice` is the highest-probability option name. `probabilities`
  maps every option name to a probability and sums to one.
* **Score:** `score` is the probability-weighted average of zero-based level
  indices. `legend` maps those indices to rendered descriptions, and
  `probabilities` uses string keys such as `"0"` and `"1"`.

See the [SystemOne API reference](/api-reference/inference-ap-is/decisions/systemone)
for the full schema.

## OpenAI-compatible Decisions

### Send input and ordered questions

The required fields are `model`, `input`, and `questions`. Here is the same
delivery-note task using the Decisions format:

```bash
curl https://mixlayer.ai/v1/decisions \
  -H "Authorization: Bearer $MIXLAYER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "model": "mixlayer/jini-qwen3.8-27b",
  "input": "Received 9 of the 12 cable kits listed on the packing slip. We need the remaining kits before Friday.",
  "questions": [
    {
      "type": "predicate",
      "name": "missing_items",
      "instructions": "Does the delivery note report fewer items received than expected?"
    },
    {
      "type": "choice",
      "name": "route",
      "instructions": "Which queue best matches the delivery note?",
      "choices": [
        {"value": "inventory", "description": "Missing items or incorrect quantities."},
        {"value": "shipping", "description": "Transit delays or tracking questions."},
        {"value": "other", "description": "Anything outside these categories."}
      ]
    },
    {
      "type": "score",
      "name": "urgency",
      "instructions": "How urgent is resolving the issue?",
      "levels": [
        {"label": "Routine", "description": "No deadline or operational impact is stated."},
        {"label": "Time-sensitive", "description": "A deadline is stated, but operations can continue."},
        {"label": "Critical", "description": "Operations are already stopped."}
      ]
    }
  ]
}'
```

`name` identifies an answer for your code and is echoed in the response. Omit it
to receive `name: null`. Put the complete evaluation instruction in
`instructions`; naming a question does not change its scoring.

### Read the answers

The `answers` array preserves question order. An illustrative response:

```json
{
  "model": "mixlayer/jini-qwen3.8-27b",
  "answers": [
    {"type": "predicate", "name": "missing_items", "probability": 0.95},
    {
      "type": "choice",
      "name": "route",
      "choice": "inventory",
      "probabilities": [
        {"value": "inventory", "probability": 0.7},
        {"value": "shipping", "probability": 0.2},
        {"value": "other", "probability": 0.1}
      ],
      "confidence": 0.55
    },
    {
      "type": "score",
      "name": "urgency",
      "score": 1.0,
      "probabilities": [
        {"value": 0, "label": "Routine", "probability": 0.1},
        {"value": 1, "label": "Time-sensitive", "probability": 0.8},
        {"value": 2, "label": "Critical", "probability": 0.1}
      ],
      "confidence": 0.7
    }
  ],
  "usage": {
    "input_tokens": 180,
    "input_tokens_details": {"cached_tokens": 0, "cache_write_tokens": 0},
    "output_tokens": 0,
    "output_tokens_details": {"reasoning_tokens": 0},
    "total_tokens": 180
  }
}
```

Predicates return `probability` rather than SystemOne's `noul`. Choice
probabilities preserve request option order, and the winning `choice` preserves
its original JSON type: boolean `true` and string `"true"` are different values.
Score probabilities preserve level order and include each level's label and
zero-based index. Labels do not need to be unique.

### User-message input

Instead of a string, `input` can be an array of messages with `role: "user"`.
Each message's `content` can be text or an array of `input_text` parts:

```json
{
  "input": [
    {
      "role": "user",
      "content": [
        {"type": "input_text", "text": "Expected quantity: 12 cable kits. "},
        {"type": "input_text", "text": "Received quantity: 9 cable kits."}
      ]
    }
  ]
}
```

This is an input-field example; include `model` and `questions` in the full
request. Parts within a message are concatenated without added separators;
separate messages are joined with two newlines. Add spaces or newlines to parts
where needed. Only user messages are supported. Images, files, audio, other
roles, and item references are rejected.

See the [Decisions API reference](/api-reference/inference-ap-is/decisions/create-decision)
for the full schema.

## Interpret probabilities and scores

Questions are evaluated independently against the shared content. One question
does not see another question's answer. Combine independent results in your
code; use a later request if a question depends on an earlier result.

Score levels start at **0**, not 1. For three levels, a score is between 0 and 2
and can be fractional. Probabilities of 0.1, 0.8, and 0.1 yield
`0 × 0.1 + 1 × 0.8 + 2 × 0.1 = 1.0`. Use Choice when you need a single category.

Mixlayer's Decisions endpoint scores choices and levels independently, then
normalizes conditional yes probabilities in log space. Choice `confidence`
measures the winning probability above a uniform baseline, rescaled to 0–1.
Score `confidence` measures concentration around the most probable level
relative to uniform spread.

> **Info**
>
> Probabilities and confidence are not calibrated guarantees of correctness.
> Set thresholds using labeled examples from your own workload. The Decisions
> schema includes a `refusal` answer for compatibility, but the current scorer
> does not produce refusals; refusal detection is not implemented.

## Limits and usage

| Limit                    | Both endpoints                                                                                        |
| ------------------------ | ----------------------------------------------------------------------------------------------------- |
| JSON request body        | 8 MiB                                                                                                 |
| Shared content           | Nonempty rendered SystemOne state or nonblank combined Decisions input; at most 4 MiB                 |
| Questions                | 1–4,096 per request                                                                                   |
| Expanded binary branches | At most 4,096 across all questions                                                                    |
| Expanded question size   | At most 16 KiB per expanded question; SystemOne expanded questions must also be nonempty              |
| Choice options           | 1–255; SystemOne option names must be nonblank, Decisions values must be distinct strings or booleans |
| Score levels             | 2–10                                                                                                  |
| Model identifier         | Nonblank and at most 256 UTF-8 bytes                                                                  |

A Noul or Predicate question uses one branch. Each Choice option and each Score
level uses a separate branch. The examples above use seven branches: one yes/no
question, three choices, and three score levels. SystemOne question IDs must
also be nonblank and at most 256 UTF-8 bytes.

Both endpoints count the shared input prefix once plus the input suffix for
every scoring branch. `output_tokens` is always zero. Decisions also returns
`total_tokens`, equal to `input_tokens`, and token-detail fields that currently
report zero cache and reasoning tokens. It does not return `compute_units`.
See [Pricing](/pricing) for model rates.

Unknown request fields are rejected. Generation settings such as `temperature`,
`max_tokens`, and `stream` are not accepted. Decisions accepts
`safety_identifier` for compatibility but ignores it; authentication comes from
your bearer token.

Invalid request shapes, unsupported input, and exceeded validation limits return
`422`. Rate limits return `429`; unavailable classification capacity or an
exceeded classification deadline can return `529`. Error bodies use
`error.code` and `error.message`. See [Credits & Limits](/credits-and-limits) for
general limits and retry guidance.

## Best practices

* **Define one judgment per question.** Keep evidence in `state` or `input`, and
  describe the evaluation in `instructions` and the rubric.
* **Use explicit options and levels.** Give each category a distinct meaning;
  include an `other` option when your categories do not cover all inputs.
* **Group independent questions.** Share the evidence in one request and stay
  within the total branch limit, which can be reached before the question limit.
* **Check the distribution.** A winning choice alone hides ambiguous results.
  Use probabilities and confidence to decide when to route for review.
* **Evaluate before automating.** Test your rubrics and thresholds on
  representative examples, including unclear cases and missing information.