OpenAI Decisions API: fast yes/no answers and scores
OpenAI's Decisions API answers questions about text, images and JSON with a probability, one of your choices or a score on your rubric, about 10 times faster than the Responses API and with no charge for output. How it works, what it costs, and how to pick the threshold you act on.
Tecyfy · Published · 8 min read

The OpenAI Decisions API answers a question about your input with a number or a label instead of text: the probability that something is true, one value from a list you give it, or a score on levels you define. OpenAI says it returns those answers about 10 times faster than the Responses API, and on gpt-6-luna, the only model it runs, you pay $0.10 per million input tokens and nothing for output.
It went into beta on 6 October 2026 and became generally available on 22 October with prompt caching, JSON input and up to 400 questions a request. It is built for the small judgements an application makes thousands of times a day: is this ticket a refund request, which team gets it, how urgent is it, is this photo of a damaged item.
The 3 kinds of question
Every question is a predicate, a choice or a score, and the type decides what comes back.
| Type | Ask it for | It returns |
|---|---|---|
predicate | A yes or no condition: "Does the photo show visible damage?" | probability, from 0 to 1, that the condition is true |
choice | One option from a set with no order: billing, technical, shipping, other | choice, plus a probability for each option and a confidence |
score | A place on 2 to 10 ordered levels: cosmetic, workaround available, fully blocked | score, the probability-weighted average of the level numbers, which can fall between levels |
A score of 1.1 on those 3 levels means the model put most of its weight on "workaround available" (level 1) with some on either side. Use choice when you need a single category and score when the levels have an order and the in-between matters.
Any answer can come back as refusal instead, so check the type before you read the number.
1 request, 3 questions
Questions that share the same input go in 1 request, and each gets its own answer by name. This routes a support ticket, sending the ticket and the order record as JSON:
from openai import OpenAI
client = OpenAI()
decision = client.decisions.create(
model="gpt-6-luna",
input=[{
"role": "user",
"content": [
{"type": "input_text", "text": "A support ticket and the customer's order."},
{"type": "input_json", "data": {
"ticket": {"body": "I was charged twice for order 48213."},
"order": {"id": "48213", "charges": [49, 49]},
}},
],
}],
questions=[
{"type": "predicate", "name": "duplicate_charge",
"instructions": "Does the ticket describe a duplicate charge that the order confirms?"},
{"type": "choice", "name": "team",
"instructions": "Which team should handle this ticket?",
"choices": [
{"value": "billing", "description": "Payments, invoices and refunds."},
{"value": "technical", "description": "Problems using the product."},
{"value": "shipping", "description": "Delivery and tracking."},
{"value": "other", "description": "Anything else."},
]},
{"type": "score", "name": "urgency",
"instructions": "How urgent is this ticket?",
"levels": [
{"label": "Can wait", "description": "No money or access at risk."},
{"label": "Today", "description": "Money owed or a task blocked."},
{"label": "Now", "description": "Ongoing loss or a security concern."},
]},
],
)
answers = {a.name: a for a in decision.answers}
if answers["duplicate_charge"].type == "predicate" and answers["duplicate_charge"].probability >= 0.8:
queue_refund("48213") # your own code acts on the answer
The questions are independent, so they run together. If one depends on another (ask about a repair category only when the photo shows damage), send them as 2 requests. A few rules from OpenAI's guide that save rework:
- Add a fallback choice such as
other, so input outside your categories has somewhere to go. - Write questions around what can be seen in the input, 1 concern per question, and give each score level criteria that differ from its neighbours.
- Images go in as base64 data URLs or public HTTPS links;
file_id, files and audio are not accepted. Each question can carry its own image to compare against a shared one. - JSON keys are data. A
roleorimage_urlkey insideinput_jsondoes not create a message or fetch a picture.
What it costs
On the Decisions API you pay only for input, so 1 million tickets cost less than 1 million classifications on the same model through the Responses API, and far less than on a larger model. Take a ticket of 600 tokens, 1,500 tokens of shared instructions that are the same on every request, and 3 questions of about 150 tokens together:
| Per million tickets | |
|---|---|
Decisions API, gpt-6-luna | $90: instructions read from the cache $15, ticket and questions $75, output free |
Responses API, gpt-6-luna, about 40 output tokens of JSON, reasoning off | $96.50 |
Responses API, gpt-6.1-sol, same prompt | $1,765 |
Cache writes are left out, and the questions in a Decisions request sit outside the cached part, which is why they are billed at the full input price. The cache needs a shared prefix of at least 1,024 tokens, so put the long, unchanging instructions or reference material first in input.
The price difference against gpt-6-luna on the Responses API is small. The reasons to switch are the speed and the answer itself: a calibrated probability you can set a threshold on, rather than a word you have to parse and trust. Against a larger model the gap is 20 times, which is the case for sending this kind of judgement to a small model at all; model routing covers that cascade, and the gpt-6-luna price page has every rate.
Choosing the threshold you act on
A probability is only useful once you decide the number above which your application acts, and that number comes from your own labelled examples. OpenAI's guide says to set it by the cost of a false positive against a false negative. If a missed damaged item means a refund and an angry customer, while a needless check costs a minute of someone's time, the line belongs lower than 0.5.
Move the line and change what a miss costs:
probability of visible damage
damaged (top row)fine (bottom row)faded: below the line, not checked
- To a person
- 12
- Needless checks
- 3
- Damage missed
- 3
At 0.50, 12 of 30 photos go to a person: 3 needlessly, and 3 of the 12 damaged ones slip through. With a miss costing 5 times a needless check, this sample's cheapest threshold is 0.15.
A made-up sample of 30 labelled photos, to show the method OpenAI's guide describes. Run your own labelled examples through the API before you pick a number.
The method in practice: label a few hundred real inputs by hand, run them through the API, then pick the threshold that makes the cheapest mix of mistakes. Keep the labelled set, because a change in the model or your instructions moves the probabilities, and the same set tells you whether the threshold still holds. For score questions with a written rubric, LLM as a judge: how to write a rubric you can trust covers the level wording.
When to use something else
- To produce something, use the Responses API. Extracting fields into your own schema, writing an explanation or calling a tool with arguments is structured output or function calling; Structured Outputs vs JSON mode covers the schema side.
- For a different model. Only
gpt-6-lunaruns on/v1/decisionstoday. A judgement that needs a stronger model goes through the Responses API. - For a chain of dependent questions, each step is its own request, so a long decision tree adds a round trip per level.
What it does offer that many endpoints do not: Zero Data Retention and HIPAA use for eligible customers, data residency in every supported API region, and regional processing in the United States and Europe. It also plugs into GPT-Live voice sessions, which can call Decisions directly while the user is still speaking.
Questions
- What is the OpenAI Decisions API?
- The Decisions API (POST /v1/decisions) evaluates text, images and JSON and returns typed answers instead of generated text: the probability that a condition is true, one value from a fixed set, or a score against ordered levels. OpenAI says it answers about 10 times faster than the Responses API. It went into beta on 6 October 2026 and became generally available on 22 October 2026.
- How much does the OpenAI Decisions API cost?
- With gpt-6-luna, the only model it supports, uncached input costs $0.10 per million tokens and output tokens are not charged. Cached input is $0.01 per million and cache writes are charged at the model's rates. Long-context pricing and the 10% regional processing premium apply as they do on other endpoints.
- What is the difference between predicate, choice and score questions?
- A predicate returns the probability, from 0 to 1, that a condition is true. A choice returns one of the values you supplied, with a probability for each and a confidence. A score rates the input against 2 to 10 ordered levels and returns the probability-weighted average of their indices, so it can fall between levels.
- How many questions can one Decisions API request ask?
- Between 1 and 400, up from 200 during the beta. All the questions in a request share the same input, and each can be a different type. Questions that depend on an earlier answer need separate requests.
- When should I use the Responses API instead of the Decisions API?
- Use the Responses API with Structured Outputs when you need the model to produce something: extracted fields in your own JSON schema, a written explanation or a tool call with arguments. The Decisions API only returns probabilities, choices and scores, and your application runs any action they select.
- Does the Decisions API support Zero Data Retention?
- Yes. OpenAI's guide says the Decisions API supports Zero Data Retention and HIPAA use for eligible customers, data residency in all supported API regions, and regional processing in the United States and Europe.
Sources