Questions
Choice, score and probability questions — structured instructions and criteria, what the API returns for each, weighted levels, the reserved other option and minimum confidence.
Questions are what a decision answers about the state. A decision has 1 to 64 questions, all answered in one engine call: Jev evaluates each of them independently and in parallel against the same state. Each question becomes a key in the response's result and confidence objects, in the order you define them.
| Type | Use it for | result[key] | Example |
|---|---|---|---|
choice | Picking one option: a team, a category, a tool | One of your option values (string) | "sales" |
score | Placing the state on an ordered scale | The label of the most likely level (string) | "high" |
probability | A yes/no question | Probability of yes, from 0 to 1 | 0.9412 |
Common properties
| Property | Type | Required | Description |
|---|---|---|---|
key | string | Yes | snake_case, unique in the decision. Becomes the JSON key in the response. |
type | string | Yes | choice, score or probability. |
instructions | string, object or array | Yes | The question the engine answers: text, or structured JSON. Up to 8,000 characters (JSON counts its serialized length). |
minConfidence | number | No | 0 to 1. Below it, the decision applies the fallback action — see below. |
Choice
{
"key": "route",
"type": "choice",
"instructions": "Which team should receive this lead?",
"options": [
{ "value": "sales", "description": "high intent, ready to talk to sales" },
{ "value": "sdr", "description": "some intent, needs qualification" },
{ "value": "nurture", "description": "early stage, send content" }
]
}optionsneeds at least 2 and at most 254 options, plusother— 255 in total, Jev's maximum.valuefollows the key rules and must be unique within the question.descriptiontells the engine when the option applies: text or JSON, up to 2,000 characters. It is optional — omit it, or set it tonull, when the value says it all ("yes_refund"). Descriptions decide accuracy: contrast similar options and add exclusions such as "not for existing customers".- Order matters. Jev can lean toward the option listed first. Test important questions with the options reordered in the Playground and check that the answer stays the same.
The reserved other option
Every choice question has an other option. Dcision adds it automatically as the last option, with the description none of the options above. It can't be removed, but you can describe it yourself by including it in options — wherever you put it, it is moved to the end:
{ "value": "other", "description": "not about our product, or a language we don't support" }Without other, an engine is forced to pick the least wrong option. With it, "none of these" becomes an explicit answer: when a choice question answers other and no policy matched first, the decision applies its fallback action with action_reason.type = "other_option". See Policies and actions.
What the API returns
result.route— the chosen option, for example"sales"(or"other").confidence.route— how far the chosen option stands above an even split between all the options, from 0 to 1 — see Confidence.- With
?include=probabilities,probabilities.routeholds one probability per option,otherincluded.
Policies on a choice answer can only use eq and neq. The comparison ignores case and surrounding spaces.
Score
{
"key": "priority",
"type": "score",
"instructions": "How urgent is it to answer this lead?",
"scale": ["low", "medium", "high", "critical"]
}scalelists 2 to 10 levels from lowest to highest. A level is a label (up to 2,000 characters) or a structured rubric with alabel. Labels must be unique.result.priorityis the label of the most likely level — not an average — andconfidence.prioritysays how concentrated the distribution is around it.scores.priorityis the weighted level: the probability-weighted average of the levels, counted from 1. In the scale above,2.81sits betweenmedium(2) andhigh(3), closer tohigh. Use it to act between levels.- With
?include=probabilities,probabilities.priorityholds one probability per label, in scale order.
Policies compare levels, numbered from 1: in the scale above low is 1 and critical is 4.
- On the answer (
"on": "output"), a rule uses the level number ("value": 3) or the label ("value": "high"), with any operator:{ "field": "priority", "operator": "gte", "value": "high", "action": "escalate" }matcheshighandcritical. A label that isn't in the scale never matches. - On the weighted level (
"on": "score"), a rule comparesscores.prioritywith a number:{ "field": "priority", "on": "score", "operator": "gte", "value": 3.5, "action": "escalate" }fires when the weight leans towardcritical, even ifhighis the most likely level.
Probability
{
"key": "purchase_intent",
"type": "probability",
"instructions": "Does this lead have real intent to buy in the next 30 days?",
"criteria": {
"yes": "asks for pricing, a demo, a quote or a start date",
"no": "just browsing, student, vendor or spam"
}
}criteria.yesandcriteria.noare optional — text or JSON, up to 2,000 characters each — and say what counts as yes and as no. Keep them aligned with the instructions:yesshould describe the yes case.result.purchase_intentis the probability of yes, between 0 and 1, rounded to 4 decimals.confidence.purchase_intentis|2p − 1|: the distance from a coin flip.0.03(a confident no) and0.97(a confident yes) both have confidence0.94;0.5has confidence0.- With
?include=probabilities,probabilities.purchase_intentis{ "yes": p, "no": 1 − p }.
Policies compare the probability with a number, for example { "field": "purchase_intent", "operator": "gte", "value": 0.8, "action": "continue" }.
Structured instructions and criteria
Jev reads structure natively. Wherever a question has text — instructions, option description, score levels, criteria.yes and criteria.no — you can send a JSON object or array instead. Structure helps when a question has several parts, or when it needs supporting data such as a taxonomy, a schema or a database row: the keys label each part.
{
"key": "duplicate_candidate",
"type": "probability",
"instructions": {
"potential_duplicate": { "name": "John Smith", "location": "Oakland, California", "last_employer": "Google" },
"question": "Is the resume in `resume` for the same person as `potential_duplicate`?"
}
}- Point at data with backticks. Name state fields and keys of the instruction between backticks —
`resume`,`ticket.messages[0].text`— to tell the engine exactly what to look at. - Give options a rubric. An option description such as
{ "what": "Charges, invoices, refunds", "not_for": "Order tracking", "examples": ["I was charged twice"] }sharpens the boundary between neighbors. - Limits are the same as for text, measured on the serialized JSON: 8,000 characters for instructions, 2,000 for an option description, a score level or a criterion. Objects and arrays can't be empty.
- In the editor, paste a JSON object or array into the field: it is stored as structure and marked structured. Anything that isn't valid JSON stays text.
Structured score levels
A score level can be an object with a label — the label is what result returns and what policies compare; the whole object is what the engine reads:
{
"key": "bug_severity",
"type": "score",
"instructions": "If this describes a bug, how severe is it for the customer?",
"scale": ["cosmetic", "minor", "major", { "label": "critical", "rubric": "outage, data loss, security issue or money at risk" }]
}The label is 1 to 255 characters; the whole level, serialized, up to 2,000. Plain and structured levels can be mixed in one scale. The editor adds levels as plain labels and shows structured ones with a braces icon — the Support Ticket Triage template starts with one.
Minimum confidence
Any question can set minConfidence between 0 and 1. When the answer's confidence is below it and no policy matched first, the decision applies its fallback action with action_reason.type = "low_confidence":
{ "type": "low_confidence", "question": "route", "confidence": 0.52, "minConfidence": 0.8 }In the editor, the Minimum confidence toggle starts at 80%. Without it, low-confidence answers still continue.
For a probability question, confidence is |2p − 1|, so a minimum confidence flags a band of probabilities around 0.5: 0.8 flags every p between 0.1 and 0.9, 0.6 every p between 0.2 and 0.8. The editor shows the band next to the slider. See Confidence and probabilities and Handling low confidence and other.
Tips
- Ask one thing per question. Split "is this urgent spam?" into a probability (
spam) and a score (urgency) — they cost one call either way. - Phrase instructions as a literal question about the state: "Which team should receive this lead?".
- Prefer probability for yes/no — the number is easier to threshold than a two-option choice.
- Prefer score for ordered levels — policies can then use
gte/lteon the level and thresholds on the weighted level. - Write option descriptions as criteria, not labels, and make neighbors mutually exclusive. If the Playground flags a near tie, the descriptions overlap.
- Put business facts in
context, not in every instruction. - Keep math, counts and dates in code and send the results in the state.
- Order matters: when several questions answer
otheror fall below their minimum confidence, the first one in question order is reported inaction_reason.
More in Writing good questions.
Decision schema
The JSON document behind every decision — the state it accepts, the questions it answers, composites, the policies that pick the action, the runtime settings and the destinations.
Composites
Combine several answers into one number with weights you control — Σ(weight × value) / Σ|weight| — return it in composites and use it in policies.