Answers and probabilities
How to read each answer type, set thresholds, and what determinism and isolation guarantee.
A response has one answer per question, under the question's name. Each answer repeats its question's type, so you can parse it without looking up the request.
"answers": {
"is_fraud": { "type": "noul", "value": true, "probability": 0.92 },
"primary_typology": {
"type": "choice",
"value": "ato",
"probabilities": { "ato": 0.88, "synthetic_id": 0.02, "mule": 0.05, "first_party": 0.03, "none": 0.02 }
},
"typologies_present": {
"type": "multi_choice",
"values": ["ato", "mule"],
"probabilities": { "ato": 0.93, "synthetic_id": 0.04, "mule": 0.61, "first_party": 0.03, "scam": 0.07 }
},
"risk": {
"type": "score",
"value": 3.46,
"level": "very high",
"probabilities": [0.01, 0.02, 0.07, 0.3, 0.6]
}
}Reading each type
| Type | Fields |
|---|---|
noul | probability: P(yes). value: probability >= 0.5 |
choice | probabilities: one entry per option, in request order, summing to 1. value: the most likely option's key |
multi_choice | probabilities: P(option applies) for each option, in request order. Each is independent, so they need not sum to 1. values: the keys with probability of at least 0.5, in request order; can be empty |
score | probabilities: one entry per level, lowest first, summing to 1. level: the most likely level. value: the expected value (see Score values) |
value, values and level are conveniences built on a cut of 0.5 or on the most likely outcome. Base decisions on the probabilities.
Probabilities are not rounded. Round them for display only, and compare the full values with your thresholds.
Setting thresholds
Grayson returns probabilities, not decisions. It is trained so that its probabilities are calibrated: of the answers given a probability near 0.8, about 8 in 10 should be right. Check calibration on a sample of your own labeled cases before you rely on a threshold, because your population, and how you label outcomes, can differ.
- Choose thresholds from your own cases. Run a labeled sample of past cases, each state cut at the time of the decision, and pick the threshold that gives the review volume, catch rate or losses you want.
- Use a threshold per action. One probability can drive several actions, for example blocking above one threshold and sending to review above a lower one.
- For a score, add up the levels you act on. P(Likely) + P(Very likely) is usually easier to threshold than the expected value.
- For a choice, look at the margin. A top option at 0.48 with a runner-up at 0.45 is a close call; 0.90 against 0.05 is not.
Determinism
The same request always returns the same answers, so retrying a request is safe.
Any change to the request makes it a different request: different instructions, option order, state content or key order can change the answers. Whitespace between JSON tokens in the state doesn't matter, because objects and arrays are compacted before they're read. Whitespace inside strings does.
Isolation
Each question sees the state and its own text, never the other questions in the request. Adding, removing or renaming a question can't feed information into another question's answer. Numerical rounding can still move another answer slightly: by under 1 percentage point on average, occasionally by more.
A choice reads its options together, in the order you give them. A multi_choice asks about each option separately.
Nothing is generated
A response contains no rationale, summary or other text: only probabilities. To record which signals drove a decision, ask about them directly, as questions of their own:
"new_device_login": {
"type": "noul",
"instructions": "Did the account log in from a device not seen before, shortly before the transfer?"
}Each answer is a probability you can log and show to a reviewer.
Keep your own record
Finic never stores the state, the questions or the answers of requests sent through the API. If you need them for audits, appeals or threshold tuning, store the request and response with your own decision record, along with the response id and the X-Request-Id header. See Zero data retention.