🛠️ For Builders · A technical deep dive
This one gets into code, architecture and building with AI. Prefer everyday tips? Explore For Everyone →
A robot that looks where you tell it
When I wrote about Jev back in September, decision models felt like a little corner of AI that only a few of us were playing with. A few weeks later that corner is growing quickly!!
One video that really caught my eye was OpenAI's launch video for their Decisions API. I really loved how they use the camera image to control a small robot from Hugging Face (a preview of their Microduck), hooking up GPT-Live and the Decisions API together. GPT-Live handles the conversation while the Decisions API looks at each camera frame and decides where the robot should look next, and it's really fast, you can see the robot react straight away.
When you think about it, that's pretty cool, because if you tried to do the same with a full LLM you just wouldn't get that reaction time. To me this really shows that speed is not just there so you have something amazing to demo, in a lot of scenarios it's actually a necessity for AI.
This is System One thinking. Imagine if we could only control our body with System Two, carefully reasoning through every single move. We'd never react in time to catch a ball or pull our hand away from something hot! In so many cases you need that fast reaction, not just when using Robots but also in business! With decision APIs there are loads of different scenarios where that matters, and it's not just OpenAI, they're now showing up from every direction.
TypeSafe launched Jev on 15 September. OpenAI previewed its Decisions API at DevDay on 29 September and made it generally available on 22 October. Microsoft launched Microsoft-Decision-1 on 9 October. And that's before you count Liquid, Cloudflare, AWS and a handful of open models that popped up in between.
So if you're building something today, the real question is:
Which decision API should I use, and what do I need to know before I wire it into my code?
I went through the docs, release posts and early tests for all three so you don't have to read hundreds of pages (or better I asked AI to do that for me). In this article we'll explore > how each one works > how you call it > the gotchas > and finally where I'd lean depending on situation.
Why do we need System One thinking anyway?
I won't repeat everything from my Jev article, but here's the short version.
TypeSafe borrowed the name from Daniel Kahneman's Thinking, Fast and Slow. System 1 is our fast, gut-feel thinking, System 2 is the slow, deliberate kind. For years we've been using System 2 models (big LLMs that write paragraphs) for jobs that are really System 1 jobs.
Think about how many of the AI calls in your app are actually decisions. Which team should get this ticket? Is this action safe? Most of us have been paying a chat model to write a sentence, waiting a second or two, and then parsing that sentence back into one word (we've all been there!).
A decision API flips that around. You give it some state and a few typed questions, and it gives you back an answer from the options you defined plus a probability. For us developers that means type safety, you don't pay for output tokens, and you get super, super fast answers, a couple of hundred milliseconds rather than seconds.
The bit I love most is that the confidence comes for free, and the early tests show it actually means something. That's what lets you decide when the app can act on its own, when it should ask the user, and when it should hand over to a person or a bigger model.
Here's what a few independent tests found when they checked Jev's confidence against what actually happened:
So when it's sure, it's almost always right, and when it's unsure, it's telling you something real. Compare that with a traditional LLM: you can ask it how confident it is, but that number is just more generated text, and nothing trains it to line up with how often the model is actually right. Of course these are other people's tests, so you still want to check the confidence on your own data before you trust a threshold.
The decision model decides what to do, the LLM decides how to say it.
Ok so now let's look into the other Decision APIs that are coming up.
So who are the three, and how do you call them?
Here's the quick lay of the land before we get into code. And mind you, besides these 3 there are many more coming online, but for the purposes of this article I just stopped at these 3.
At a high level they do the same job. However, let's look at how the API shape differs a little in syntax, what you can feed each one, and how the responses come back, because all of that is worth factoring in when you build.
Jev
Jev was the first one out and, for me, still the one that feels most purpose-built. You give it a state (a string, an object or an array) and a map of questions keyed by your own names. Answers come back under the same names.
import { choice, TypeSafeClient } from "@typesafe-ai/sdk";
const client = new TypeSafeClient();
const { answers } = await client.systemOne({
state: { document: "I was charged twice. Please fix this ASAP." },
questions: {
category: choice("What is this ticket about?", {
billing: null,
technical: null,
other: null,
}),
},
});
answers.category.choice; // "billing" | "technical" | "other"OpenAI Decisions API
OpenAI went its own way on the shape. You send one input (a string, or user messages that mix text and images) and an ordered list of questions, each with a name. Answers come back as a list in the same order.
const decision = await client.decisions.create({
model: "gpt-6-luna",
input: "I was charged twice for my order.",
questions: [{
type: "choice",
name: "category",
instructions: "What is this ticket about?",
choices: [
{ value: "billing", description: "Payments, invoices and refunds." },
{ value: "technical", description: "Problems using the product." },
{ value: "other", description: "Anything else." },
],
}],
});
const answer = decision.answers[0];
if (answer.type === "refusal") {
// send it to a human or a bigger model
} else if (answer.type === "choice") {
console.log(answer.choice, answer.confidence);
}Interestingly, OpenAI's API lead told TechCrunch that under the hood it's "plain old Luna", their small model tuned for speed, not a model trained specifically for decisions (at least not yet).
Microsoft-Decision-1
Microsoft did something smart here: rather than invent a new shape, Decision-1 speaks the same System One format as Jev. I didn't want to just trust the docs on this one, so I deployed it on Foundry and sent it the exact same state and questions I sent Jev. It came back with answers keyed by my question names, with the same fields as Jev, from https://<your-resource>.services.ai.azure.com/providers/microsoft/v1/systemone. Your Foundry key works in either an api-key header or Authorization: Bearer. You can also call it through OpenRouter.
Even better, TypeSafe's own SDK works against it, BUT it's not quite the "just change the URL and key" move I was expecting. Three things caught me out:
The model is your deployment name – leave it pinned to Jev (or use the catalogue name) and you get a 404.
The base URL needs
/providers/microsofton the end – the SDK adds/v1/systemoneitself.Turn off compression in the TypeScript SDK – it zstd-compresses any request of 1 KiB or more by default. Jev is happy with that, Foundry answers with a 400. A short test message will never show you this, a real document will!
const client = new TypeSafeClient({
apiKey: process.env.FOUNDRY_API_KEY,
baseURL: `${process.env.FOUNDRY_ENDPOINT}/providers/microsoft`,
defaultModel: "<your-deployment-name>",
compression: false,
});So moving between Jev and Microsoft is a few lines of config rather than a rewrite. That's pretty awesome, and it's exactly what happened with chat models when everyone started supporting the OpenAI-style API. This time the startup set the standard, Microsoft adopted it, and OpenAI is the odd one out.
One thing to watch though: on my test sentence ("I was charged twice. Please fix this ASAP.") both agreed it was a billing issue, but when I asked whether it was asking for a refund, Jev said about 0.7 and Microsoft about 0.25. One sentence tells you nothing about which model is better, but it does tell you that a threshold you tuned on one model won't automatically work on the other. If you switch, re-tune.
Are they all type-safe?
This is one of the first things I wanted to know, and the honest answer is yes and no :/ Let's split type safety into two layers.
Layer one is the API itself, and here all three are type-safe. The model can only answer with one of the options you declared, or a probability, or a score. There's no free text to parse and no half-broken JSON to clean up. That on its own is a huge win over prompting a chat model and hoping it returns billing and not "This looks like a billing issue!".
Layer two is your code, and this is where they differ.
Jev – the SDK infers the answer types from your questions. In the example above,
answers.category.choiceis typed as exactly"billing" | "technical" | "other", and answers are keyed by the names you gave them. Your editor tells you straight away if you check for an option that doesn't exist. Fitting, for a company called TypeSafe :)OpenAI – the official SDK tells you what kind of answer you got (choice, score, predicate or refusal), but the chosen value isn't narrowed to your list of options, and you match answers back to questions by position or by name. You also need to handle
refusal, which the others don't have. If you want the Jev-style experience, wrappers like LangChain'sOpenAIDecisions, xsAI and the Vercel AI SDK give you typed, name-keyed answers on top of it.Microsoft – there's no Microsoft SDK, but because it speaks System One you can use TypeSafe's own SDK against it (with the small config change above) and get the same typed answers as Jev. I tried both the Python and TypeScript SDKs and they worked fine.
Ow, so it's not just text, you can feed images as well?
This is the part that got me pretty excited. A few weeks ago decision models were text only. Now they're starting to see as well!!
OpenAI shipped image input from the start and it's now generally available. You pass images either inline as base64 or as a public image URL, alongside your text, and ask your questions about them. That's what powers the robot and the car game in their video. OpenAI's API lead also said Luna has been showing better calibration on image classification, and their next target is getting a decision down to around 60 ms, fast enough to make a call on every frame of a video 😍
Jev surprised everyone with Jev 1.14 on 14 October: it turns out the model was multimodal all along. Images are switched on with a
TypeSafe-Danger-Zone-Images: trueheader, and you can drop an image anywhere in the state, the question or even the criteria. It also added aboxquestion that returns a bounding box (find where the damage is, not just whether there's damage). BUT TypeSafe is very upfront that this is experimental and not ready for production yet.Microsoft-Decision-1 is still text only 🥺
Why does this matter so much for me? Think about applied AI outside the chat window or demo robots. So many real use cases start with a camera feed (or could do) or an image and need a quick decision on it: is this product damaged, is this the same item as the catalogue photo, is the person in the frame wearing a hard hat.
You've probably seen lots of computer use demos online, where an agent looks at a screen and decides what to do. Today most of those decisions go to a big model and take seconds each. Put a fast, cheap decision model on each step and the whole thing starts to feel much snappier. Same story for robots, drones, inspection cameras or a phone pointed at a shipping container.
I really think images in decision APIs are a big enabler for what we'll build next. That said, it's one reason to pick a provider, not the only one, so let's look at the gotchas.
So what's the catch with each one?
Every one of these has something you'll want to know before you commit.
Jev
Only on TypeSafe's servers – no open weights and no self-hosting, so you're tied to their infrastructure (it's also available through gateways like OpenRouter and Vercel).
Experimental features are flagged as such – images, longer context and
boxall sit behind "danger zone" headers. Great to play with, not something to put in front of customers yet.Pin your version –
jev-latestmoves when a new release comes out, so pin something likejev-1.14.0in production. TypeSafe has said it will give notice before old versions are retired.
OpenAI Decisions API
A different shape from everyone else – single input, ordered questions, answers in a list. If you might want to switch providers later, you'll need a small adapter.
Handle refusals – an answer can come back as
refusal, and your code needs to treat that as "send it somewhere else", not as an error.More expensive – roughly 2.4 times Jev's and Microsoft's price per token. Still cheap compared with a large model, but it adds up at volume.
The upside – it's generally available, comes with OpenAI's enterprise controls, takes images in production, and sits naturally next to GPT-Live if you're building voice.
Microsoft-Decision-1
Text only – no images for now.
Still marked Preview – when I deployed it, the Foundry catalogue listed the model as Preview, with an end date for version 1 of 4 February 2027. Worth knowing before you put it in front of customers.
The model can change under the same name – Microsoft says it will keep updating the weights and plans to rebase it on other models (its own MAI models and OpenAI's) while keeping the API the same. And every response just says
microsoft-decision-1, with no version, so you can't tell from the answer which version replied. Re-test your questions after updates.No Microsoft SDK – but TypeSafe's works with a few lines of config, as above.
The upside – it lives inside Azure, with Foundry's governance and EU data zone options, and it speaks the same format as Jev, which makes it an easy second provider. Same list price as Jev too, and in my test it counted far fewer input tokens for the same request, so the actual bill came out lower.
And one gotcha that applies to all of them: test the question, not just the model. Arize asked the same hallucination question two ways round ("is every claim supported?" versus "does it contain an unsupported claim?"). Jev and OpenAI gave consistent answers both ways, but some other decision models confidently answered the opposite question.
So which one would I pick?
In my Jev article I walked through four examples, and they really came down to a few things that make decision APIs special: type safety, paying for one input while asking as many questions as you want about it, and a confidence score that tells you how sure (or not sure) the model is about its answer. So the first thing I wanted to know was whether all three give you that same feature set.
So on the core feature set they're pretty much level, and for most text decisions all three will do a good job. But there are a few cases where I'd clearly lean one way.
You need images in production – go with OpenAI's Decisions API. It's the only one of the three with generally available image support today. Jev can do images too, but TypeSafe itself says that's experimental and not ready for production yet, and Microsoft is text only. So if your decision starts from a camera feed, a product photo or a screenshot, and it has to work for real customers, OpenAI is the safe bet right now. If you're just experimenting, or you need a bounding box, Jev's danger-zone images are fun to try.
Your company already lives in Azure – Microsoft-Decision-1. If your data, security reviews and procurement already run through Azure, this is the easiest one to get approved. You get Foundry's governance, EU data zone options and Azure billing, and because it speaks the System One format, you're not locked in: moving to Jev (or back) is just a few lines of config.
Text decisions where you want the most purpose-built option – Jev is my default. It was built only for decisions, the typed SDK is the nicest to work with, and its API shape is the one everyone else is copying.
Whichever you pick, write your code against the System One format (or go through a gateway like OpenRouter or Vercel AI Gateway) so that switching provider is a config change rather than a rewrite. These models are moving every couple of weeks, so keeping that door open matters.
Where to dig deeper
When you're ready to implement, these are the pages worth your time:
Jev – System One concepts, the TypeScript SDK (including images and
box) and the Jev 1.14 release post.OpenAI – the Decisions guide and the guide to connecting voice to Decisions.
Microsoft – the launch post, the Foundry catalogue page and the OpenRouter listing.
Comparing them – Arize's decision model benchmark, the best independent comparison I've found so far.
Special thanks to Claude Opus 5.5 for helping me dig through all the docs for this one 🫶


