/docs

Using Jev

Jev evaluates a state against typed questions and returns structured answers: typed values and probability distributions your code can branch on. Here is how to run one.

Overview

Jev is TypeSafe's flagship model and the first System One model; JevStation is the workspace built around it. Large language models are built to produce text for people to read, so asking one for a judgement your code will consume means coercing text generation into structured output and parsing the result back. Jev works the other way round: send a state plus typed questions and it returns typed answers directly. No text generation, no parsing, no prose to interpret.

Quick start

Run an evaluation in the playground in three steps, then call the same model from your own code.

01

Paste the state

Open the playground and paste whatever Jev should judge: a support ticket, a review, a spec, or a JSON record. The playground calls the same contract your code will.

02

Ask your questions

Add one question per judgement and mix Choice, Score, and Noul in the same call. Every question is evaluated against the same state.

03

Read the answers

Each answer comes back under the id you chose, with its probability distribution and, for Choice and Score, a confidence value.

04

Call it from code

The playground is the same contract your code will call — design a question set there, then call it from your own backend. That endpoint is `POST /api/v1/systemone`, authenticated with an API key you create in Settings (`Authorization: Bearer sk_…`), and it consumes the same credits a playground run does. If you would rather talk to the model directly, without JevStation metering, TypeSafe's own API is the supported path.

Use Jev from an AI agent

Working with an AI coding assistant? Copy a complete integration brief — endpoint, auth, request and answer shapes, errors, costs and how to verify — and paste it into Claude Code, Cursor or any other assistant.

MCP server

The same evaluations are available as MCP tools over Streamable HTTP, authenticated with your API key and billed exactly like the HTTP API. Tools: jev_decide, jev_run_question_set, jev_list_question_sets, jev_route_model, jev_guard_tool_call, jev_moderate and jev_get_credits. For Claude Code:

claude mcp add --transport http jevstation https://jevstation.com/api/mcp \
  --header "Authorization: Bearer $JEVSTATION_API_KEY"

Agent Skills

Three skills teach an agent how to call Jev, design question sets and use Jev as a guardrail. Install them into ~/.claude/skills with:

curl -fsSL https://jevstation.com/skills/install.sh | sh

Prefer to read before running? The script only downloads /skills/jev-api/SKILL.md, /skills/jev-question-design/SKILL.md and /skills/jev-guardrails/SKILL.md.

Guides: Jev in open-source projects

Six independent GitHub projects, each with a step-by-step guide to creating a JevStation API key and calling Jev. They are not affiliated with JevStation.

All guides

Question types

TypeSafe exposes three AI primitives. Each asks a different kind of question and returns a different kind of answer.

Question typeGoalReturns
ChoiceChoose one option from a list you definechoice, probabilities, confidence
ScoreRate the state against an ordered rubricscore, probabilities, confidence
NoulIs this statement true?noul (0–1)

Atomic questions, composed in code

System One models work best when each question asks one specific, well-scoped thing: the kind of judgement a knowledgeable person could make in a few seconds given the right context. If a question would need extended reasoning, or weighs several independent factors, decompose it. Ask each factor separately and combine the answers with your own formula, so reprioritising later is a coefficient change in code rather than a prompt rewrite. Questions are evaluated in parallel and in isolation, so asking more barely changes response time and context does not rot across them.

Request parameters

ParameterTypeRequiredDescription
statestring | object | array✓The content to evaluate. A plain string for text, or structured data for chat logs, records, or the current state of your application.
modelstring (optional)✓Optional. Which decision model answers: jev (default, TypeSafe), clef-flash or clef (Cloudflare), pplx-decider (Perplexity Decider), luna-decisions (OpenAI GPT-6 Luna Decisions), ms-decision-1 (Microsoft-Decision-1), d1-ultra or d1 (Liquid AI). Clef and d1-ultra cost double credits. Upstream IDs such as typesafe/jev-latest are accepted; any other value returns an error instead of falling back to Jev.
questionsmap<string, Question>✓A map of typed questions. You choose each key and the matching answer comes back under it; the key is a label only and is never sent to the model. Choice needs at least two options, Score at least two ordered levels.
question_set_idstring (optional)✓Optional, instead of questions. The id of a question set you saved in the playground; only your own sets can be used. Send one of questions or question_set_id, not both.

