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

# Make a decision

> Ask a model to pick one option per question, with a confidence. No prose, no parsing.

Some calls are not writing tasks. *Should this command run? Which model should serve this request? Is this ticket a bug or a feature?* Those are choices, and a model that answers them in prose makes you parse the prose back into a choice.

`POST /v1/decisions` answers them as choices. You send the state and the questions, each with its options; every question comes back with one option and a confidence.

```bash theme={null}
curl https://api.kymaapi.com/v1/decisions \
  -H "Authorization: Bearer $KYMA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "jev",
    "state": "Proposed shell command: `rm -rf ./build` in a CI job that has already published its artifacts.",
    "questions": {
      "gate": {
        "type": "choice",
        "instructions": "Should this command be allowed to run?",
        "criteria": {
          "allow": "safe, run it",
          "deny": "refuse it",
          "escalate": "ask a human"
        }
      }
    }
  }'
```

```json theme={null}
{
  "model": "jev",
  "answers": {
    "gate": {
      "choice": "allow",
      "confidence": 0.82,
      "probabilities": { "allow": 0.82, "deny": 0.11, "escalate": 0.07 }
    }
  },
  "usage": { "input_tokens": 383, "output_tokens": 41, "cost": 0.0001 }
}
```

## Request

<ParamField body="model" type="string" default="jev">
  The decisions model. `jev` is the only value today; any other returns `400`.
</ParamField>

<ParamField body="state" type="string" required>
  What the model is deciding about, in your own words. Plain text.
</ParamField>

<ParamField body="questions" type="object" required>
  One or more questions, keyed by an id you choose. Each must be `{"type": "choice", "instructions": "...", "criteria": { "<option>": "<what it means>", ... }}` with at least one option. Anything else returns `400` naming the question.
</ParamField>

## Response

`answers` is keyed by your question ids. Each carries `choice` (always one of the options you supplied), `confidence` between 0 and 1, and `probabilities` across the options when the model reports them.

Use the confidence: a common pattern is to act on the choice above a threshold you pick and hand the rest to a full language model, which costs more and answers slower.

## What it will not do

It writes no prose, reads no images and calls no tools. It is a classifier you put **in front of** a model, a tool call or a risky command — not a replacement for one. Sending it to `/v1/chat/completions` returns `400`.

## Billing

Per input token, at the model's published rate — `$0.0567` per million for `jev`, with output free — **rounded up to the nearest `$0.0001`**, which is the smallest amount the ledger holds. A decision is small enough that the honest price of one call lands below that, so the rounding is what makes it chargeable at all: up to about 1,700 input tokens a call costs `$0.0001`, and 10,000 short decisions are \$1. The response quotes `usage.cost` in dollars, and that is the amount taken from your balance — not a number rounded somewhere else afterwards.

Failures are not charged: an upstream error or an unreadable answer returns `502` and writes a \$0 row you can see in [usage](/api-reference/auth-usage-models).

## Errors

| Status | `error.type`           | When                                                                                                                 |
| ------ | ---------------------- | -------------------------------------------------------------------------------------------------------------------- |
| `400`  | `invalid_request`      | `state` or `questions` missing or malformed, a question that is not a choice question, or a `model` other than `jev` |
| `401`  | `auth_error`           | Missing or invalid API key                                                                                           |
| `402`  | `insufficient_credits` | Balance does not cover the call. The body names `need_usd` and `have_usd`.                                           |
| `503`  | `server_error`         | Kyma could not read your account to price the call. Not charged; retry.                                              |
| `502`  | `server_error`         | The upstream failed or returned an answer Kyma could not read. Not charged.                                          |
| `504`  | `timeout`              | The decision did not come back in time. Not charged.                                                                 |
