Handling low confidence and other

Design decisions that admit uncertainty — the reserved other option, minimum confidence, confidence policies, the fallback action, near ties and the engine-error fallback.

A decision that always answers confidently is lying some of the time. Jev's probabilities are calibrated, so its confidence is worth acting on, and Dcision gives you four tools to make uncertainty an explicit, routable outcome instead of a silent wrong answer.

1. The other option

Every choice question has a reserved other option, added automatically as the last option ("none of the options above"). It lets the engine say that nothing fits instead of picking the least wrong option.

When a choice answers other and no policy matched, the response carries the decision's fallback action:

{
  "result": { "route": "other" },
  "action": "escalate",
  "action_reason": { "type": "other_option", "question": "route" }
}

Describe other when "none of these" has a specific meaning for you:

{ "value": "other", "description": "not a sales inquiry: job applications, partnerships, press" }

2. Minimum confidence

Set minConfidence on a question to treat answers below it as uncertain:

{
  "key": "route",
  "type": "choice",
  "instructions": "Which team should receive this lead?",
  "minConfidence": 0.8,
  "options": [ … ]
}
{
  "result": { "route": "sdr" },
  "confidence": { "route": 0.52 },
  "action": "escalate",
  "action_reason": { "type": "low_confidence", "question": "route", "confidence": 0.52, "minConfidence": 0.8 }
}

Start around 0.8 (the editor's default) for choice and score questions and adjust with real traffic. For probability questions, confidence is |2p − 1|, the distance from a coin flip: a minConfidence of 0.8 flags every probability between 0.1 and 0.9, and 0.6 every probability between 0.2 and 0.8 — see the table.

3. Confidence policies

When different questions — or different answers — need different actions, write explicit rules with "on": "confidence". They run before the other and minimum-confidence checks:

{ "field": "purchase_intent", "on": "confidence", "operator": "lt", "value": 0.6, "action": "escalate" }

The response then says { "type": "policy", "rule": 1 } (the rule's 0-based index).

Combine a confidence condition with an answer to give each action its own threshold — a transfer needs more certainty than a balance check:

{
  "field": "intent",
  "on": "output",
  "operator": "eq",
  "value": "approve_transfer",
  "and": [{ "field": "intent", "on": "confidence", "operator": "lt", "value": 0.9 }],
  "action": "escalate"
}

That's the confidence-gated routing pattern.

Destinations can follow the same logic: give a route its own minimum confidence, or send every escalate to a person through a webhook, a workflow or an API request — see Triggers.

4. The fallback action

settings.fallbackAction is the action used for other answers, minimum-confidence misses and — when you opt in — engine failures. It defaults to escalate:

fallbackActionUse it when uncertain cases should…
escalate (default)go to a person or a review queue
fallbackgo to a stronger, more expensive path — a large model, more retrieval
blockbe dropped (strict moderation)
continueproceed anyway — uncertainty is only logged

Putting it together

const decision = await response.json();
const reason = decision.action_reason;

switch (decision.action) {
  case "continue":
    return automate(decision.result);
  case "escalate": {
    const why =
      reason.type === "other_option"
        ? `no option fits "${reason.question}"`
        : reason.type === "low_confidence"
          ? `"${reason.question}" is only ${Math.round(reason.confidence * 100)}% sure`
          : reason.type === "engine_error"
            ? `the engine failed (${reason.code})`
            : `policy rule ${reason.rule + 1}`;
    return reviewQueue.add({ item, why, executionId: decision.execution_id });
  }
  case "fallback":
    return largeModel.handle(item);
  case "block":
    return reject(item);
}

Near ties

Two options can share the probability mass — { "sales": 0.46, "sdr": 0.40 } — with a top answer that passes a low threshold. The Playground flags these near ties (runner-up above 20% and less than 15 points behind). Fix them at the source: make the two option descriptions mutually exclusive, then re-run the same input and check Compared with the previous run. Use ?include=probabilities to detect them in production — see Confidence and probabilities.

Engine errors: an error or the fallback action

By default, the fallback action applies to answers, not to failures: if the engine times out or fails — after Dcision's own retries — the API returns an error (503, 504, …) and no action. Route errors explicitly — most integrations treat them like escalate after a retry:

if (!response.ok) {
  const { error } = await response.json();
  if (["ENGINE_TIMEOUT", "ENGINE_UNAVAILABLE", "ENGINE_RATE_LIMITED"].includes(error.code)) {
    return retryLater(item); // or escalate
  }
  throw new Error(`${error.code}: ${error.message} (${error.request_id})`);
}

Or let the decision handle it: with "onEngineError": "fallback" in its settings, an engine failure answers 200 with the fallback action and { "type": "engine_error", "code": "ENGINE_TIMEOUT" }, an empty result, no charge — and the switch above handles it like any other escalate. Retrying later with the same Idempotency-Key reaches the engine again. See Decision settings.

Monitor it

  • The decision's Overview tab measures other answers, near ties, low confidence and the effect of each minConfidence per question, and suggests what to change — see Overview and calibration.
  • In Executions, open runs with escalate and read their reason: many other_option reasons mean your options miss a common case; many low_confidence reasons on one question mean its instructions or descriptions are vague — see Writing good questions.
  • Pull the same data from code with GET /v1/executions to chart reasons and confidence over time and calibrate thresholds against outcomes.
  • Re-run those inputs in the Playground after each edit, then deploy.

On this page