Every question object shares instructions (what to decide or rate) and adds its own criteria: an option map for Choice, an ordered level array for Score, and optional true/false descriptions for Noul.

Answers

One answer per question, keyed by the ids you supplied. Choice and Score answers carry a confidence value derived from their probability distribution; Noul answers return a probability only.

choice

The highest-probability option, every option mapped to its probability, and a confidence value.

score

A probability-weighted value across your levels (it can land between them), the legend mapping each level back to its description, and confidence.

noul

The probability that the answer is yes, from 0 (no) to 1 (yes). Noul answers carry no confidence.

Every response also reports token usage for the request as usage.input_tokens and usage.output_tokens.

Confidence

The shape of a probability distribution is what tells you how certain the model is: concentrated on one outcome is confident, spread across several is not. The confidence value collapses that shape into a single number from 0 to 1, so you can threshold on it without doing the maths yourself. A useful starting pattern is three bands:

High confidence

Act automatically. The model has a clear read and you can proceed without human involvement.

Medium confidence

Proceed with caution. Ask the user to confirm, flag for review, or gather more information first.

Low confidence

Do not act. Route to a human, ask for clarification, or fall back to a different system.

Where you draw the boundaries depends on the stakes: gate a destructive action at a higher threshold than a read-only one.

Full example

One call, three questions, one response — no SDK required.

evaluate.ts
const res = await fetch("https://jevstation.com/api/v1/systemone", {
  method: "POST",
  headers: {
    Authorization: "Bearer " + process.env.JEVSTATION_API_KEY,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    state: "Hi, I've been trying to connect my Stripe account for 3 days and it keeps failing. I'm losing sales. Please help ASAP.",
    questions: {
      department: {
        type: "choice",
        instructions: "Which team should handle this?",
        criteria: {
          billing: "Payments, invoicing, refunds",
          technical: "Bugs, outages, integrations",
          sales: "Pricing, upgrades, new accounts",
        },
      },
      frustration: {
        type: "score",
        instructions: "How frustrated is the customer?",
        criteria: ["Calm", "Frustrated", "Very angry"],
      },
      is_urgent: {
        type: "noul",
        instructions: "Does this convey urgency?",
      },
    },
  }),
});

const { data } = await res.json();

data.answers.department.choice;      // "billing"
data.answers.department.confidence;  // 0.59
data.answers.frustration.score;      // 1.04
data.answers.is_urgent.noul;         // 0.99
data.credits.charged;                // 1
data.credits.remaining;              // 4,996
curl
curl -X POST https://jevstation.com/api/v1/systemone \
  -H "Authorization: Bearer $JEVSTATION_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "state": "Payouts have been failing for 3 days.",
    "questions": {
      "is_urgent": { "type": "noul", "instructions": "Does this convey urgency?" }
    }
  }'

Notes & limits

  • An evaluation is a single round trip: Jev returns answers, not a token stream, so a run either produces a complete result or fails cleanly.
  • Adding questions to a set costs extra input tokens but barely any extra latency, because they are evaluated in parallel against the same state.
  • Each run consumes credits: one for a standard evaluation, three once the state passes 8,000 characters or the set passes five questions. Clef doubles both (2 and 6); Jev and Clef-flash do not. The balance is checked before the model is called, and a failed or cancelled run is refunded.
  • Evaluations are scoped to the signed-in user; one account can never read another's.
  • Provider credentials are configured by the operator in the admin settings and never reach the browser.
  • On 429 or 529, retry with exponential backoff. The client SDKs already do this for you.