OpenAI Decisions API: Classify Text and Images with Probabilities & Scores
Contents
When routing support tickets to specific teams or screening product photos for defects, applications often just need a category label or a numerical probability rather than freeform text generation.
OpenAI’s Decisions API provides a dedicated endpoint to pass text or images and receive structured evaluation results in predefined formats.
According to the official guide, it runs roughly 10x faster than the Responses API.
As of October 13, 2026, the API is in public beta and exclusively supports gpt-6-luna. Requests are sent to POST /v1/decisions.
Choosing Output Formats by Decision Type
With standard text generation, extracting structured data requires parsing model outputs with regex or JSON extractors.
The Decisions API lets you specify the response type directly in the request, so the client only needs to read the corresponding field in the response.
| Question Type | Example Use Case | Key Returned Value |
|---|---|---|
predicate | Check if a product photo shows defects | Estimated probability that condition is true (probability) |
choice | Route a ticket to the right department | Selected candidate from the provided list (choice) |
score | Evaluate severity on a tiered scale | Expected value calculated from category probabilities (score) |
Use choice for unordered classification like department routing, and score for ordinal evaluations like minor, moderate, or severe.
Because predicate returns a probability between 0 and 1 rather than a raw boolean, setting the threshold for taking action is handled on the application side.
If you need JSON with custom fields, Structured Outputs with a defined schema is a better fit.
Extracting order numbers and customer requests from an inquiry while drafting a response message falls under Structured Outputs.
If you want the model to select external functions and construct arguments for them, use function calling.
The Decisions API focuses on returning the decision itself; triggering downstream workflows like moving a ticket is handled on the application side.
Implementation Example with the Python SDK
A request takes model to specify the model name, input for the text or image payload, and a questions list defining what to evaluate.
The response returns an answers list, matching each item to the name assigned in the request. Assigning unique names to questions makes it straightforward to correlate responses when evaluating multiple items in one call. The schema details are documented in the API reference.
The Python SDK requires version 3.26.0 or later. Set your OPENAI_API_KEY environment variable first. Here is an example routing a user inquiry to “account”, “plan”, or “other”:
from openai import OpenAI
api = OpenAI()
result = api.decisions.create(
model="gpt-6-luna",
input="機種変更してから確認コードを受け取れず、ログインできません。",
questions=[{
"name": "support_queue",
"type": "choice",
"instructions": "この問い合わせを受け付ける窓口を選ぶ。",
"choices": [
{"value": "account", "description": "ログイン、認証、アカウント設定"},
{"value": "plan", "description": "プラン変更、契約、解約"},
{"value": "other", "description": "上記以外、または内容を判断できない相談"},
],
}],
)
for item in result.answers:
if item.type == "refusal":
print(item.name, "回答拒否")
elif item.type == "choice":
print(item.name, item.choice)
print("各候補の確率:", item.probabilities)
print("confidence:", item.confidence)
In choices, value is the programmatic identifier, while description provides the criteria the model uses to pick that option.
The API reference specifies between 2 and 255 choices with no duplicate values. Including a fallback choice like other helps capture inputs that do not fit into predefined categories.
If a question triggers safety policies or cannot be answered, type: "refusal" is returned instead of standard evaluation fields. When sending multiple questions in a single request, individual questions can return different response types, so handle them by checking item.type in your loop.
Handling Probabilities, Scores, and Thresholds
A choice response includes the selected option, probabilities for each candidate, and an overall confidence score.
While candidate probabilities sum across choices, confidence reflects how confident the model is in its overall assessment. Even with high confidence, misclassifications can still occur, so production setups require calibrating thresholds against labeled validation datasets to determine when to route decisions to human review.
score is an expected value (weighted average) computed by multiplying each category index by its probability. Indices start at 0.
| Tier Index | Evaluation Criteria | Assumed Probability |
|---|---|---|
| 0 | Minor (cosmetic issue only) | 0.2 |
| 1 | Moderate (affects operation, workaround exists) | 0.5 |
| 2 | Severe (operation blocked, no workaround) | 0.3 |
In this example, the score is 0 × 0.2 + 1 × 0.5 + 2 × 0.3 = 1.1.
This is a single scalar reflecting the full probability distribution rather than selecting Tier 1 as a majority vote. Because identical scores can arise from different probability distributions, routing logic can inspect the per-tier probabilities alongside the score.
Independent questions on the same input can be bundled into a single questions array.
However, sequential logic, such as determining repair types only when damage is detected, requires separate requests executed in order.
Image Input and Documentation Discrepancies
To pass text and images together, specify text and image objects side by side in the request’s input field.
The official guide illustrates embedding images as base64 data URLs (data:image/...):
[
{"input_text": "Check this product photo for visible damage."},
{"input_image": "data:image/jpeg;base64,..."}
]
However, documentation diverges regarding whether public HTTP/HTTPS image URLs are supported as of October 13, 2026.
| Source | Image URL Support |
|---|---|
| Official Guide | Requires base64 data URLs; HTTP/HTTPS URLs are not supported |
| API Reference | Supports both base64 data URLs and public HTTP/HTTPS URLs |
Because the active production behavior cannot be verified solely from the documentation, using base64 data URLs is the safer approach.
Both documents agree that pre-uploaded file_id references are not supported.
Dedicated Pricing at $0.10 per 1M Input Tokens
According to the official pricing documentation, using gpt-6-luna with the Decisions API costs $0.10 per 1 million input tokens.
Billing applies only to input tokens; output decision tokens and prompt cache reads/writes incur no additional charge. Surcharges for data residency and token multipliers for long context inputs apply as usual.
This rate is specific to the /v1/decisions endpoint and differs from standard Chat Completions or Responses API pricing for gpt-6-luna.
To explore how different prompts and question formats behave before writing code, test them interactively in the Decisions Playground.