docs
API

Jev — a decision model

Markdown

TypeSafe's Jev decision model answers typed questions about text or JSON: choosing an option, rating on a scale, or answering “yes/no” with probabilities. It is not a chat or text generation model.

Full guide
POSThttps://api.ailoot.ai/v1/systemone
Jev — a decision model
curl https://api.ailoot.ai/v1/systemone \
  -H "Authorization: Bearer $AILOOT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "jev-latest",
    "state": "Help! My payouts have been failing for 3 days.",
    "questions": {
      "is_urgent": {
        "type": "noul",
        "instructions": "Does this convey urgency?"
      }
    }
  }' 
200 OK
{
  "model": "jev-1.13.0",
  "answers": {
    "is_urgent": {
      "type": "noul",
      "noul": 0.95
    }
  },
  "usage": { "input_tokens": 296, "output_tokens": 20 }
}

Jev is a System One decision model from TypeSafe. It does not generate text or hold a conversation: you provide a state (state) — text or JSON — and a set of questions, and receive typed values with probabilities in response. Your code can use them directly to branch, sort, and route, without parsing free-form text.

All questions in a request are evaluated in parallel and independently against the same state. According to TypeSafe, adding questions has almost no effect on response time, and the questions do not interfere with one another.

ItemIn brief
Modeljev-latest — an alias for the latest stable version of Jev; catalog entry
MethodPOST /v1/systemone. This is not a chat endpoint: OpenAI, Anthropic, and Gemini formats are not compatible with Jev. The complete response arrives as a single JSON object
Accepted inputText only: a string, a JSON object, or an array of texts. Convert images, audio, and video to text first
Context64K tokens per request for state and all questions combined; state plus the longest question can contain up to 32K
LanguageAccording to TypeSafe, the model is most accurate in English. It accepts other languages with lower accuracy, so test it on your own data
PriceInput: $0.084 per 1 million tokens; output is free

Request

Authentication

  • Authorizationheaderrequired

    Your Ailoot key in the format Bearer sk-….

Request body

  • modelstringrequired

    jev-latest.

  • statestring | object | arrayrequired

    What to evaluate: a text string or JSON containing a customer inquiry, a database record, a conversation, or your application's current state. An object with clear field names is usually easier to work with than a single string.

  • questionsobjectrequired

    The questions. You choose the keys, and answers are returned under the same keys. The key does not affect the answer; the question itself is specified in instructions.

  • questions.*.typestringrequired

    noul, choice or score — see below.

  • questions.*.instructionsstring | object | arrayrequired

    The question itself. You can pass a long question with supporting data as an object: put the question in one field and the data in others, and refer to fields by name in backticks.

  • questions.*.criteriaobject | array

    Answer options, defined differently for each type: optional descriptions of “yes” and “no” for noul, a dictionary of options for choice, and an ordered list of levels for score.

Question types

TypeWhat it asksWhat it returns
noulWhether a statement is true: yes or nonoul — the probability of “yes,” from 0 to 1
choiceWhich of the supplied options fitschoice, probabilities, confidence
scoreWhere state falls on your scale of levelsscore, legend, probabilities, confidence

You can combine question types in a single request.

noul — yes or no

The field criteria is optional: you can use it to describe what “yes” (true) and “no” (false) mean. The answer noul — a number from 0 (no) to 1 (yes).

"is_urgent": {
  "type": "noul",
  "instructions": "Does this convey urgency?",
  "criteria": {
    "true": "Explicitly time-sensitive",
    "false": "No urgency expressed"
  }
}

choice — selecting an option

criteria — an “option → description” dictionary; if no description is needed, use null. Up to 255 options. In the response, choice — the most likely option, probabilities — the probability of each option (summing to 1), confidence — confidence from 0 to 1.

"department": {
  "type": "choice",
  "instructions": "Which team should handle this?",
  "criteria": {
    "billing": "Payments, invoicing, refunds",
    "technical": "Bugs, outages, integrations",
    "sales": "Pricing, upgrades, new customers"
  }
}

score — rating on a scale

criteria — levels ordered from lowest to highest, with no more than 10 (TypeSafe recommends at least two). In the response, score — a value weighted by the probabilities of the levels (it can fall between levels), legend — the level number and its description, probabilities and confidence. According to TypeSafe, score is suitable for comparison against a threshold, but not for deriving an exact number between levels.

"frustration": {
  "type": "score",
  "instructions": "How frustrated is the customer?",
  "criteria": ["Calm", "Frustrated", "Very angry"]
}

