A decision model is a model that answers typed questions about a piece of content — is this true, which of these options, where on this rubric — with a probability for every allowed answer, and writes no text. By 13 October 2026, eight vendors document one. This comparison covers what each vendor publishes today on its own pages: the endpoint, the question types, the limits, image support and the list rate. Where a vendor does not publish a figure, the table says so instead of borrowing one from an aggregator.
If you are new to the category, What is Jev? explains the model type in depth, and the cost article works through why input-only billing changes the arithmetic. This piece is about choosing between engines.
What the category has in common
Every engine here takes the same three ideas:
- State: the content to judge, usually a string, a JSON object or an array.
- Typed questions: a yes/no question (TypeSafe calls it a noul, OpenAI a predicate), a choice among options you define, or a score on an ordered rubric of levels you write.
- Probabilities as the answer: the probability of yes for a noul; the chosen option plus every option's probability for a choice; a probability-weighted level for a score, which can fall between two levels. Choice and score answers also carry a
confidenceon most engines12.
The billing model is shared too. Every vendor below that states a price charges for input tokens and does not charge for output, because there is no generated text to pay for32456. The cost of a decision is set by how much state and question text you send, and by how many questions you can ask about the same state in one request.
The two request dialects
TypeSafe, Cloudflare, Perplexity, Inception, Liquid, Upstage, Microsoft, OpenRouter
System One shape
- state: a string, object or array
- questions: a map of ids you choose
- types: noul, choice, score
- choice criteria: option name to description
- answers come back under your ids
GPT-6 Luna
OpenAI's Decisions shape
- input: a string or user messages with text and image parts
- questions: an array, each with a name
- types: predicate, choice, score
- choices: value plus description
- answers: an array echoing each name; refusals typed
Seven of the eight vendors accept TypeSafe's System One body, sometimes at a different path: a state, a model, and questions as a map from ids you choose to typed questions, with answers returned under the same ids. Cloudflare and Upstage name System One on their pages, and Microsoft calls its request pattern "similar to a system-one API"478.
OpenAI went its own way. Its POST /v1/decisions takes input (a string, or user messages with input_text and input_image parts) and questions as an array, each with a name, a type of predicate, choice or score, and instructions. Choices are objects with a value and a description; score levels have a label and a description. Answers come back as an array echoing each name, and a question the model declines comes back with type: "refusal"2.
The practical difference is small for a single engine and large for several: a question set written once in the System One shape runs on seven engines with a model name changed, while OpenAI's needs a translation layer.
The engines, vendor by vendor
| Vendor docs, read 2026-10-13 | Endpoint and shape | Published limits | Images | Input list rate (output not charged) |
|---|---|---|---|---|
| OpenAI GPT-6 Luna | POST /v1/decisions, OpenAI's own shape (predicate, choice, score); public beta | Not stated on the guide | Inline base64 data URLs only | $0.10 per 1M |
| TypeSafe Jev 1.13 | POST /v1/systemone (state + questions) | 255 options, 10 levels, 64k tokens per request | ○text only | $0.042 per 1M |
| Cloudflare Clef | Workers AI @cf/cloudflare/clef, System One body | 1–64 questions, 65,536-token context | Up to 4, data URLs | Clef $0.24, Flash $0.038, Omni $0.15 per 1M |
| Perplexity pplx-decider | POST /v1/decisions, System One questions | 1–128 questions, 255 options, 10 levels, 10 req/s | In the state array, data URLs | $0.02 per 1M (v1.1) |
| Inception Mercury Decide | POST /v1/decisions, System One questions | 255 options, 10 levels | Not offered | $0.02 per 1M |
| Liquid AI d1 | POST /decisions/v1/systemone | Up to 8 images; question limits not stated | Top-level array, paid d1 only | Not stated on the model page |
| Upstage Solar Decide | POST /v1/systemone, beta | 2–26 options, 512K context | Not documented | Not stated on the API page |
| Microsoft-Decision-1 | Foundry deployment, /providers/microsoft/v1/systemone | Not stated | Text or JSON state | Not stated on the how-to |
OpenAI: GPT-6 Luna on the Decisions API
POST /v1/decisions with gpt-6-luna, which the guide names as the only supported model. The API is in public beta, with general availability expected "in the coming weeks" and no date given. Input is $0.10 per million tokens, with no output, cache-read or cache-write charges; regional-processing premiums and long-context multipliers still apply. Images must be inline base64 data URLs: hosted URLs and file ids are refused. OpenAI says answers return about ten times faster than through the Responses API; it publishes no absolute latency, and the guide states no maximum number of questions, choices or levels2.
TypeSafe: Jev 1.13
POST https://api.typesafe.ai/v1/systemone, model jev-1.13.0, with jev-latest and jev-preview as aliases that currently point to it. $0.042 per million input tokens, output free. A request holds 64k tokens, and the state plus the longest question must fit in 32k. Rate limits are 100K tokens and 80 requests per second, which TypeSafe says may change without notice. Text only3. A choice takes up to 255 options and a score up to 10 levels1.
Cloudflare: Clef, Clef Flash and Clef Omni
Served on Workers AI as @cf/cloudflare/clef, with clef-flash selected through the model field. Cloudflare describes Clef as a 27B multimodal decision model. A request takes 1 to 64 questions inside a 65,536-token context shared with any images; up to four embedded PNG, JPEG or WebP images, each up to 4 MiB, are passed in a top-level images array that Cloudflare calls its extension to the System One API. Remote image URLs are not accepted4. The Workers AI pricing page lists input only: $0.24 per million for Clef, $0.038 for Clef Flash and $0.15 for Clef Omni9.
Perplexity: pplx-decider
POST https://api.perplexity.ai/v1/decisions with pplx-decider-v1.1-27b or pplx-decider-v1-27b. The body is System One's state and questions, with 1 to 128 questions, 1 to 255 options per choice and 1 to 10 levels per score (Perplexity advises at least two). Input must stay under 262,144 tokens, the body under 32 MiB, and the rate is 10 requests per second. Images go inside the state array as base64 image_url parts; Perplexity will not fetch an http or https URL10. The pricing page lists $0.02 per million input tokens for v1.1, with output free and no per-request fee5.
Inception: Mercury Decide
POST /v1/decisions with mercury-decide, System One questions, 1 to 255 options per choice and 1 to 10 levels per score; questions are evaluated independently against the shared state. The model does not serve chat completions, streaming or tool calls6. Input is $0.02 per million tokens; output tokens are reported but not charged. The models page lists no context window11.
Liquid AI: d1
POST https://api.liquid.ai/decisions/v1/systemone with d1, or d1:free, which is text only. Images go in a top-level images array: up to eight, under a 4.5 MB body, billed at 1.5 input tokens per 32 × 32 patch, and each question is charged for its text and every image. The model page publishes no limits on questions, options or levels, no context window and no price12.
Upstage: Solar Decide
POST https://api.upstage.ai/v1/systemone with solar-decide, marked beta with a warning that the schema may change before general availability. The context window is 512K tokens, large enough for a whole document as state. A choice takes 2 to 26 options, because the endpoint scores the single-token labels A to Z; a 27th option is a 422. Output tokens are not billed; the API page states no per-token price7.
Microsoft: Microsoft-Decision-1
A Foundry model you deploy yourself (GlobalStandard, or DataZoneStandard in selected regions), called at <your Foundry endpoint>/providers/microsoft/v1/systemone with Entra ID or an API key. The request's model is your deployment name, not the model name. The page documents noul, choice and score with System One bodies, and a candid list of limitations: scores move with the wording and order of questions and options, and calibration is strongest on familiar task types. It publishes no price and no limits on questions or options8.
OpenRouter as a second path
OpenRouter exposes POST https://openrouter.ai/api/v1/systemone in TypeSafe's shape, maps bare ids such as jev-latest into its typesafe/ namespace, and adds id, provider and usage.cost to the response. Its reference page documents no image input13. Which other vendors' decision models it lists changes often enough that you should check its catalogue directly.
What the vendors leave out
Read across the pages and the gaps are as useful as the numbers:
- No comparable accuracy. None of the pages publishes a score on a shared, independent benchmark. Some vendors cite their own evaluations elsewhere; none is a figure you can compare across engines.
- No latency figures. OpenAI gives a relative claim; Microsoft's own quickstart measures median latency on your examples instead of quoting one8.
- Prices missing for three engines. Liquid, Upstage and Microsoft document their models without a per-token price on the page. Aggregators list rates for some of them; those are the aggregator's prices, not the vendor's.
- Calibration is a claim to test. A probability is useful as a threshold only if, across many answers, 0.9 means right about nine times in ten. Modern neural networks are often poorly calibrated out of the box, and a simple rescaling such as temperature scaling usually repairs much of it14. Treat each vendor's calibration as something your evaluation confirms.
How to choose on your own labelled data
1 · a few hundred cases
Freeze a labelled set
Past decisions with known outcomes, hard and hostile cases kept in, split by class.
2 · same wording everywhere
Write one question set
Translate it once per dialect; keep options and levels identical across engines.
3 · pinned versions
Run every engine
Record the answer, the full probabilities, input tokens and wall time per case.
4 · per engine
Plot accuracy by confidence
Find the threshold above which each engine is right often enough to act alone.
5 · robustness
Shuffle option order
Rerun with options reordered and reworded; an answer that moves is a warning.
6 · cost per correct decision
Price the whole design
Input tokens × list rate, plus what the cases below threshold cost a person or a larger model.
The only comparison that settles which engine to use is one on your own decisions. A few hundred cases is enough to start:
- Freeze a labelled set. Past tickets, moderated posts or reviewed claims with known outcomes. Keep the hard cases and add hostile inputs: text written to steer the answer.
- Write the questions once. Same instructions, same options, same rubric levels on every engine. For OpenAI, translate the noul to a predicate and the option map to a list; change nothing else.
- Pin versions. Use
jev-1.13.0, notjev-latest, and the versioned id each vendor returns. A threshold tuned on one version is not guaranteed on the next3. - Record everything per case. The answer, the full probabilities, input tokens and wall time.
- Plot accuracy against confidence for each engine. The useful output is not one accuracy number but the threshold above which an engine is right often enough to act on alone, and the share of cases above it.
- Shuffle and reword. Rerun with options in a different order and lightly reworded. Microsoft warns that scores move with the wording and order of questions and options8.
- Price the design, not the call. Input tokens times the list rate, plus what the cases under the threshold cost when they go to a person or a larger model.
Running decision models through INFRO
INFRO is a control plane that sits between your code and the providers you already pay. Every decision call runs on your own account with the engine's provider, which bills you directly; INFRO charges nothing per decision, and nothing it sells is priced per token. INFRO connects every engine above — TypeSafe, OpenAI, Cloudflare, Perplexity, Inception, Liquid AI, Upstage, Microsoft-Decision-1 through an Azure Foundry deployment, and each of them through OpenRouter — and translates each provider's wire into one shape, so changing engines is a model name. The decision models page lists every model slug and how each is connected.
One endpoint, either dialect
POST /v1/systemone takes TypeSafe's body for every decision model (plus a top-level images array for engines that see images), described in the System One reference. POST /v1/decisions takes OpenAI's dialect, so OpenAI's SDK works with the base URL and key changed — and the model need not be OpenAI's:
import os
from openai import OpenAI
client = OpenAI(base_url="https://api.infro.io/v1", api_key=os.environ["INFRO_API_KEY"])
decision = client.decisions.create(
model="cloudflare/clef-flash", # or "gpt-6-luna", "typesafe/jev-1.13"
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": "Requests outside these categories."},
],
}],
)On a System One engine a predicate becomes a noul and a score level reads label: description; a question no engine answered readably comes back as OpenAI's refusal. Responses add id, usage.cost, usage.price_source, route, route_name, provider and connection. On a decision endpoint gpt-6-luna means GPT-6 Luna's decisions; a decision model named on chat completions is refused with 400 decision_model. A request with an image moves past text-only engines to its next fallback, and with none left is 400 images_unsupported.
Decision policies and confidence bands
For decisions you make repeatedly, a decision policy keeps the question, the meaning of each outcome, the thresholds, pins, a deadline and a fallback in a saved, versioned policy. Your code sends only the state to POST /v1/decisions/{slug}, or up to 500 items to POST /v1/decisions/{slug}/batch. The Decisions API reference has the full contract.
- 50% · bands.confirm (default 0.5): ask before acting
- 90% · bands.act (default 0.9): act without asking
- 100% · A pin answers 1
Each answer carries a band computed from its confidence: act at or above bands.act, confirm at or above bands.confirm, otherwise human. A pin decides by rule before any model call and answers with confidence 1. When the deadline passes or every connection fails, the policy's fallback answers with source: "fallback" and a fallback_reason; with no fallback, a missed deadline is 408 decision_deadline. Thresholds in the policy mean the cut-offs from your evaluation change without a deploy.
Failover between engines
Your code
INFRO
Engine A (your account)
Engine B (your account)
- Your code to INFRO: POST /v1/decisions/{slug} with the state only
- INFRO to INFRO: Pins checked first: a match answers with no model call
- INFRO to Engine A (your account): The policy's question, on your connection
- Engine A (your account) to INFRO: Error or timeout
- INFRO to Engine B (your account): Next target in the route
- Engine B (your account) to INFRO: Probabilities and confidence
- INFRO to Your code: outcome, band, confidence, usage.cost (estimate)
A policy, a guardrail check or a route classifier can name a route instead of a model, so a decision fails over across several keys of one provider, between a provider and OpenRouter, or between two vendors' engines, like any other INFRO request. One exception is deliberate: when an engine rejects the question set as invalid (400 invalid_request), the request is not retried on another key of the same provider, because every key validates alike. If you fail over across vendors, evaluate both engines on the same labels first and keep a threshold per engine: a 0.9 from one is not a 0.9 from another.
Cost per decision, as an estimate
Every response and every row in the request log carries usage.cost: what your provider will bill you for that call, at the vendor's list rate or at a rate you entered for your organization (usage.price_source says which). It is an estimate of the provider's charge, kept separate from your INFRO subscription; where no rate is known it is reported as unpriced, never as zero. That puts decision spend next to the rest of your AI traffic, grouped by the same metadata, so cost per decision — and, with your labels, cost per correct decision — is a query rather than a spreadsheet.
