# Jev API: integration, question design, scenario examples, and common errors for the decision model Source: https://ofox.ai/docs/develop/models/jev TypeSafe Jev is a **decision model**. It does not generate text; it answers only questions defined in advance. A request provides the content to be evaluated and a set of questions, and the model returns a structured answer with probabilities for each question, so that the application can branch directly on the result. - [Quick start](#quickstart) — Prepare the connection details and make the first call. - [Question design](https://ofox.ai/docs/develop/models/jev/writing) — Option design and the response fields, and how to avoid common misjudgments. - [Production readiness](https://ofox.ai/docs/develop/models/jev/production) — Confidence thresholds, cost, and input limits. - [Scenario examples](https://ofox.ai/docs/develop/models/jev/scenarios) — Ticket routing, content moderation, RAG filtering, structured decisions. - [Project integration](https://ofox.ai/docs/develop/models/jev/assistant) — Integration through a coding assistant, or migration from TypeSafe. - [Common errors](#errors) — Causes of and resolutions for errors and unexpected results. ## Use cases **Key point**:Use Jev when the application must execute different logic based on a decision; use a chat LLM when text intended for human readers must be generated. **Suitable for**: - Classification and routing: the team responsible for a ticket, or the category of a user's intent. - Yes/no decisions: whether content contains personal information, is a refund request, or is a prompt injection. - Scoring and ranking: urgency, relevance, sentiment intensity, and filtering of retrieval results. - Quality control of LLM output: whether a response is on topic or violates a policy. **Not suitable for**: - Generating text, summaries, translations, or code. - Image decisions (Jev accepts only text and JSON input; for image decisions, use [GPT-6 Luna](https://ofox.ai/docs/develop/models/gpt-6-luna)). - Open-ended questions whose answers cannot be defined in advance as options or levels. Comparison with a chat LLM plus JSON output: | | Jev | Chat LLM + JSON output | |---|---|---| | Returned values | Limited to the predefined options or levels | May return values outside the options; additional validation is required | | Uncertainty | Each answer includes probabilities; choice and score also include confidence | Usable probabilities are generally not provided | | Multiple questions | Answered together in a single request that shares one input | Must be combined into one prompt or sent as multiple calls | | Billing | Input tokens only; output is not billed | Both input and output are billed at chat model rates | ## Quick start **1. Prepare the connection details**: Create an API key in the [OfoxAI console](https://app.ofox.ai/manage/api-keys) and use the following values: **Connection details** - Base URL: `https://api.ofox.ai/v1` - Model ID: `typesafe/jev-latest` — jev-latest is also accepted - Endpoint: `/v1/decisions` — POST; /v1/chat/completions is not applicable **2. Install the SDK**: When calling through the official OpenAI Python SDK, install a version that includes `client.decisions`: ```bash filename="Terminal" pip install -U openai ``` **Note**:If `AttributeError: 'OpenAI' object has no attribute 'decisions'` occurs at runtime, the SDK version is outdated; run the command above to upgrade (`openai` 3.31.0 has been tested and works). Without the SDK, the API can also be called with the cURL example below. **3. Make the call**: **Python** ```python filename="quickstart.py" import os from openai import OpenAI client = OpenAI(base_url="https://api.ofox.ai/v1", api_key=os.environ["OFOX_API_KEY"]) r = client.decisions.create( model="typesafe/jev-latest", input="Customer message: I was charged twice, nobody has answered my two emails, and I need a refund today.", questions=[{"type": "predicate", "name": "is_frustrated", "instructions": "Is the customer frustrated?"}], ) print(r.answers[0].probability) # 0.98 ``` **cURL** ```bash filename="Terminal" curl https://api.ofox.ai/v1/decisions \ -H "Authorization: Bearer $OFOX_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "typesafe/jev-latest", "input": "Customer message: I was charged twice, nobody has answered my two emails, and I need a refund today.", "questions": [ { "type": "predicate", "name": "is_frustrated", "instructions": "Is the customer frustrated?" } ] }' ``` Example response: ```json { "model": "typesafe/jev-latest", "answers": [{ "type": "predicate", "name": "is_frustrated", "probability": 0.98 }], "usage": { "prompt_tokens": 302, "completion_tokens": 23, "total_tokens": 325 } } ``` `probability` is the probability that the answer is "yes"; 0.98 indicates that the model considers it highly likely that the customer is frustrated. To apply this to a specific use case, replace `input` with the actual content and `questions` with the actual questions. ## Question types Select the question type according to the form of the required result: | Required result | Question type | Fields to provide | Returned fields | |---|---|---|---| | Yes or no | `predicate` | The question; optionally `criteria` defining what "yes" and "no" mean | `probability`: the probability of "yes" | | One of several options | `choice` | `choices`: 2–255 options | `choice`, per-option probabilities, `confidence` | | Degree | `score` | `levels`: 2–10 levels ordered from low to high | `score`, per-level probabilities, `confidence` | Examples: "Is this a refund request?" uses predicate; "Which team should handle it?" uses choice; "How urgent is it?" uses score. All three questions can be placed in the same request, and all answers are returned at once. After selecting a question type, review the questions and options against [Question design](https://ofox.ai/docs/develop/models/jev/writing). ## Common errors | Symptom | Cause | Resolution | |---|---|---| | `AttributeError: 'OpenAI' object has no attribute 'decisions'` | The OpenAI SDK version is outdated | Run `pip install -U openai` and retry | | 400 `endpoint_not_supported`, with the message `Please use /v1/decisions instead` | Jev was called as a chat model through `/v1/chat/completions` | Call `/v1/decisions` instead | | 400 `Invalid request payload` | The TypeSafe native format (`state`, `questions` as an object) was used on `/v1/decisions` | Use `input` and `questions` as an array, or call `/typesafe/v1/systemone` instead | | 400 `questions are required for decision` | `questions` is empty | Provide at least one question | | 400 `question "a" has kind choice and requires criteria options` | A choice question has no `choices` | Add the options | | 400 `Too many score levels. Must have at most 10 levels.` | A score question has more than 10 levels | Merge levels | | 400 `max_tokens_exceeded` | The input exceeds 64K tokens | Split long documents, or send only the relevant parts | | 400, with `input_image` and `Typesafe cannot read` in the error message | An image was sent to Jev | Remove the image, or use a model that supports images | | 404 `model_not_found` | The model ID is incorrect | Use `typesafe/jev-latest` | | The request succeeds, but the answer is clearly wrong and confidence is high | The choice options do not cover the actual case | Add a "none of the above" option and improve the option descriptions; see [Question design](https://ofox.ai/docs/develop/models/jev/writing) | | Answers lack `name` and cannot be matched to questions | The questions have no `name` | Set a `name` for every question | For the complete list of errors, see [Decisions API · Common errors](https://ofox.ai/docs/api/decisions#errors). ## Official documentation - [TypeSafe · Documentation](https://docs.typesafe.ai/) - [TypeSafe · Cookbooks](https://docs.typesafe.ai/cookbooks) ## FAQ **How does Jev differ from having an LLM output JSON?** Jev answers only within the given options and levels and never returns values outside that range. Each answer includes probabilities, and choice and score answers also include confidence, which can be used directly for thresholds. JSON output from an LLM requires additional validation and generally does not provide usable probabilities. **Which should be used, /v1/decisions or /typesafe/v1/systemone?** /v1/decisions is recommended for new projects, as it can be called directly with the OpenAI SDK. Projects that already use the TypeSafe SDK or its official sample code can use /typesafe/v1/systemone, changing only the base URL. **How is Jev billed?** Only input tokens are billed; output is not billed. Rates are listed on the model page. Multiple questions in the same request share one input, so combining questions into a single request reduces cost. **Does high confidence mean the answer is always correct?** Not necessarily. When the options do not cover the actual case, the model still selects one of the available options, and confidence may be high. Choice questions should therefore include a fallback option such as "none of the above", and results should be validated against human-labeled samples. **What does a score of 1.43 indicate?** The score is a probability-weighted value across levels, which are numbered from 0. A value of 1.43 lies between level 1 and level 2, closer to level 1; the probability of each level is given in probabilities. **Is content in languages other than English supported?** Yes. In testing, Chinese content was confirmed to work with questions written in either Chinese or English. **Does Jev support images?** No. Jev accepts only text and JSON. For decisions about images, use GPT-6 Luna (openai/gpt-6-luna), which supports image input and uses the same request format.