Jev, launched by TypeSafe AI on September 15, 2026, is a System One model: instead of chatting, it answers one typed question at a time — pick an option, rate something on a scale, or say whether a statement is true — and returns a calibrated probability instead of a paragraph. No free text, no parsing an LLM's prose into an enum by hand. You get { "choice": "billing", "confidence": 0.94 } back, directly usable in an if statement.
This post covers what that actually means, the three question types Jev supports, and setup in both TypeScript and Python (they are not symmetric — see below). To inspect any response along the way, paste it into our JSON Formatter.
What a System One Model Is
TypeSafe's own docs put it plainly: "System One models are a class of AI models built to make fast, structured decisions that software can use directly." Where a general-purpose chat model answers an open-ended prompt with free-form text you then have to parse, a System One model answers a predefined question shape and returns a value your code can consume with no parser in between.
The docs are explicit this isn't just a formatting difference: "System One models do not write replies, produce code, or generate explanations of their reasoning." They're trained differently, too — "System One models are trained for calibrated decisions: their probabilities are optimized against outcomes to reflect uncertainty." In practice, the confidence value coming back isn't a vibe the model generated in text; it's a number meant to be thresholded on — route anything below 0.6 to a human, auto-handle anything above it.
The Three Primitives
Every question you ask Jev is one of three typed shapes.
Choice — "Which of these options?"
You give it named options with descriptions; it returns the best match plus a full probability distribution across every option. This is the one primitive TypeSafe's own docs show worked end-to-end in both languages:
// TypeScript
import { choice, TypeSafeClient } from "@typesafe-ai/sdk";
const client = new TypeSafeClient();
const response = 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,
}),
},
});
console.log(response.answers.category.choice);
// "billing"# Python
from typesafe_sdk import Choice, TypeSafeClient
with TypeSafeClient() as client:
response = client.system_one(
state="My running shoes arrived in the wrong size. Can I swap them for a size 10?",
questions={
"department": Choice(
instructions="Which team should handle this?",
criteria={
"returns": "Exchanges, wrong or damaged items",
"shipping": "Delivery status, delays, lost packages",
"billing": "Charges, invoices, payment problems",
},
),
},
)
print(response.answers["department"].choice)
# "returns"Both return the same shape:
{
"type": "choice",
"choice": "returns",
"confidence": 1.0,
"probabilities": { "shipping": 0.0, "returns": 1.0, "billing": 0.0 }
}Score — "Which level, on a described scale?"
You describe each rung of an ordered scale; it returns a probability-weighted position on that scale, not just the single most likely rung. TypeSafe's Python docs show a full worked example:
# Python
from typesafe_sdk import Score, TypeSafeClient
with TypeSafeClient() as client:
response = client.system_one(
state="The export button crashes the settings page in Safari. It works in Chrome, "
"but a few of our customers only use Safari.",
questions={
"bug_severity": Score(
instructions="How severe is the reported issue?",
criteria=[
"Cosmetic; no impact to functionality",
"Broken or degraded feature, but workaround exists",
"Blocking issue; no workaround exists",
],
),
},
)
print(response.answers["bug_severity"].score)
# 1.43The JavaScript docs list score()'s type signature (function score<T>(instructions, criteria): ScoreQuestion<T>) but don't show it called end-to-end, so this TypeScript version is assembled directly from that signature plus the same criteria array shown above — not copied from a worked JS example, because TypeSafe hasn't published one yet:
// TypeScript
import { score, TypeSafeClient } from "@typesafe-ai/sdk";
const client = new TypeSafeClient();
const response = await client.systemOne({
state: "The export button crashes the settings page in Safari. It works in Chrome, " +
"but a few of our customers only use Safari.",
questions: {
bugSeverity: score("How severe is the reported issue?", [
"Cosmetic; no impact to functionality",
"Broken or degraded feature, but workaround exists",
"Blocking issue; no workaround exists",
]),
},
});
console.log(response.answers.bugSeverity.score);Response shape:
{
"type": "score",
"score": 1.43,
"confidence": 0.35,
"legend": {
"0": "Cosmetic; no impact to functionality",
"1": "Broken or degraded feature, but workaround exists",
"2": "Blocking issue; no workaround exists"
},
"probabilities": { "0": 0.0, "1": 0.57, "2": 0.43 }
}Noul — "Is this true?"
The simplest primitive: a single probability that the answer is yes, where 0 means no and 1 means yes. No separate confidence field — with one probability value, there's nothing extra to summarize.
# Python
from typesafe_sdk import Noul, TypeSafeClient
with TypeSafeClient() as client:
response = client.system_one(
state="I have asked three times now. Can I please just talk to a real person?",
questions={
"is_human_escalation": Noul(
instructions="Is the customer asking for a human agent?",
),
},
)
print(response.answers["is_human_escalation"].noul)
# 0.99Same caveat as Score: TypeSafe's docs list noul()'s signature (function noul(instructions?, criteria?): NoulQuestion) without a full JS example, so this is assembled from that signature rather than copied:
// TypeScript
import { noul, TypeSafeClient } from "@typesafe-ai/sdk";
const client = new TypeSafeClient();
const response = await client.systemOne({
state: "I have asked three times now. Can I please just talk to a real person?",
questions: {
isHumanEscalation: noul("Is the customer asking for a human agent?"),
},
});
console.log(response.answers.isHumanEscalation.noul);Setup
Every path starts the same way: grab a key from console.typesafe.ai/keys and set it as TYPESAFE_API_KEY in your environment — every SDK reads it automatically, so it never appears in your code.
# TypeScript / JavaScript (Node.js 20+)
npm install @typesafe-ai/sdk# Python
pip install typesafe-sdk
# or: uv add typesafe-sdkNo SDK required if you'd rather call the API directly:
curl https://api.typesafe.ai/v1/systemone \
-X POST \
-H "Authorization: Bearer $TYPESAFE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"state": "Help! My payouts have been failing for 3 days.",
"model": "jev-latest",
"questions": {
"is_urgent": { "type": "noul", "instructions": "Does this convey urgency?" }
}
}'Use the model id jev-latest; the response reports the concrete pinned version that actually answered (jev-1.13.0 at the time of writing):
{
"model": "jev-1.13.0",
"answers": { "is_urgent": { "type": "noul", "noul": 0.95 } },
"usage": { "input_tokens": 296, "output_tokens": 20 }
}The two SDKs aren't symmetric
A reader coming from one language will guess wrong about the other — worth knowing up front rather than at runtime:
| TypeScript | Python | |
|---|---|---|
| Install | npm install @typesafe-ai/sdk | pip install typesafe-sdk |
| Primitives | lowercase functions — choice(), score(), noul() | capitalised classes — Choice, Score, Noul |
| Calling | await client.systemOne(...) (camelCase) | client.system_one(...) (snake_case) |
| Reading an answer | dot access — response.answers.category.choice | dict access — response.answers["is_urgent"].noul |
| Client variants | one Promise-based client | TypeSafeClient (sync) and AsyncTypeSafeClient (async with) both ship |
| Typing | answer types are inferred per-question from what you pass in | response.answers is a generic dict; typed .choices / .scores / .nouls convenience dicts are also available |
Note the package names differ in shape too — @typesafe-ai/sdk (scoped npm package) vs. typesafe-sdk (hyphenated on PyPI) — an easy thing to get wrong from memory, so copy them exactly rather than guessing.
Pricing, Limits, and What's Actually Documented
Jev is priced at $42 per billion input tokens ($0.042 per million) — output tokens aren't charged at all. Worth flagging: a search aggregator we checked while researching this post reported "$0.042 per decision," which is simply the per-million-token figure with the wrong unit attached. A typical System One call uses a few hundred tokens, so the real per-call cost is a small fraction of a cent, not four cents — estimate your own request size with our LLM Token Counter before trusting any aggregator number. TypeSafe also claims a "238x lower input price than Claude Fable 5.1" and, on its homepage, a benchmark of one workflow completing in 0.114s versus 8.566s for a comparable LLM call — both are TypeSafe's own comparisons, not independently verified, so treat them as vendor claims rather than general specs.
Each request is capped at 64k tokens total, with state plus the longest individual question limited to 32k tokens. Rate limits, as documented today, are 250,000 tokens/second and 1,200 requests/minute, with a note that they're "adjusting dynamically" — worth re-checking before you build capacity planning around a fixed number, since a product six days old is the most likely thing to have already changed its stated limits.
The JavaScript SDK exports typed errors you can catch specifically — AuthenticationError, RateLimitError, BadRequestError, APITimeoutError, UnprocessableEntityError, InternalServerError, and others, all extending a base TypeSafeError. The raw API returns matching HTTP status codes — 401 for bad credentials, 422 for a malformed request, 429 for rate limits, 529 when the service is overloaded — and recommends exponential backoff on 429/529, which the SDKs handle automatically by default.
When to Use It — and When Not To
A System One model fits anywhere you currently parse an LLM's free text into an enum, a rating, or a boolean by hand: ticket routing, moderation gates, RAG passage relevance filtering, confidence-gated automation (auto-handle above a threshold, escalate below it), or a cheap second opinion checking a more expensive model's output before it ships.
Here's the honest limit, and it's worth saying plainly rather than glossing over: a typed-decision model cannot explain why it chose what it chose the way a chat model can — there's no reasoning trace to inspect when it's wrong, only a probability. And that confidence number is only as trustworthy as its calibration is in practice for your data — verify it against real outcomes on a held-out sample before you gate production traffic on a threshold, don't assume the vendor's calibration claim transfers to your domain unchanged. It's also text-only (string, JSON object, or array of text values — no image, audio, or video input), and forcing a genuinely open-ended problem into Choice, Score, or Noul just because a System One call is cheap is a misuse of the shape, not a clever use of it.
Frequently Asked Questions
What is a System One model, in one sentence?
A model that answers a typed question — Choice, Score, or Noul — with a calibrated probability instead of free text, so your code can use the answer directly without parsing an LLM's prose.
Is Jev a replacement for a chat model like Claude or GPT?
No — they solve different problems. A chat model generates open-ended text, code, or explanations; Jev answers a predefined, typed question and returns a probability. Use Jev for the classification/rating/yes-no step inside a pipeline, not for anything that needs a generated reply.
How much does Jev cost per request?
$42 per billion input tokens, with output tokens free. Most System One requests use a few hundred tokens of input, so a typical call costs a small fraction of a cent — check your own request size with our token counter rather than trusting a flat per-decision figure from a third party.
Does the JavaScript SDK work the same way as the Python SDK?
No — same underlying API, different conventions. TypeScript uses lowercase helper functions (choice(), score(), noul()) and camelCase calls; Python uses capitalised classes (Choice, Score, Noul) and snake_case calls, plus both a sync and an async client. See the comparison table above before porting code between them.
For validating the JSON Jev (or any AI API) returns against a schema you define, our Structured Output Validator checks it client-side — nothing you paste leaves your browser.