Mizan

System One models (Jev)

Jev, from TypeSafe AI, is not a chat model. It doesn't write text — it reads a piece of state, answers typed questions about it, and hands back structured values and probabilities your code can act on directly. It's built for the fast, high-volume decisions that sit inside real-time loops and pipelines, where an LLM is slow, expensive, and returns prose you then have to parse.

Overview

TypeSafe calls this class of model a System One model — a nod to fast, intuitive “System 1” thinking. A conventional LLM generates an answer one token at a time; Jev is non-autoregressive, so it produces every answer at once in a single parallel pass. That's why it responds in roughly 70–500 ms and costs a small fraction of a frontier LLM for the same kind of judgment call.

Because it can't generate free-form text, it also can't hallucinate a sentence or return malformed JSON: every answer is exactly the type you asked for. You get calibrated probabilities instead of a confident-sounding paragraph, so you can decide how sure is sure enough.

Mizan serves Jev on its own endpoint, POST /v1/systemone, under the model id typesafe/jev-latest. It uses your regular Mizan API key and wallet (or your own TypeSafe key, via BYOK), and shows up in your spend, logs, and limits like any other call. It does not work through /v1/chat/completions — there is no messages array and no completion text.

How it works

Every request has two parts:

  • state— the thing to evaluate. A string, an object, or an array: a support ticket, a game frame's sensor readings, a transaction record, a draft to review.
  • questions — a map of your own question ids to typed questions. Each one declares how it should be answered (yes/no, pick one, or rate on a scale) and gives plain-language instructions.

Jev evaluates every question against the state independently and in parallel, then returns one answer per question id. Asking five questions costs one round trip, not five, and the answers don't influence each other.

Request
curl https://api.app-mizan.com/v1/systemone \
  -H "Authorization: Bearer mizan_rt_..." \
  -H "Content-Type: application/json" \
  -d '{
    "model": "typesafe/jev-latest",
    "state": "Help! My payouts have been failing for 3 days.",
    "questions": {
      "is_urgent": {
        "type": "noul",
        "instructions": "Does this convey urgency?"
      },
      "topic": {
        "type": "choice",
        "instructions": "Which topic is this about?",
        "criteria": {
          "billing": "payments, payouts, invoices",
          "bug": "a technical defect",
          "other": "anything else"
        }
      },
      "anger": {
        "type": "score",
        "instructions": "How angry is the writer?",
        "criteria": ["calm", "mildly annoyed", "annoyed", "angry", "furious"]
      }
    }
  }'
Response
{
  "model": "jev-1.13.0",
  "answers": {
    "is_urgent": { "type": "noul", "noul": 0.95 },
    "topic": {
      "type": "choice",
      "choice": "billing",
      "confidence": 0.99,
      "probabilities": { "billing": 0.99, "bug": 0.01, "other": 0.0 }
    },
    "anger": {
      "type": "score",
      "score": 2.04,
      "confidence": 0.66,
      "legend": { "0": "calm", "1": "mildly annoyed", "2": "annoyed", "3": "angry", "4": "furious" },
      "probabilities": { "0": 0.0, "1": 0.18, "2": 0.6, "3": 0.22, "4": 0.0 }
    }
  },
  "usage": {
    "input_tokens": 402,
    "output_tokens": 71,
    "cost": 0.000016884,
    "balance_after_usd": 4.981234
  }
}

The model in the response is the concrete version that served the call (jev-latest always points at the newest). usage.cost and usage.balance_after_usd are added by Mizan, matching the fields on chat completions.

Question types

Three primitives, freely combinable in one request.

noul — yes/no

A boolean judgment, answered as a probability between 0 and 1 that the answer is true. The optional criteriaspell out what “true” and “false” mean for your case.

Question
"is_refund_eligible": {
  "type": "noul",
  "instructions": "Is this refund request within policy?",
  "criteria": {
    "true": "Order is under 30 days old and unused",
    "false": "Order is older than 30 days or has been used"
  }
}

choice — pick one

Select one option from a list you define. criteria maps each option key to a description. You get the chosen key, a confidence, and the full probabilities distribution across every option.

Question
"department": {
  "type": "choice",
  "instructions": "Which team should handle this ticket?",
  "criteria": {
    "billing": "Payments, invoices, refunds",
    "engineering": "Bugs and outages",
    "sales": "Pricing and plan questions"
  }
}

score — rate on a scale

Rate against an ordered rubric of 2–10 levels. The answer is a probability-weighted score (so it can fall between levels, like 2.04 above), plus a legend mapping numbers back to your labels and the probabilities per level.

Question
"risk": {
  "type": "score",
  "instructions": "How risky is this login attempt?",
  "criteria": ["safe", "low", "medium", "high", "critical"]
}

Calling Jev

It's a plain JSON POST with your Mizan key — no SDK required. Only model, state, and questions are read; anything else in the body is ignored. model accepts typesafe/jev-latest (canonical) or the bare jev-latest. There is no streaming — the whole answer arrives in one response.

