Unofficial guide · Jev / TypeSafe

Jev API quickstart: your first call with curl, Python and TypeScript

By Ben (BenX) · Published · Last checked against official sources

This is an unofficial, plain-English walkthrough of your first call to Jev, the decision model from TypeSafe AI: the endpoint, a curl request, the Python and TypeScript SDKs, how to read the answer, and what the common errors mean. Every code sample comes from TypeSafe's official docs, linked at the bottom.

What is the Jev API?

Short answer: It is TypeSafe AI's HTTP endpoint, POST https://api.typesafe.ai/v1/systemone. You send some text (the state) plus typed questions, and Jev returns typed answers with probabilities instead of generated text.

Jev is the first "System One" model from TypeSafe AI, announced on 15 September 2026. TypeSafe describes System One models as models "built to make fast, structured decisions that software can use directly." Every request has three required parts:

  • state: the content to judge. A plain string, or a JSON object or array (for example a support ticket plus the order record).
  • model: which model answers. The docs use jev-latest.
  • questions: a map of questions you name yourself. Each one is a Noul (yes/no, returns the probability of yes), a Choice (pick one option from a set you define, up to 255 options), or a Score (rate against ordered levels you describe, 2 to 10 levels).

Answers come back under the same keys you used. All the questions in one request are evaluated against the same state, so you can batch several related questions into a single call.

What do I need before my first Jev API call?

Short answer: An API key and a way to send an HTTP request. For the official SDKs you also need Python 3.10 or newer, or Node.js 20 or newer.

  1. A key. TypeSafe's quickstart says to get your key from the TypeSafe console. Jev launched in early access, so you may not be let in straight away. You can also reach Jev through OpenRouter, Vercel AI Gateway or Cloudflare Workers AI with those platforms' own keys. How to get a Jev API key: four ways compares them.
  2. An environment variable. The official SDKs read the key from TYPESAFE_API_KEY. Keep it on the server; never ship it in browser code.
  3. Optional: an SDK. Python: pip install typesafe-sdk (or uv add typesafe-sdk). JavaScript/TypeScript: npm install @typesafe-ai/sdk.

If you only want to see what Jev does before writing code, TypeSafe's quickstart also points to a browser Playground (login required).

How do I call the Jev API with curl?

Short answer: POST JSON with state, model and questions to https://api.typesafe.ai/v1/systemone, with your key in an Authorization: Bearer header.

This is the one-question example from TypeSafe's quickstart. It asks a single Noul question about a support message:

curl -X POST https://api.typesafe.ai/v1/systemone \
  -H "Authorization: Bearer $TYPESAFE_API_KEY" \
  -H "Content-Type: application/json" \
  -d @- <<'EOF'
  {
    "state": "Hi, I've been trying to connect my Stripe account for 3 days and the integration keeps failing. I'm losing sales. Please help ASAP.",
    "model": "jev-latest",
    "questions": {
      "urgency": {
        "type": "noul",
        "instructions": "Does this message express urgency?"
      }
    }
  }
EOF

To ask more than one thing, add more entries under questions. Here is the request body from the same quickstart with one question of each type:

{
  "state": "Hi, I've been trying to connect my Stripe account for 3 days and the integration keeps failing. I'm losing sales. Please help ASAP.",
  "model": "jev-latest",
  "questions": {
    "department": {
      "type": "choice",
      "instructions": "Which team should handle this",
      "criteria": {
        "billing": "Payment or subscription issues",
        "technical": "Bugs or integration problems",
        "sales": "Pricing or account questions"
      }
    },
    "frustration": {
      "type": "score",
      "instructions": "How frustrated the customer appears",
      "criteria": [
        "Calm, just stating facts",
        "Frustrated but civil",
        "Very angry, strong language"
      ]
    },
    "is_urgent": {
      "type": "noul",
      "instructions": "The message conveys urgency or time-sensitivity"
    }
  }
}

Note: aiedu.guide has not yet run these examples against the live API with its own key. They are copied from TypeSafe's official quickstart (linked under Sources) so you can compare them yourself.

What does a Jev API response look like?

Short answer: A JSON object with the model version that answered, one typed answer per question under your keys, and token usage.

This is the example response TypeSafe publishes for the three-question request above:

{
  "model": "jev-1.13.0",
  "answers": {
    "department": {
      "type": "choice",
      "choice": "technical",
      "confidence": 0.78,
      "probabilities": { "technical": 0.85, "sales": 0.0, "billing": 0.15 }
    },
    "frustration": {
      "type": "score",
      "score": 1.0,
      "confidence": 1.0,
      "legend": {
        "0": "Calm, just stating facts",
        "1": "Frustrated but civil",
        "2": "Very angry, strong language"
      },
      "probabilities": { "0": 0.0, "1": 1.0, "2": 0.0 }
    },
    "is_urgent": { "type": "noul", "noul": 1.0 }
  },
  "usage": { "input_tokens": 392, "output_tokens": 65 }
}

How to read it:

  • Noul returns noul, a number from 0 (no) to 1 (yes). The API reference does not list a confidence field for Noul answers.
  • Choice returns the top option in choice, a probability for every option in probabilities (they sum to 1), and a confidence from 0 to 1.
  • Score returns score, a probability-weighted position across your levels (it can land between levels), a legend mapping level numbers to your descriptions, probabilities per level, and confidence.
  • model shows the versioned ID that answered (here jev-1.13.0), even if you sent an alias. Log it.

