---
title: Decisions
description: The POST /v1/systemone call — a state and questions in, answers as probabilities out, and what the call costs.
keywords: decisions, system one, systemone, noul, choice, score, probabilities, usage
group: gateway
---

## Quick {#quick keywords="curl, python, node, state, questions"}

A decision model does not write text. It reads a state — `state` — and answers your questions with probabilities: yes or no, which of several options, where on a scale. One operation takes the state and a map of questions and answers with a map of answers under the same keys. The request format is System One, the same as OpenRouter's: a client already written for it changes only the base URL.

:::code-group
```bash title=curl
curl https://api.kumorouter.com/v1/systemone \
  -H "Authorization: Bearer $KUMO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "<model>",
    "state": "The customer writes for the third time this week that the order has not arrived and asks for a refund.",
    "questions": {
      "refund": {
        "type": "noul",
        "instructions": "Is the customer asking for a refund?"
      },
      "topic": {
        "type": "choice",
        "instructions": "What is the request about?",
        "criteria": {
          "delivery": "delivery and timing",
          "payment": "payment and refunds",
          "other": "something else"
        }
      },
      "urgency": {
        "type": "score",
        "instructions": "How urgently does this need an answer?",
        "criteria": ["can wait", "within the day", "right now"]
      }
    }
  }'
```
```python title=Python
import os

import requests

response = requests.post(
    "https://api.kumorouter.com/v1/systemone",
    headers={"Authorization": f"Bearer {os.environ['KUMO_API_KEY']}"},
    json={
        "model": "<model>",
        "state": "The customer writes for the third time this week that the order has not arrived and asks for a refund.",
        "questions": {
            "refund": {"type": "noul", "instructions": "Is the customer asking for a refund?"},
        },
    },
    timeout=60,
)
answers = response.json()["answers"]
print(answers["refund"]["noul"])
```
```javascript title=Node
const response = await fetch("https://api.kumorouter.com/v1/systemone", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.KUMO_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    model: "<model>",
    state: "The customer writes for the third time this week that the order has not arrived and asks for a refund.",
    questions: {
      refund: { type: "noul", instructions: "Is the customer asking for a refund?" },
    },
  }),
});

const { answers } = await response.json();
console.log(answers.refund.noul);
```
:::

## Request members {#request keywords="model, state, questions"}

| Member | What it is |
| --- | --- |
| `model` | Required. A catalog model carrying the decisions protocol, under the name the client uses for it. |
| `state` | Required. What the model judges: a string, a JSON object or a JSON array. |
| `questions` | Required. A non-empty object: the key is your name for the question, the value is the question. The key is how your code finds the answer. |

`state` may be a string — an email, a message, a description — a JSON object with named fields when the state reads better in parts, or a JSON array: a list of messages, or a list of content parts such as `[{"type":"text","text":"…"}]`, where some models also read images. The state reaches the model exactly as you sent it. Whether a given model reads images depends on the model; it is stated on its page and in the catalog.

Streaming is not part of this surface: the answer arrives whole.

## Question types {#questions keywords="noul, choice, score, instructions, criteria"}

Every question carries `type` and `instructions` — the judgment you ask for; the upstream refuses a question without `instructions`. The questions of one request are decided independently of each other.

| Type | What it asks |
| --- | --- |
| `noul` | Yes or no: does the statement hold. |
| `choice` | Which of several options. |
| `score` | Where on an ordered scale. |

### noul

`criteria` is optional: an object describing `true` and `false`, when yes and no are worth spelling out. The answer carries `noul` — the probability of yes, from 0 to 1.

### choice

`criteria` is required: an object of label → description, with one label or more; a label's description may be `null`. The answer carries `choice` — the label chosen, `probabilities` — the probability of each label, and `confidence` — how settled the choice is.

### score

`criteria` is required: a list of levels, lowest first. The answer carries `score` — the probability-weighted position, from 0 to the number of levels minus one; `legend` — each level's number and text; `probabilities` — the probability of each level; and `confidence`.

## The response {#response keywords="answers, id, usage, input_tokens"}

| Reply member | What it is |
| --- | --- |
| `id` | The call's identifier. |
| `model` | The model that answered. |
| `answers` | One answer per question, under the question's own key; `type` repeats the question's type. |
| `usage` | `input_tokens` — the call's input tokens; `output_tokens` is always `0`. |

```json title=Response
{
  "id": "dec-<request id>",
  "model": "<model>",
  "answers": {
    "refund": { "type": "noul", "noul": 0.97 },
    "topic": {
      "type": "choice",
      "choice": "payment",
      "confidence": 0.81,
      "probabilities": { "delivery": 0.17, "payment": 0.82, "other": 0.01 }
    },
    "urgency": {
      "type": "score",
      "score": 1.62,
      "confidence": 0.58,
      "legend": { "0": "can wait", "1": "within the day", "2": "right now" },
      "probabilities": { "0": 0.04, "1": 0.3, "2": 0.66 }
    }
  },
  "usage": { "input_tokens": 412, "output_tokens": 0 }
}
```

## What the call costs {#billing keywords="price, input tokens, usage"}

Billing counts input tokens only: a decision model has an input price and no output price, so `output_tokens` in the answer is always zero and the ledger records zero for it. What a million input tokens of a given model cost is stated in the price list.

## Which models answer {#models keywords="catalog, protocol, modality"}

Only a model whose published catalog entry carries the decisions protocol answers here; its modality in the catalog is Decisions. A model of another protocol is refused on this surface, just as a decision model is refused on the chat surfaces.

> [The model catalog →](/en/models) [The price list →](https://kumorouter.com/en/pricing)

## Next {#next keywords="errors, rate limits, reference"}

:::cards
- [Errors](/en/errors) — the refusal envelope and this operation's status codes.
- [Rate limits](/en/limits) — the request and token ceilings.
- [API reference](/en/api-reference) — the operation member by member, straight from the API description.
:::
