# Decisions (/concepts/decisions)



A [decide](/reference/decide) request asks 1 to 128 questions about one case, its [data and context](/concepts/data). Grayson, Finic's decision model, answers each with calibrated probabilities. Nothing is generated: no rationale or text, only probabilities.

```json
"questions": {
  "is_fraud": { "type": "noul", "instructions": "Is this account engaged in or the victim of fraud?" },
  "escalate_to": {
    "type": "choice",
    "instructions": "Which team should this alert be escalated to?",
    "criteria": { "ato": "Account security / ATO team", "aml": "AML investigations", "none": "No escalation needed" }
  }
}
```

Each question's key names it, and its answer comes back under the same key. Keys and option keys match `^[A-Za-z_][A-Za-z0-9_]{0,63}$`. The model never sees them: everything it needs goes in the `instructions` and `criteria`. In a choice, the key (`ato`) comes back in the answer; the description ("Account security / ATO team") is what the model reads.

## Question types [#question-types]

Every question has `type` and `instructions` (not blank). Fields that don't belong to the type are rejected. Every answer repeats its question's `type`.

| Type           | Use for                                                           | `criteria`                                                                                   | Answer                                                                                          |
| -------------- | ----------------------------------------------------------------- | -------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
| `noul`         | Yes or no                                                         | Optional: `{"true": "…", "false": "…"}`, what each answer means, read after the instructions | `noul`: the probability of yes                                                                  |
| `choice`       | Exactly one right answer: routing, next action, primary typology  | 2–255 options as `key: description`                                                          | `choice`: the most likely key; `confidence`; `probabilities` per option, summing to 1           |
| `multi_choice` | Any number of right answers: typologies present                   | As for `choice`                                                                              | `multi_choice`: keys with probability 0.5 or more; `probabilities` per option, each independent |
| `score`        | A degree on an ordered scale: risk, severity, every "How likely…" | 2–32 levels, **lowest first**                                                                | `score`: the expected level; `legend`; `confidence`; `probabilities` per level                  |

```json title="Answers"
"answers": {
  "is_fraud": { "type": "noul", "noul": 0.92 },
  "primary_typology": { "type": "choice", "choice": "ato", "confidence": 0.85, "probabilities": { "ato": 0.88, "synthetic_id": 0.02, "mule": 0.05, "first_party": 0.03, "none": 0.02 } },
  "typologies_present": { "type": "multi_choice", "multi_choice": ["ato", "mule"], "probabilities": { "ato": 0.93, "synthetic_id": 0.04, "mule": 0.61, "first_party": 0.03, "scam": 0.07 } },
  "risk": { "type": "score", "score": 3.46, "legend": { "0": "very low", "1": "low", "2": "medium", "3": "high", "4": "very high" }, "confidence": 0.5, "probabilities": { "0": 0.01, "1": 0.02, "2": 0.07, "3": 0.3, "4": 0.6 } }
}
```

* **Option descriptions** must not be blank and must be unique, ignoring case and whitespace. A `null` description reads as the key with spaces for underscores (`first_party` reads "first party"), but a real description works better.
* **A choice** spreads all its probability over its options, so include one for "none of these" when that can happen. If two options can both be true, use `multi_choice`: a choice has to split probability between them, and neither may reach 0.5.
* **A multi\_choice** asks about each option separately. With up to 16 options, each is judged with the full list in view; with more, each on its own, like a separate `noul`.
* **A score's levels** are numbered from 0. For "How likely…" questions, use the standard levels, the same for every question so answers compare: `["Very unlikely (under 10%)", "Unlikely (10-40%)", "Uncertain (40-60%)", "Likely (60-90%)", "Very likely (over 90%)"]`. A `score` question is separate from the 0–1000 [scores](/concepts/scores) you create from examples.

## Score answers and confidence [#score-answers-and-confidence]

A score's `score` is the expected level: each level's number times its probability, added up, so it can fall between levels. `confidence`, for a choice or a score, is (K × the top probability − 1) / (K − 1) over K options or levels: 0 when all are equally likely, 1 when one has all the probability.

With the standard likelihood levels and probabilities 0.02, 0.06, 0.25, 0.44 and 0.23, the score is 0×0.02 + 1×0.06 + 2×0.25 + 3×0.44 + 4×0.23 = **2.80**, a little under "Likely", and the confidence (5×0.44 − 1) / 4 = **0.30**, because the probability is spread over three levels. A high score with low confidence means a split answer: check the probabilities. To act when an answer is at least "Likely", add those levels: 0.44 + 0.23 = 0.67.

`choice`, `multi_choice` and `score` summarize the probabilities; base decisions on the probabilities themselves, unrounded. See [Choosing thresholds](/concepts/calibration#choosing-thresholds).

## Writing good questions [#writing-good-questions]

* **Ask one thing.** "Is this account takeover or a scam?" is two questions: use a `choice`, or two nouls.
* **Name the subject:** "the outbound ACH on September 20", not "this", when the data holds several transactions.
* **Make yes mean the action:** "Should this wire be held?" thresholds more directly than "Is this wire safe to release?"
* **Define your terms and standards.** "High risk: two or more of a new device, a new payee and a changed email in the last 24 hours" gets answers that follow your policy; "High risk" leaves it to the model.
* **Write descriptions that stand alone:** "Hold the payment and verify the customer another way", not "Hold".
* **Keep wording and order fixed.** A choice reads its options and a score its levels together, in the order given. Changing the wording or order can change the answers, so choose thresholds with the exact questions you run in production.
* **Ask about signals directly** when you need to record why: "Did the account log in from a new device shortly before the transfer?" gives a probability you can log and show a reviewer.

## Determinism and isolation [#determinism-and-isolation]

* **The same request always gets the same answers,** so retrying is safe. Any change (instructions, option order, data, context, key order) makes it a different request. Whitespace between JSON tokens in `data` doesn't matter; whitespace inside strings does.
* **Each question sees only the case and its own text,** never the other questions: adding, removing or renaming one can't feed into another's answer. Numerical rounding can still move other answers slightly, under 1 percentage point on average.

Requests and answers are kept only as your [data retention](/concepts/data#data-retention) allows. To keep them for audits, appeals or threshold tuning, store the request and response, with its `id` and `request_id`, with your own decision record.
