Create Decision

Answer typed questions about a state with calibrated probabilities.

Ask typed questions about a piece of state and get back typed answers with calibrated probabilities. Decision models return no text, so there is no OpenAI SDK method for this endpoint. Call it with plain HTTP.

POST /v1/decisions

Authentication

AuthorizationBearerrequired

API key as bearer token in the Authorization header. Create keys at Manage API Keys.

Headers

Content-Typestringrequired

Must be application/json.

Body

modelstringrequired

Decision model id. Example: jev-1.13.

statestring | object | arrayrequired

The content to evaluate. Either a plain string, or a JSON object or array of related context. Questions can refer to nested fields by name, e.g. `listing.title`.

questionsobjectrequired

Map of question id to question. At least one question is required. Each answer comes back under the same id.

Question

typestringrequired

What kind of answer you want. See Question types.

Allowed values:noulchoicescore
instructionsstringrequired

The question itself, phrased the way you would ask a human reviewer.

criteriaobject | string[]optional

What each possible answer means. The shape depends on type. Required for choice and score, optional for noul.

Response

idstringoptional

Unique request id.

modelstringoptional

The model id you requested.

answersobjectoptional

Map of question id to answer. Each answer has a type matching its question plus the fields described below.

usageobjectoptional

{ input_tokens, output_tokens }. Only input tokens are billed.

Question types

noul - yes or no

criteria is optional. Use it to spell out what true and false mean when the question is ambiguous.

{
  "type": "noul",
  "instructions": "Does this message convey urgency?",
  "criteria": {
    "true": "Explicitly time-sensitive",
    "false": "No urgency expressed"
  }
}

The answer is { "type": "noul", "noul": 0.96 }, where noul is the probability that the answer is yes, between 0 and 1. A value near 0.5 means yes and no are about equally likely. It does not mean "medium".

choice - pick one option

criteria maps each option key to a description.

{
  "type": "choice",
  "instructions": "Which team should handle this?",
  "criteria": {
    "billing": "Payments, invoicing, refunds",
    "technical": "Bugs, outages, integrations",
    "sales": "Pricing, upgrades, new accounts"
  }
}
Answer fieldMeaning
choiceThe selected option key.
probabilitiesProbability of every option.
confidenceHow concentrated that distribution is.

score - place on an ordered scale

criteria is an array of levels, lowest first. At least two levels are required.

{
  "type": "score",
  "instructions": "How frustrated is the customer?",
  "criteria": ["Calm", "Frustrated", "Very angry"]
}
Answer fieldMeaning
scoreProbability-weighted position on the scale. Index 0 is the first level, so 1.99 sits almost exactly on the third level.
probabilitiesProbability of every level, keyed by index.
legendIndex to level text, so you don't have to keep your own mapping.
confidenceHow concentrated that distribution is.

Reading the probabilities

Probabilities vary slightly from call to call, so branch on bands rather than exact values. A common pattern is to act automatically when confidence is above a threshold you tuned on real data, and send everything else to a human.

const { team } = answers;
if (team.confidence >= 0.8) {
  await routeTo(team.choice);
} else {
  await sendToReviewQueue(ticket);
}

Pick thresholds from the cost of each kind of mistake, not from a round number. confidence describes how spread out the options are. It does not tell you whether the action is safe to take.

Tips

  • Put every independent question about the same state in one request. They are answered in parallel and billed once for the shared state.
  • Keep instructions specific and name the state fields you want the model to look at.
  • If you need an explanation for a decision, make the decision here, then ask a chat model to explain it.

Errors

All errors follow the OpenAI structured shape:

{ "error": { "type": "invalid_request_error", "message": "..." } }
Statuserror.typeMeaning
400invalid_request_errorSchema violation. The message names the offending field.
401authentication_errorMissing or invalid API key.
402billing_errorAccount out of credit or hit a spend limit.
404not_found_errorUnknown model, or the model is not a decision model.
429rate_limit_errorRPM exceeded. Respect Retry-After.
500internal_server_errorUnexpected gateway failure. Safe to retry.
502 / 503upstream_errorDownstream provider failure.