Branching on the answers
const res = await fetch("https://api.app-mizan.com/v1/systemone", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.MIZAN_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    model: "typesafe/jev-latest",
    state: ticket,
    questions: {
      department: { type: "choice", instructions: "Which team owns this?", criteria: DEPARTMENTS },
      urgent: { type: "noul", instructions: "Does this need a human right now?" },
    },
  }),
})
const { answers } = await res.json()

// No parsing — plain typed values your code can branch on.
if (answers.urgent.noul > 0.8) page(answers.department.choice)
else if (answers.department.confidence < 0.6) sendToTriage()
else route(answers.department.choice)

Reading the answers

Each answer is keyed by your question id and carries a type matching the question:

  • noul answers hold a single number, noul, from 0 to 1.
  • choice answers hold choice (the winning key), confidence, and probabilities for every option.
  • score answers hold score, confidence, legend, and probabilities per level.

Treat the probabilities as the point of the model, not decoration. Act automatically when confidence is high, and escalate to a person or a stronger model when it isn't — that threshold is yours to set per decision.

When to use it

Reach for Jev when the output feeds code rather than a reader, and when latency or volume matters:

  • Routing and triage: send tickets, emails, or leads to the right team or queue.
  • Classification and moderation at scale, where a paragraph of reasoning is wasted.
  • Policy and eligibility checks: refund rules, risk scoring, escalation decisions.
  • Real-time control loops: game agents, robots, simulations, anything deciding many times per second.
  • A cheap first pass in front of a heavier model, escalating only the low-confidence cases.

Don't use it to write, summarize, explain, or hold a conversation — it can't generate text. For those, use a chat model through /v1/chat/completions.

Pricing & billing

Jev is billed at $0.042 per million input tokens with output tokens free — TypeSafe's published rate, passed through with no per-call markup, like every other Mizan model. The formula is simply input_tokens × $0.042 / 1M: output tokens are reported in usage.output_tokens but never add to the cost. Cost is debited from your wallet after each successful call, based on the token counts TypeSafe reports.

Input tokens are more than your state. Every request carries a fixed base of roughly 270 tokens for TypeSafe's own framing (about $0.000011), then your state, then your questions — each adds roughly 10 to 45 tokens depending on how much instructions and criteriatext it has. That's why a one-word state still reports around 270 input tokens. These figures are measured, not published by TypeSafe, so treat them as approximate; the exact count for every call is in usage.input_tokens and the exact charge in usage.cost. In practice a typical call costs a few hundredths of a cent, and batching several questions into one request is cheaper than separate requests because the base is paid once.

Failed calls (validation errors, upstream outages) are never billed. Each call is logged with its cost and latency and counts toward your key and project spend limits — see Limits and Wallet & billing.

Bring your own key

If you have your own TypeSafe account, connect its API key under Configuration → BYOK and Jev calls are served with it. It works exactly like BYOK for every other provider: a connection scoped to a project wins for that project's keys, otherwise a default connection marked “apply to all projects” is used, and if neither exists the call goes through Mizan's own TypeSafe account and your wallet.

On a BYOK call your Mizan wallet is not debited — TypeSafe bills your own account directly. The call is still logged with its cost and marked as BYOK, and still counts toward your key and project spend limits. Requests use the same body and response as above, minus usage.balance_after_usd. If TypeSafe rejects your key you get a 401 that says so, and a call is never silently re-routed to your wallet.

Limits

  • Context window of about 32,000 tokens for the state plus all questions.
  • At least one question per request.
  • Up to 255 options in a single choice question.
  • Between 2 and 10 levels in a score rubric.

Errors

Errors use the same { "error": { "message": "..." } } envelope as the rest of the Mizan API.

400Missing or unknown model, missing state, questions that isn't a non-empty object, or a question TypeSafe rejects (for example a score with more than 10 levels). The message names the problem.
401BYOK only: TypeSafe rejected the API key you connected. Fix or reconnect it under Configuration → BYOK.
402Your Mizan wallet doesn't have enough balance. Top it up and retry.
403The API key or its project has hit a spend limit.
422The model isn't available through Mizan (unknown or not yet priced), or TypeSafe rejected the request body's structure. The message names the offending field.
429Rate limit exceeded for this key. Retry with exponential backoff.
502 / 503TypeSafe is unreachable or overloaded. Safe to retry; failed calls are never billed.

Calling typesafe/jev-latest on /v1/chat/completions or /v1/messages returns a 400 that points you back here.

Limitations

  • Own endpoint only — not available on chat completions or the Anthropic-style messages API.
  • Not part of Auto Router, Switchboard, or model fallbacks, which all choose between interchangeable chat models.
  • Aman PII redaction, response caching, and tracing don't apply to these calls — they're built around chat messages. Don't send state you couldn't send to TypeSafe directly.
  • No streaming, and no text output of any kind.
  • Your state and questions are processed by TypeSafe AI, listed on our subprocessors page.