Response

  • modelstring

    The model version that answered. The jev-latest alias moves to newer versions over time. If you have calibrated confidence thresholds for a specific version, monitor this field.

  • answersobject

    One answer per question, under the same keys. Every answer has type, and choice and score also have confidence.

  • usageobject

    input_tokens and output_tokens. Only input tokens are charged.

Multiple questions in one request

Submit all questions about the same state in one request: they are evaluated in parallel, and state is sent only once. According to TypeSafe, in their example with 13 questions, one combined request cost less by a factor of 12.2 and was 10 times faster than 13 separate requests sent sequentially, with the same answers.

Break a complex judgment into simple questions and combine the answers in code. For example, instead of “evaluate this application,” ask separately about the market, feasibility, and differences from competitors. You can then adjust the weights in code rather than in the question text.

{
  "model": "jev-latest",
  "state": "Help! My payouts have been failing for 3 days.",
  "questions": {
    "department": {
      "type": "choice",
      "instructions": "Which team should handle this?",
      "criteria": {
        "billing": "Payments, invoicing, refunds",
        "technical": "Bugs, outages, integrations",
        "sales": "Pricing, upgrades, new customers"
      }
    },
    "frustration": {
      "type": "score",
      "instructions": "How frustrated is the customer?",
      "criteria": ["Calm", "Frustrated", "Very angry"]
    },
    "is_urgent": {
      "type": "noul",
      "instructions": "Does this convey urgency?"
    }
  }
}

When to use it

  • Routing. Send an inquiry to the right department or a request to the right handler: simple code, a large model, or a human.
  • Sorting and prioritization. Rate urgency, sentiment, and risk on a scale, with thresholds defined in code.
  • Moderation and checks. Check whether a message violates the rules, a source supports a quotation, or a document contains an answer to a question before passing the text on.
  • Scoring and ranking. Evaluate documents, candidates, or retrieved passages against your own rubric, and decide in code what moves forward.
  • Replacing fragile “return JSON” prompts. A call that returns typed values by design, rather than text you need to parse.

When not to use it

  • Chat, replies to users, and text or code generation. Jev does not generate text; for that, use text models.
  • A model for Claude Code, Cursor, and other agents. You cannot replace an agent's model with jev-latest: the agent needs a model that generates text and calls tools. You can call Jev from code the agent writes for you.
  • Arithmetic, counting, and date comparisons. According to TypeSafe, these operations are more reliable in code. Ask the model only for the semantic part—for example, extracting date components using choice.
  • Images, audio, and video. The model accepts only text; convert these inputs to text beforehand.

Price

Only input tokens are charged, as reported in the usage.input_tokens field of the response: $0.084 per 1 million. Output tokens are free.

The example request on this page (296 input tokens) costs less than $0.0001.

Before the request, Ailoot places a reserve on your balance and, after the response, charges you once based on actual usage — how it works.

Limits

ItemLimit
Entire request: state and all questions64K tokens
state together with the longest question32K tokens
Options in a single choiceup to 255
Levels in a single scorefrom 2 to 10
Inputtext only: a string, a JSON object, or an array of texts

Model limits are provided by TypeSafe. Your key and balance limits apply as they do for any Ailoot model: Errors and limits.

Errors

Errors use the standard Ailoot API format: a code, a clear message, and a Request ID. The most common errors for this method are:

CodeWhen it occursWhat to do
400 invalid_requestThe body failed validation: state, model, or questions is missing; type is unknown; choice has more than 255 options; or score has more than 10 levelsCorrect the request as described in the error message. It will fail again without a correction.
400 context_length_exceededstate and the questions together exceed the model limitFilter state in your code and keep only what the questions need
401 invalid_api_keyThe key is missing or invalidSend the key in the Authorization header
402 insufficient_balanceThere is not enough available balance for the reserveAdd funds to your balance
404 model_not_found, unsupported_endpointThe ID is incorrect or the model was called through the wrong method, such as /v1/chat/completionsCall jev-latest only through POST /v1/systemone
429 rate_limit_exceededToo many requestsWait for the number of seconds specified in Retry-After, then retry
503 model_overloaded, model_unavailableThe model is temporarily overloaded or unavailableIf X-Should-Retry: true, retry after the number of seconds in Retry-After; if false, check the Request ID in your history first
504 model_timeoutThe model did not respond in timeDo not send the request again until you have checked its Request ID in your history

For the full list of codes, see Errors and limits.

Still have questions? Send your Request ID and a description — we'll help you troubleshoot.Contact support