OpenAI Decisions API Guide (2026): GPT-6 Luna at $0.10 per 1M Tokens, With No Output Charge
On October 22, 2026, OpenAI moved its Decisions API out of public beta and into general availability, according to the company's API changelog. The beta had started on October 6. The idea is simple. Instead of asking a chat model to write something and then parsing it, you send text, images, or JSON plus a list of questions, and you get typed answers back: a probability, a pick from a fixed list, or a rubric score.
OpenAI says it runs about 10x faster than the Responses API for these jobs. The pricing is what caught my eye, though: $0.10 per 1M input tokens, and output tokens aren't charged. Here's how to call it, what it really costs, when batching beats caching, and where a normal chat model is still the better pick.
Key Takeaways
- OpenAI made the Decisions API generally available on October 22, 2026, after a public beta that began on October 6, 2026.
- The Decisions API (POST /v1/decisions) currently supports only the gpt-6-luna model and returns one of three typed answers: a probability, a choice, or a score.
- Decisions requests with gpt-6-luna cost $0.10 per 1M uncached input tokens, and output tokens are not charged.
- Cached input costs $0.01 per 1M tokens and cache writes cost $0.125 per 1M tokens, and caching requires a shared input prefix of at least 1,024 tokens.
- One Decisions request can carry up to 400 questions, up from 200 during the public beta.
What the Decisions API Actually Does
Every request has three parts: a model, shared input (a string, or an ordered array of messages, tool calls, and tool outputs), and a list of questions. The only supported model today is gpt-6-luna, which OpenAI describes as its most efficient model for focused, high-volume tasks. It has a 1,050,000-token context window. Questions come in three types:
- predicate returns a probability from 0 to 1 that a condition is true.
- choice picks one value from options you supply and returns per-option probabilities plus a
confidencefield. - score rates the input against ordered levels and returns a probability-weighted average, so a result can land between levels.
No free text comes back. If you need extracted fields, an explanation, or a tool call, use Structured Outputs or function calling on the Responses API. A classifier that can't ramble can't break your JSON parser either.
GA also added JSON input through input_json, images inside individual questions, org-level usage reporting, Private Link, and native GPT-Live integration. OpenAI lists Zero Data Retention and HIPAA support for eligible customers.
Your First Request
This is OpenAI's own routing example, trimmed. It sends a complaint and asks which department owns it.
curl https://api.openai.com/v1/decisions \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-6-luna",
"input": "I was charged twice for my order.",
"questions": [{
"type": "choice",
"name": "department",
"instructions": "Which department should handle this complaint?",
"choices": [
{"value": "billing", "description": "Payments, invoices, and refunds."},
{"value": "technical", "description": "Problems using the product."},
{"value": "shipping", "description": "Delivery and tracking."},
{"value": "other", "description": "Requests outside these categories."}
]
}]
}'
The response carries an answers array. For the request above you'd get "choice": "billing", a probabilities array, and a confidence value such as 0.93. Here's the Python version with a guard that sends shaky answers to a human:
from openai import OpenAI
client = OpenAI()
decision = client.decisions.create(
model="gpt-6-luna",
input="I was charged twice for my order.",
questions=[{
"type": "choice",
"name": "department",
"instructions": "Which department should handle this complaint?",
"choices": [
{"value": "billing", "description": "Payments, invoices, and refunds."},
{"value": "technical", "description": "Problems using the product."},
{"value": "other", "description": "Anything else."},
],
}],
)
answer = decision.answers[0]
if answer.type == "refusal" or answer.confidence < 0.80:
route = "human_review" # 0.80 is a placeholder, calibrate it
else:
route = answer.choice
Don't treat that confidence number as gospel. OpenAI's guidance is to set thresholds from labeled examples in your own app, based on what a false positive costs versus a false negative. Label 200 real tickets and see where 0.8 versus 0.9 actually lands before you auto-route anything.
What It Costs: The Pricing Math
On /v1/decisions with gpt-6-luna, uncached input is $0.10 per 1M tokens, cache reads are $0.01 per 1M, cache writes are $0.125 per 1M, and output is not billed. Inputs above 272K tokens get a 2x multiplier on input and cache rates. Regional processing adds a 10% premium where available.
| Model / endpoint | Input (USD per 1M) | Cached input (USD per 1M) | Output (USD per 1M) | Context window |
|---|---|---|---|---|
| gpt-6-luna via /v1/decisions | $0.10 | $0.01 (writes $0.125) | $0 (not charged) | 1,050,000 tokens |
| gpt-6-luna via Responses API | $0.10 | $0.01 (writes $0.125) | $0.50 | 1,050,000 tokens |
| GPT-6.1 Sol via Responses API | $2.00 | $0.10 | $10.00 | 1,050,000 tokens |
| DeepSeek-V4.1-Flash-1017 (off-peak) | $0.15 | $0.003 | $0.60 | 1,000,000 tokens |
| MiniMax M3.1 Flash | $0.15 | $0.015 | $0.60 | 1,000,000 tokens |
DeepSeek's peak-hour rate is double the off-peak figure. Say you triage 1,000,000 support tickets, each averaging 600 input tokens including the questions. That's 600M input tokens. These are my assumptions, not benchmarks:
- Decisions API: 600M × $0.10 per 1M = $60.
- gpt-6-luna on the Responses API, 20 output tokens each: $60 + $10 = $70.
- Same, but 200 output tokens each (reasoning defaults to medium): $60 + $100 = $160.
- DeepSeek-V4.1-Flash-1017 off-peak, no thinking, 20 output tokens: $90 + $12 = $102, or about $204 at peak rates.
The gap comes almost entirely from output and reasoning tokens. Run your own numbers through the token counter and the API cost calculator before you commit.
Batch Questions Before You Cache Anything
Most people reach for prompt caching first. Try batching first. Take a 20,000-token contract and 50 yes/no questions of about 100 tokens each:
- One request, 50 questions: 25,000 tokens × $0.10 per 1M = $0.0025.
- 50 separate requests, no cache: 1,005,000 tokens = $0.1005.
- 50 separate requests with caching: one $0.0025 write, 49 reads of 20,000 tokens at $0.01 per 1M ($0.0098), plus roughly $0.0005 of question tokens = about $0.0128.
Batching is about 5x cheaper than caching here. The catch, per OpenAI's docs: decisions that depend on an earlier answer need separate requests. Use caching when questions arrive at different times. The shared prefix needs at least 1,024 tokens and must stay identical between calls. Verify hits in usage.input_tokens_details.cached_tokens.
import OpenAI from "openai";
const client = new OpenAI();
const decision = await client.decisions.create({
model: "gpt-6-luna",
input: contractText, // shared evidence, cached automatically at 1,024+ tokens
questions: [
{ type: "predicate", name: "auto_renews",
instructions: "Does the contract renew automatically?" },
{ type: "predicate", name: "uncapped_liability",
instructions: "Is the vendor's liability uncapped?" },
// ...up to 400 questions per request
],
});
for (const a of decision.answers) {
if (a.type === "predicate") console.log(a.name, a.probability);
}
Decisions vs the Alternatives
| Option | Best for | Price (input / output per 1M) | Key limitation |
|---|---|---|---|
| OpenAI Decisions API (gpt-6-luna) | Classifying, routing, and scoring text, images, or JSON in one request | $0.10 / $0 (not charged) | Only gpt-6-luna is supported, and answers are limited to probability, choice, or score |
| Responses API with Structured Outputs (gpt-6-luna) | Extracting fields or returning explanations in your own JSON schema | $0.10 / $0.50 | Output and reasoning tokens are billed, and OpenAI says it is slower than Decisions for typed answers |
| DeepSeek-V4.1-Flash-1017 | Cheap text labeling off-peak with a 1,000,000-token window | $0.15 / $0.60 off-peak | Peak-hour rates are double, and you prompt for labels and parse them yourself |
| MiniMax M3.1 Flash | Long-context tasks that benefit from always-on thinking | $0.15 / $0.60 | Thinking is always on, so even simple labels consume output tokens |
My take: for high-volume routing and moderation, Decisions is the first thing to benchmark, because the cost model is so lopsided. For anything that needs a sentence of reasoning back, it's the wrong tool.
Gotchas Worth Knowing
- One model only. There's no fallback inside the endpoint, so build your own retry path.
- Handle refusals. Answers can come back with
type: "refusal". Check for it before readingchoice. - Add an "other" option. OpenAI recommends a catch-all choice so odd inputs reach a review queue.
- Don't assume a gateway forwards it.
/v1/decisionsis brand new, so confirm any proxy actually supports it with a real call. If you route other traffic through KissAPI, its OpenAI-compatible chat endpoint is a handy way to run a cheaper fallback classifier on another model.
Sources: OpenAI API changelog (Oct 22, 2026), Decisions guide, and the GPT-6 Luna model page.
Need a Second Route for Your Classification Pipeline?
Create a free account at api.kissapi.ai/register and keep an OpenAI-compatible endpoint ready for the parts of your stack that Decisions doesn't cover.
Start FreeFrequently Asked Questions
What is the OpenAI Decisions API?
It's an endpoint (POST /v1/decisions) that evaluates text, images, and JSON and returns typed answers: a probability that a condition is true, a choice from a fixed set, or a score against a rubric. It became generally available on October 22, 2026, and currently supports only the gpt-6-luna model.
How much does the OpenAI Decisions API cost?
With gpt-6-luna, uncached input costs $0.10 per 1 million tokens, cached input costs $0.01 per 1 million tokens, and cache writes cost $0.125 per 1 million tokens. Output tokens are not charged. Inputs over 272,000 tokens use a 2x multiplier on input and cache rates, and regional processing adds a 10% premium where available.
When should I use the Decisions API instead of Structured Outputs?
Use Decisions when you only need a classification, a routing choice, a yes/no probability, or a rubric score. Use Structured Outputs on the Responses API when the model must generate an object that follows your own JSON schema, such as extracted fields or a written explanation, and function calling when you need a tool call.