# Questions (/concepts/ask)



An [ask](/reference/ask) 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 |

```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 } }
}
```

* **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`.

## Confidence [#confidence]

A choice's `confidence` is (K × the top probability − 1) / (K − 1) over K options: 0 when all are equally likely, 1 when one has all the probability. In the answers above, (5 × 0.88 − 1) / 4 = **0.85**.

`choice` and `multi_choice` 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 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.