Your code decides what to do with the numbers. See what confidence threshold to use in our Jev vs LLM guide.

How do I call Jev from Python?

Short answer: Install typesafe-sdk, set TYPESAFE_API_KEY, create a TypeSafeClient and call client.system_one(state=..., questions=...).

From TypeSafe's quickstart. The client reads TYPESAFE_API_KEY from the environment and uses jev-latest unless you say otherwise:

pip install typesafe-sdk
from typesafe_sdk import Choice, Noul, Score, TypeSafeClient

client = TypeSafeClient()  # reads TYPESAFE_API_KEY; defaults to jev-latest

ticket = "Hi, I've been trying to connect my Stripe account for 3 days and the integration keeps failing. I'm losing sales. Please help ASAP."

response = client.system_one(
    state=ticket,
    questions={
        "department": Choice(
            instructions="Which team should handle this",
            criteria={
                "billing": "Payment or subscription issues",
                "technical": "Bugs or integration problems",
                "sales": "Pricing or account questions",
            },
        ),
        "frustration": Score(
            instructions="How frustrated the customer appears",
            criteria=[
                "Calm, just stating facts",
                "Frustrated but civil",
                "Very angry, strong language",
            ],
        ),
        "is_urgent": Noul(
            instructions="The message conveys urgency or time-sensitivity",
        ),
    },
)

print(response.answers["department"].choice)
print(response.answers["frustration"].score)
print(response.answers["is_urgent"].noul)

The SDK also has an async client, AsyncTypeSafeClient, and helper accessors such as response.nouls[...], response.choices[...] and response.scores[...] (see the Python SDK page). The SDK's default timeout is 10 seconds per HTTP operation.

How do I call Jev from TypeScript or JavaScript?

Short answer: Install @typesafe-ai/sdk (Node.js 20+), set TYPESAFE_API_KEY, create a TypeSafeClient and call client.systemOne({ state, questions }).

From TypeSafe's JavaScript SDK page. The package includes ESM, CommonJS and TypeScript declarations, and answer types are inferred from your questions:

npm install @typesafe-ai/sdk
import { choice, TypeSafeClient } from "@typesafe-ai/sdk";

const client = new TypeSafeClient(); // reads TYPESAFE_API_KEY
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);

The choice(), noul() and score() helpers build the question objects. You can also pass plain objects such as { type: "noul", instructions: "..." }.

Should I use jev-latest or jev-1.13.0?

Short answer: Use jev-latest to get started. Pin a versioned ID such as jev-1.13.0 once you have tuned confidence thresholds, because an alias moves when a new release ships.

From TypeSafe's Models page (checked 25 Sep 2026):

NamePoints toMeaning
jev-latestjev-1.13.0Most recent stable release. The SDK default.
jev-previewjev-1.13.0Most recent release, official or not. TypeSafe says no preview build is available right now.
jev-1.13.0(itself)A pinned version. Its answers do not change when a new alias target ships.

GET https://api.typesafe.ai/v1/models lists the names your account can use.

What does the Jev API cost, and what are the limits?

Short answer: TypeSafe lists Jev 1.13 at $0.042 per million input tokens ($42 per billion), with output tokens free. Listed limits are 250,000 tokens per second and 1,200 requests per minute, and TypeSafe says these are changing.

  • Price: charged per input token; output tokens are free. TypeSafe's launch post adds that it "can't prove" the price isn't subsidized and expects pricing to go down, not up.
  • Rate limits: 250,000 tokens per second / 1,200 requests per minute. The Models page warns these "can change without notice" while TypeSafe adds capacity. Going over either limit returns 429.
  • Context: 64k tokens per request in total; 32k tokens for the state plus the single longest question.
  • Input: text only (a string, JSON object or array of text). No image, audio or video input. English is where accuracy is currently best.

Prices on gateways can differ. Check each platform's own page (see the four ways to get a key).

What do Jev API errors like 401, 422, 429 and 529 mean?

Short answer: 401 means a missing or invalid key; 422 means the request body failed validation; 429 means you hit a rate limit; 529 means TypeSafe is temporarily overloaded. Retry 429 and 529 with exponential backoff.

StatusMeaning (per TypeSafe's API reference)What to do
401Missing or invalid API keyCheck the Authorization: Bearer header and the env var
422Body failed validation (missing field, malformed question)Read the response body; it names the offending field
429Rate limit exceededBack off and retry; honor retry-after if present
529Temporarily overloadedRetry after a short delay

The official SDKs retry 429 and 529 with backoff by default. In Python, errors are raised as exception classes such as TypeSafeAuthenticationError, TypeSafeUnprocessableEntityError, TypeSafeRateLimitError (with retry_after_ms) and TypeSafeAPITimeoutError. The JavaScript SDK has matching classes such as AuthenticationError and RateLimitError.

Can the Jev API generate text or chat?

Short answer: No. Jev returns typed decisions (Noul, Choice, Score) and does not write replies, code or explanations. Use an LLM for text.

TypeSafe's docs say plainly that Jev "does not generate text, write code, or hold a conversation", and that it is not a drop-in model for coding agents. If your task needs prose, pair Jev with an LLM. Our guide Jev vs LLM: when to use each covers how.

Next steps

Sources checked for this guide

Facts on this page come from these pages, checked on 25 Sep 2026. Jev launched in September 2026 and details change quickly, so check the official page before you rely on a number.