DEV Community

Yong Yu
Yong Yu

Posted on Originally published at yongboyu.hashnode.dev

OpenAI Decisions API Is GA: First /v1/decisions Shape, Free Output Tokens, and When to Prefer It Over Responses

Attributed compile + one small offline smoke test

Primary sources (OpenAI, 2026-10-22): Build more responsive apps with the Decisions API (OpenAI blog), Decisions (developer guide), Decisions API is now generally available with new updates (Community), GPT-6 Luna + Pricing for list rates

Also trending on: 掘金 AI 日报 2026-10-23 (OpenAI Decisions API GA callout)

Latency multiples, customer speedups, and cost-savings quotes are OpenAI's / customers'. This box has no OPENAI_API_KEY, so I did not call POST /v1/decisions. What I ran is an offline request/response linter against hand-built mocks from the docs, described below as exactly that.


OpenAI made the Decisions API generally available on 2026-10-22, powered by gpt-6-luna only. Same product category as Liquid's open d1 and Microsoft-Decision-1 (covered earlier as post #16): stop begging a chat model for JSON and ask a decision endpoint for a typed probability, choice, or score. Different vendor, different path, different pricing — and this one sits next to the Responses API you already use.

Chinese digests on 2026-10-23 led with the GA. The practical question for an applied-AI stack is narrower: when does /v1/decisions beat routing the same Luna call through Responses?

What GA added (vs beta)

From OpenAI's blog and guide, since public beta:

  • Up to 400 questions per request (was 200)
  • Prompt caching on shared input
  • Native input_json content parts
  • Images in question instructions (compare candidates against a shared reference)
  • Native GPT-Live integration
  • US / EU regional processing; ZDR for eligible customers

OpenAI's claim (label as vendor): Decisions is up to 10× faster than GPT-6 Luna via the Responses API for bounded answers. I did not measure that.

Three answer types

type you ask you get
predicate is this condition true? probability in [0, 1]
choice pick one of my options choice + per-option probabilities + confidence
score rate against ordered levels (2–10) probability-weighted level index

No free-form prose. That is the point. Your code thresholds the number and routes, gates, or escalates.

First request shape

Endpoint: POST /v1/decisions. Model field: gpt-6-luna only. Shared evidence goes in input (string or message array). Questions are an array (not Microsoft's name→object map from post #16).

from openai import OpenAI  # only if you have a key; I did not call this

client = OpenAI()
decision = client.decisions.create(
    model="gpt-6-luna",
    input="I was charged twice for my order.",
    questions=[
        {
            "type": "predicate",
            "name": "duplicate_charge",
            "instructions": "Does the message describe a duplicate charge?",
        },
        {
            "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."},
            ],
        },
        {
            "type": "score",
            "name": "severity",
            "instructions": "How severe is this issue?",
            "levels": [
                {"label": "Cosmetic", "description": "Appearance only."},
                {"label": "Workaround available", "description": "Task fails; another way works."},
                {"label": "Fully blocked", "description": "Task fails with no workaround."},
            ],
        },
    ],
)
# answers = decision.answers  # typed; threshold in your code
Enter fullscreen mode Exit fullscreen mode

Three habits before production:

  1. Always include an abstention option on choice (other / cannot_tell). Without it, junk still gets a department.
  2. Put reusable context in input, not in every question — that is what prompt caching discounts. Question content is outside the reusable prefix; OpenAI says the prefix needs ≥1,024 tokens to cache.
  3. Dependent decisions are separate requests. Independent checks (damage + category) can share one call; "if damaged, then repair type" needs a second call after you see the first answer.

For structured app state, pass input_json inside a user message instead of stringifying first — keys inside data are ordinary data, not messages.

Cost math (published list prices only)

OpenAI lists Decisions at $0.10 / 1M uncached input, $0.01 / 1M cached input, and no output-token charges. Cache writes follow Luna rates on the pricing guide: $0.125 / 1M (30m) and $0.25 / 1M (12h). GPT-6 Luna via Responses still lists $0.50 / 1M output on the model page — relevant only as a hypothetical if you had generated prose or JSON there instead.

Illustrative arithmetic (not a bill): 10,000 requests/day × 2,000 input tokens

path day cost (list)
Decisions, all uncached $2.00
Decisions, all cached reads $0.20
Hypothetical Responses Luna, same 2k in + ~150 out tokens $2.75

The free-output line is why decision endpoints look cheap for hot-path routing: you are not paying for a rationale you would throw away. Caching is where the bigger gap appears once a shared policy doc or reference image sits in input.

What customers told OpenAI (quotes, not my numbers)

Attributed to the GA blog:

  • Box (Biswaroop Palit): ~5× faster route selection on 30 certificate-of-insurance cases, same accuracy as Responses.
  • Datadog (AJ Stuyvenberg): 40× faster p95 scoring agent-generated rshell risk before remediating.
  • Ramp (René Sultan): 4× faster and 30% cheaper AI-cost attribution vs GPT-6 Luna.
  • Sierra (Ajeet Grewal): under 280 ms p95, ~3× faster and 90% lower cost per call.
  • Speak (Andrew Hsu): GPT-Live + Decisions cut time-to-next-action from 1.4s → 0.13s.

Treat those as launch anecdotes. Measure on your labeled tickets.

Light contrast with Microsoft-Decision-1

Same category, different shelf. Microsoft-Decision-1 (post #16) is a Foundry / OpenRouter systemone surface with noul / choice / score, list input around $0.042 / 1M, and a planned Qwen→MAI/OpenAI rebase. OpenAI Decisions is predicate / choice / score, $0.10 / 1M uncached, Luna-only, images + JSON + Live, and lives next to your existing OpenAI key. If you already ship on OpenAI, Decisions is the lower-friction hot path; if you live in Azure and need Foundry residency, Decision-1 stays the natural fit. Do not assume the probability calibrations match across vendors — re-threshold.

What I actually ran (offline)

No OpenAI key on this box, so I wrote a preflight that only checks shapes and list-price arithmetic:

  • A legacy messages body is flagged as the wrong API.
  • model: gpt-6-sol is rejected (Luna only).
  • A multi-question body with predicate + choice + score lints clean.
  • An input_json user-message body lints clean.
  • A two-option choice without abstention gets a warning.
  • 401 questions trips the GA 400 cap.
  • A hand-built mock answers array (shaped like the docs' illustrative excerpts) parses; a chat-completions mock raises ValueError: missing answers array.
  • The $2.00 / $0.20 / $2.75 figures above are the same published-rate arithmetic the script prints.

That is a smoke test of your client, not of Luna. Scripts: runs/25-decisions-api/ (preflight.py, run_output.txt).

When I'd prefer Decisions over Responses

  1. Hot-path classify / route / gate where the answer is one of a fixed set or a probability you threshold.
  2. Many independent questions over the same evidence (batch up to 400).
  3. Voice / Live loops that need a reaction without waiting for a full chat turn.
  4. Shared long prefix (policy, catalog, reference image) where cache reads dominate.

Keep Responses (or a stronger model) when you need generated text, tool-call arguments, or a custom JSON schema that is not a predicate/choice/score. Decisions does not replace writing. It stops you from using a writer for a multiple-choice question.

Wire it like any other decision model: log input, question definitions, answers, and the action you took; tune thresholds on labeled examples; escalate on low confidence or other. Then decide whether OpenAI, Microsoft, or an open d1 wins on your tickets — not on anyone's launch blog.


YongBo Yu · Toronto AI engineer · https://yongbo-yu.vercel.app · GitHub YongBoYu1

Top comments (0)