Close Menu
AIToday7

    Subscribe to Updates

    Get the latest creative news from FooBar about art, design and business.

    What's Hot

    OpenAI says GPT-6.1 Sol is dramatically better at migrating legacy code

    October 20, 2026

    Government tests cyber resilience in tabletop exercise

    October 20, 2026

    Anthropic Will Be The Last AI IPO Of 2026, As Industry Collapses

    October 20, 2026
    Facebook X (Twitter) Instagram
    Trending
    • OpenAI says GPT-6.1 Sol is dramatically better at migrating legacy code
    • Government tests cyber resilience in tabletop exercise
    • Anthropic Will Be The Last AI IPO Of 2026, As Industry Collapses
    • AI challenges maths by solving the unsolvable
    • Figma co-founder Dylan Field thinks MCP is not a perfect protocol
    • US orders federal agencies to remove China’s DeepSeek AI from their systems
    • Eka is worth $1.45B thanks to a physical AI model that has experts raving
    • Science Archives – Interesting Engineering
    Facebook X (Twitter) Instagram Pinterest Vimeo
    AIToday7
    • Home
    • AI News
    • Tech News
    • AI Guides
    • Chatbots
    • Cybersecurity
    • Gadgets
    • More
      • Generative AI
      • Startups
    AIToday7
    Home»AI Guides»A Practical Guide to OpenAI’s New Decisions API
    AI Guides

    A Practical Guide to OpenAI’s New Decisions API

    aitoday7By aitoday7October 11, 2026No Comments11 Mins Read
    Share Facebook Twitter Pinterest LinkedIn Tumblr Reddit Telegram Email
    A Practical Guide to OpenAI's New Decisions API
    Share
    Facebook Twitter LinkedIn Pinterest Email

    I recently covered TypesafeAI’s JEV in TDS (link at the end). JEV makes fast decisions, such as classifying content or choosing the next step in a workflow, and returns typed answers that software can use directly. The accompanying probabilities help an application decide whether to act on an answer or pass it to a person for review.

    The internet went a bit crazy over JEV, so it was no surprise to see rival products appear after its release. Among the most prominent was the Decisions API that OpenAI previewed at its recent DevDay and made available as a public beta shortly after.

    In this article, I’ll look at the new API, how to get it, and some practical use-case examples, and I’ll let you know whether I think it’s a JEV killer or whether TypesafeAI can sleep soundly at night.

    The background to JEV-like models

    Suppose you run an online shop. A customer writes to say that their keyboard arrived with three broken keys and asks for a replacement. Before anyone replies, your application needs to decide which team should handle the message.

    You could ask a language model to classify it and return JSON. But the application only needs a category and enough information to decide whether to trust that category. That process could also be relatively slow and costly if it had to handle 1000s of requests.

    OpenAI’s Decisions API gives that operation its own endpoint. Additionally, OpenAI claims its Decisions API can make decisions up to ten times faster than GPT-6 Luna, the LLM that Decisions is based on, through the Responses API. To explore how it works, we’ll walk through three Python examples and compare OpenAI’s approach with TypesafeAI’s JEV model.

    One major advantage of the Decisions API over JEV is that it can handle images. We’ll see an example of that later.

    What the OpenAI Decisions API returns

    A request supplies a model, some input and a list of questions. The current beta supports the gpt-6-lunaLLM. Questions share the input, which can contain text, images or both. 

    There are three question types:

    +-----------+--------------------------------------------------+------------------------------+| Type      | Question                                         | Result                       |+-----------+--------------------------------------------------+------------------------------+| predicate | Does the document contain a return deadline?     | A probability between zero   ||           |                                                  | and one                      |+-----------+--------------------------------------------------+------------------------------+| choice    | Which support queue should receive this message? | A selected value,            ||           |                                                  | probabilities and confidence |+-----------+--------------------------------------------------+------------------------------+| score     | How severely does this incident affect customers?| A score across ordered       ||           |                                                  | levels, probabilities and    ||           |                                                  | confidence                   |+-----------+--------------------------------------------------+------------------------------+

    These fields are defined in the SDK’s response types. A predicate doesn’t return a Boolean: your code chooses the threshold that turns its probability into an action.

    The API returns answers in question order. It can also refuse individual questions, so check an answer’s type before reading its other fields. 

    Defining the available answers is part of designing the application. Suppose your choices are only billing and delivery, but the customer asks about opening hours. Neither response is appropriate, but adding a general category gives the system a sensible place to route that request. Test the categories against real customer messages, including requests that don’t fit any of them.

    With the Decisions API, you choose from three question types: predicate, choice and score. Each returns a defined answer format, including probabilities. If you need to extract an invoice number, a customer name and a list of purchased items into your own JSON structure, use Structured Outputs with the Responses API.

    When to use the Decisions API and what it costs

    A support system processing thousands of messages may only need a queue name before passing each request to the right team. The Responses API can produce that answer, but the Decisions API provides a dedicated interface for questions with defined answers: a yes/no probability, a choice from a list or a score against a rubric.

    You send those questions to /v1/decisions and use the returned answers in your application logic. That makes it a useful option for routing messages, selecting a search index or choosing an agent’s next action from a permitted list.

    It also has separate pricing. At launch, OpenAI lists $0.10 per million input tokens, with no charges for output tokens, cache reads, or cache writes. Long-context multipliers and regional processing premiums still apply. 

    As a simple calculation, one million requests averaging 1,000 billable input tokens would cost $100 at that base rate. Include the questions and their descriptions when estimating input size.

    A task that needs a written explanation or an extracted object with arbitrary fields still needs a generation interface. It doesn’t make sense to squeeze an invoice extraction problem into twenty classification questions just because the endpoint is fast.

    Equally, keep simple rules in Python. If priority depends only on an order total exceeding £500, for example, compare the number directly in Python code itself. A model becomes useful when the input expresses something your rules can’t easily recognise, such as a customer describing the same fault in several different ways. Even then, the extra network call must save enough downstream work to justify its latency.

    Set up Python with the API

    The official openai-python repository added Decisions support in version 3.26.0. Install that version in your environment:

    c:> python -m pip install openai==3.26.0

    You’ll need an OpenAI API key. If you don’t already have one, you need to make sure you have registered with OpenAI and added a payment method with some credit to your account. Afterwards, go to https://platform.openai.com/home. On the left side of the screen, you’ll see an API keys link. Click on that and follow the instructions to create a new secret key.

    Set the OPENAI_API_KEY environment variable to your API key. Do that in PowerShell like this:

    c:> $env:OPENAI_API_KEY="your-api-key"

    Each example below is a complete, standalone Python program with its own imports and client setup.

    The SDK implementation exposes client.decisions.create() and sends the request to the /v1/decisions endpoint. This is the client implementation; inference runs on OpenAI’s service.

    Save each program using the filename shown in its section, then run it directly with Python. The three files work independently. Each program makes a billable API request when you run it.

    Code example 1: Routing a support request

    Our shop has three specialist queues and a general queue for anything that doesn’t fit. Create a file named decisions_route.py and add this code.

    from openai import OpenAIMODEL = "gpt-6-luna"def main() -> None:with OpenAI(timeout=20.0) as client:result = client.decisions.create(model=MODEL,input="My keyboard arrived with three broken keys. Can you replace it?",questions=[{"type": "choice","name": "queue","instructions": "Choose the queue for the customer's main request.","choices": [{"value": "returns", "description": "Damaged goods or replacements."},{"value": "billing", "description": "Charges or invoice errors."},{"value": "delivery", "description": "Missing or delayed deliveries."},{"value": "general", "description": "Everything else or unclear intent."},],}],)answer = result.answers[0]if answer.type == "refusal":print("Send to manual triage")elif answer.type == "choice":print(answer.choice, answer.confidence)queue = answer.choice if answer.confidence >= 0.8 else "manual_triage"print("Queue:", queue)if __name__ == "__main__":main()

    The (correct) output to my question about a broken keyboard was:

    c:> python decisions_route.pyreturns 1.0Queue: returns

    When I asked a different question in the code,

    Do you have a website I could look at?

    I got this output, which is correct again.

    c:> python decisions_route.pygeneral 0.8Queue: general

    The choice objects contain values and descriptions, as specified in the SDK’s request types. Descriptions let us distinguish damaged goods from a delivery that never arrived.

    The 0.8 threshold is illustrative. It isn’t an OpenAI recommendation, and it doesn’t establish an 80% success rate. Start with messages people have already classified, and measure mistakes at several thresholds before you decide on your threshold.

    Code Example 2: Check a document for missing information

    Suppose staff write return instructions in several formats. We want to flag instructions that omit either a deadline or a postal address. Create the filedecisions_document.py with this content.

    from openai import OpenAI, RateLimitErrorMODEL = "gpt-6-luna"def main() -> None:with OpenAI(timeout=20.0) as client:checks = {"deadline": "Does the text explicitly give a deadline for returning an item?","address": "Does the text explicitly provide a postal return address?",}result = client.decisions.create(model=MODEL,input="Return the item within 30 days. Email support to request our address.",questions=[{"type": "predicate", "name": name, "instructions": question}for name, question in checks.items()],)for answer in result.answers:if answer.type == "refusal":print(answer.name, "review required")elif answer.type == "predicate":status = "present" if answer.probability >= 0.9 else "check manually"print(answer.name, status, answer.probability)if __name__ == "__main__":try:main()except RateLimitError as exc:if exc.code == "credit_balance_exhausted":raise SystemExit("Your OpenAI API credit balance is exhausted. Add credits for ""the organisation associated with your API key at ""https://platform.openai.com/settings/organization/billing/ ""and then run this example again.") from Noneraise
    c:> python decisions_document.pydeadline present 1.0address check manually 0.0

    The wording is important. Being told to request an address isn’t the same as being given one. A search for the word address would miss that distinction.

    Both questions can share one request because neither depends on the other’s answer. If a later question needs an earlier result, make another request after inspecting that result.

    This checks whether information appears in the text. Checking whether an address exists or whether a deadline matches your business rules needs separate validation.

    Code Example 3: Inspect a product photograph

    Our last example uses three images of a parcel, one heavily damaged, one with slight damage and the other completely undamaged. We’ll see if the model can distinguish between damaged/undamaged. Here are the images I used. All were in .PNG format.

    Undamaged parcel
    Undamaged parcel
    Heavily damaged parcel
    Heavily damaged parcel
    Slightly damaged parcel
    Slightly damaged parcel

    Place all three images in the same location as the Python scripts, called, say, undamaged.png, heavy_damage.png and slight_damage.png. Next, create a file called decisions_image.py with this code.

    import base64from pathlib import Pathfrom openai import OpenAI, RateLimitErrorMODEL = "gpt-6-luna"PARCEL_IMAGES = ("undamaged.png", "heavy_damage.png", "slight_damage.png")def main() -> None:with OpenAI(timeout=20.0) as client:for filename in PARCEL_IMAGES:image_path = Path(__file__).with_name(filename)encoded = base64.b64encode(image_path.read_bytes()).decode("ascii")result = client.decisions.create(model=MODEL,input=[{"role": "user","content": [{"type": "input_text","text": "Image of a delivered parcel.",},{"type": "input_image","image_url": f"data:image/png;base64,{encoded}",},],}],questions=[{"type": "predicate","name": "visible_damage","instructions": ("Does the packaging visibly have a tear, ""hole or crushed corner?"),}],)answer = result.answers[0]if answer.type == "refusal":print(f"{filename}: Inspect the photograph manually")elif answer.type == "predicate":print(f"{filename}: Probability of visible packaging "f"damage: {answer.probability}")if __name__ == "__main__":try:main()except RateLimitError as exc:if exc.code == "credit_balance_exhausted":raise SystemExit("Your OpenAI API credit balance is exhausted. Add credits for ""the organisation associated with your API key at ""https://platform.openai.com/settings/organization/billing/ ""and then run this example again.") from Noneraise

    Images must use inline data URLs; ordinary web URLs and file IDs aren’t accepted. The endpoint supports up to 128 images per request, and its message input supports only the user role with text and image parts.

    c:> python decisions_image.pyundamaged.png: Probability of visible packaging damage: 0.05heavy_damage.png: Probability of visible packaging damage: 1.0slight_damage.png: Probability of visible packaging damage: 0.98

    That last result surprised me. The package was only slightly damaged, but the model identified it with high probability. That’s pretty impressive, though I accept that even slight damage can be visible and may lead to a high score.

    Summary: How Decisions compares with JEV

    JEV addresses a similar programming problem to the Decisions API. Its interface evaluates shared state using three primitives: Noul, Choice, and Score. Noul returns the probability of a yes/no answer, making it the closest equivalent to OpenAI’s predicate, which we used in examples 2 and 3. JEV’s choice primitive is largely the same as OpenAI’s, which we used in our first example.

    The products behind those interfaces differ. OpenAI exposes GPT-6 Luna through a specialised endpoint. TypeSafeAI describes JEV as a model built for decisions, with a parallel sampler and Reinforcement Learning for Calibrated Decisions, or RLCD.

    The practical comparison, as of early October 2026, looks like this:

    +-----------------------------+------------------+-------------------------------------------+| Feature                     | OpenAI Decisions | Jev 1.13                                  |+-----------------------------+------------------+-------------------------------------------+| Model                       | gpt-6-luna       | jev-1.13.0                                |+-----------------------------+------------------+-------------------------------------------+| Input                       | Text and images  | Text, including structured textual state  |+-----------------------------+------------------+-------------------------------------------+| Questions                   | Ordered array    | Map keyed by question name                |+-----------------------------+------------------+-------------------------------------------+| Yes/no                      | predicate ->     | noul question -> noul                     ||                             | probability      |                                           |+-----------------------------+------------------+-------------------------------------------+| Choose an option            | choice -> choice | choice -> choice, probabilities,          ||                             | probabilities,   | confidence                                ||                             | confidence       |                                           |+-----------------------------+------------------+-------------------------------------------+| Score against a rubric      | score -> score,  | score -> score, probabilities,            ||                             | probabilities,   | confidence, legend                        ||                             | confidence       |                                           |+-----------------------------+------------------+-------------------------------------------+|Price per million tokens     | $0.10            | $0.042                                    |+-----------------------------+------------------+-------------------------------------------+| Output-token charge         | None             | None                                      |+-----------------------------+------------------+-------------------------------------------+

    JEV’s listed input token cost is 58% lower, although different tokenisation and request sizes affect the bill. Its current context limits are 64,000 tokens for the complete request and 32,000 for the state plus the longest question. 

    TypeSafeAI reports 70–500 millisecond response times in its launch post. During my testing of the OpenAI Decisions API, response times often ran into multiple seconds, but I didn’t time a direct comparison between the two products.

    For both systems, Python still controls what happens next after the models return their results. Keep arithmetic and fixed business rules in ordinary code, and use a generative model when the task is more ambiguous and needs a written explanation.

    So, finally, do I think JEV should be worried? No, not yet, at least. In my experience, JEV has the advantage of speed; Decisions API has the advantage of interpreting images. But how long do you think it will be before JEV can process images? 

    You can read my original TDS article on JEV here.

    Post Views: 45

    Generative Ai Tools Jev Llm Applications Open Ai Open Ai Api Python
    Share. Facebook Twitter Pinterest LinkedIn Tumblr Email
    Previous Article5 Forgotten Windows Features That Are Pure Nostalgia
    Next Article What Are Vision-Language Models (VLMs)? How AI Connects Images and Words
    aitoday7
    • Website

    Related Posts

    AI Guides

    Zillow Launches Claude Connector for Listings, Tours, and Financing

    October 19, 2026
    AI Guides

    Dream Labs Raises $90M Seed to Bring Robot AI Across Different Machines

    October 19, 2026
    AI Guides

    My Father’s Final Weeks Revealed Why Canadian Healthcare Needs AI

    October 18, 2026
    Add A Comment
    Leave A Reply Cancel Reply

    Top Posts

    OpenAI says GPT-6.1 Sol is dramatically better at migrating legacy code

    October 20, 20260 Views

    Government tests cyber resilience in tabletop exercise

    October 20, 20260 Views

    Anthropic Will Be The Last AI IPO Of 2026, As Industry Collapses

    October 20, 20260 Views
    Stay In Touch
    • Facebook
    • YouTube
    • TikTok
    • WhatsApp
    • Twitter
    • Instagram
    Latest Reviews
    Uncategorized

    Architecting memory and storage in the AI era

    aitoday7September 4, 2026
    Uncategorized

    Roland Releases Melody Flip, an AI Melody-Generation Plug-In for DAWs

    aitoday7September 4, 2026
    Uncategorized

    Home Depot Labor Day Sale (2026): BOGO on Best Grills and Tools

    aitoday7September 4, 2026

    Subscribe to Updates

    Get the latest tech news from FooBar about tech, design and biz.

    Most Popular

    OpenAI says GPT-6.1 Sol is dramatically better at migrating legacy code

    October 20, 20260 Views

    Government tests cyber resilience in tabletop exercise

    October 20, 20260 Views

    Anthropic Will Be The Last AI IPO Of 2026, As Industry Collapses

    October 20, 20260 Views
    Our Picks

    Architecting memory and storage in the AI era

    September 4, 2026

    Roland Releases Melody Flip, an AI Melody-Generation Plug-In for DAWs

    September 4, 2026

    Home Depot Labor Day Sale (2026): BOGO on Best Grills and Tools

    September 4, 2026

    Subscribe to Updates

    Get the latest creative news from FooBar about art, design and business.

    Facebook X (Twitter) Instagram Pinterest
    • About Us
    • Get In Touch
    • Disclaimer
    • Privacy Policy
    • Terms and Conditions
    © 2026 AIToday7. All Rights Reserved.

    Type above and press Enter to search. Press Esc to cancel.