Models Hub
API ReferenceChat

TypeSafe Jev structured judgments

Call typesafe/jev through /v1/responses to ask several yes/no, classification and scoring questions about a piece of text or a structured state, and get machine-readable answers.

Edit this page

typesafe/jev does not write free-form text. It answers questions you define in advance: one request can ask several questions about the same input, and each question returns a numeric judgment, a chosen option or a graded score. Use it for ticket routing, moderation pre-checks, lead scoring and rule-assisted decisions, where the result goes straight into your own code.

Access

ItemValue
EndpointPOST https://modelsok.com/v1/responses
AuthAuthorization: Bearer <API Key>
Modeltypesafe/jev
ModeSynchronous and non-streaming; one request returns the full JSON

Non-streaming only

Do not send "stream": true; the request is rejected with 400. There is no task to poll either: wait for the HTTP response.

Make sure the group of your API key has access to typesafe/jev. Keep the API key on your server (for example in an environment variable); never ship it in browser or mobile code.

Request body

{
  "model": "typesafe/jev",
  "input": {
    "state": "The content to evaluate: plain text or a JSON object",
    "questions": {
      "<question ID>": {
        "type": "noul | choice | score",
        "instructions": "What this question should decide",
        "criteria": "Decision criteria; the format depends on the type, see below"
      }
    }
  }
}
FieldRequiredDescription
modelYesAlways typesafe/jev
input.stateYesWhat to evaluate. Usually a string or a JSON object; an array or null also works. A bare number or boolean does not
input.questionsYesYour questions. Each key is a question ID of your choice; the answer comes back under the same key
questions.<ID>.typeYesnoul, choice or score
questions.<ID>.instructionsYesWhat to evaluate, ideally one clear sentence
questions.<ID>.criteriaDepends on typeSee the table below

When state is an object you can pass tickets, orders or user records as they are, without flattening them into a string first.

Question types

Typecriteria formatResult
noulOptional. If given, an object with only the keys "true" and "false", describing the affirmative and negative standardsnoul: a number from 0 to 1; closer to 1 means more affirmative
choiceRequired object: option ID → option descriptionchoice: the chosen option ID, plus probabilities per option and confidence
scoreRequired array of at least two levels, ordered from lowest to highestscore: a level value starting at 0 that may be fractional, plus legend, probabilities and confidence

noul is a number, not a boolean. If you need a yes/no answer, pick a threshold in your own code (for example, above 0.7 means yes). confidence and probabilities express the model's certainty; they do not guarantee the answer is correct.

Example

One request asking three questions: should this be handled today, which team should take it, and how much does it affect the customer.

curl https://modelsok.com/v1/responses \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "typesafe/jev",
    "input": {
      "state": "Order X42 is missing a mounting part. The customer needs it for a trade show tomorrow and asks for a replacement today.",
      "questions": {
        "urgent": {
          "type": "noul",
          "instructions": "Should this be prioritized today?",
          "criteria": {
            "true": "There is an explicit same-day request or an imminent deadline",
            "false": "No explicit deadline; the normal process is fine"
          }
        },
        "team": {
          "type": "choice",
          "instructions": "Which team should handle this first?",
          "criteria": {
            "fulfillment": "Replacements, missing parts and shipping",
            "support": "How-to questions and troubleshooting",
            "sales": "Product selection and purchasing"
          }
        },
        "impact": {
          "type": "score",
          "instructions": "How much does this affect the customer's plans?",
          "criteria": [
            "Routine question, no impact on use",
            "Affects use, but a workaround exists",
            "Blocks use and the deadline is close"
          ]
        }
      }
    }
  }'

Response

The response is a complete JSON document, and the answers are not at the top level: they are under result.result. The shape of a real response:

{
  "result": {
    "state": "Completed",
    "result": {
      "model": "jev-1.13.0",
      "answers": {
        "urgent": { "type": "noul", "noul": 0.91 },
        "team": {
          "type": "choice",
          "choice": "fulfillment",
          "probabilities": { "sales": 0, "support": 0, "fulfillment": 1 },
          "confidence": 1
        },
        "impact": {
          "type": "score",
          "score": 2,
          "legend": {
            "0": "Routine question, no impact on use",
            "1": "Affects use, but a workaround exists",
            "2": "Blocks use and the deadline is close"
          },
          "probabilities": { "0": 0, "1": 0, "2": 1 },
          "confidence": 1
        }
      },
      "usage": { "input_tokens": 472, "output_tokens": 72 }
    },
    "gatewayMetadata": { "keySource": "Unified" }
  },
  "success": true,
  "errors": [],
  "messages": []
}
PathMeaning
successWhether the evaluation succeeded; check it before reading answers
result.result.answers.<question ID>The answer to each question, keyed by the question ID you sent
result.result.modelThe model version that ran, such as jev-1.13.0; it may differ from typesafe/jev
result.result.usageInput and output token counts. There is no total_tokens; add them yourself if needed

Don't read it like a text model

Although the endpoint is /v1/responses, the response has no output, output_text or choices. Read result.result.answers directly.

Python

import os
import requests

resp = requests.post(
    "https://modelsok.com/v1/responses",
    headers={"Authorization": f"Bearer {os.environ['API_KEY']}"},
    json={
        "model": "typesafe/jev",
        "input": {
            "state": {
                "order_id": "X42",
                "missing_parts": ["mounting bracket"],
                "replacement_sent": False,
                "customer_note": "Needed at tomorrow's trade show",
            },
            "questions": {
                "needs_follow_up": {
                    "type": "noul",
                    "instructions": "Is follow-up needed to supply the missing part before use?",
                }
            },
        },
    },
    timeout=60,
)
resp.raise_for_status()
data = resp.json()
if not data.get("success"):
    raise RuntimeError(data.get("errors"))

answers = data["result"]["result"]["answers"]
usage = data["result"]["result"]["usage"]
print(answers["needs_follow_up"]["noul"])
print(usage["input_tokens"], usage["output_tokens"])

Node.js

Run this on a server (Node.js 18+ ships fetch), never in a browser page.

const apiKey = process.env.API_KEY;
if (!apiKey) throw new Error('Missing API_KEY');

const resp = await fetch('https://modelsok.com/v1/responses', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
  },
  signal: AbortSignal.timeout(60_000),
  body: JSON.stringify({
    model: 'typesafe/jev',
    input: {
      state: 'Order X42 is missing a mounting part. Please send a replacement.',
      questions: {
        team: {
          type: 'choice',
          instructions: 'Which team should handle this first?',
          criteria: {
            fulfillment: 'Replacements, missing parts and shipping',
            support: 'How-to questions and troubleshooting',
            sales: 'Product selection and purchasing',
          },
        },
      },
    },
  }),
});
if (!resp.ok) throw new Error(`HTTP ${resp.status}: ${await resp.text()}`);

const data = await resp.json();
const { answers, usage } = data.result.result;
console.log(answers.team.choice, answers.team.confidence);
console.log(usage.input_tokens, usage.output_tokens);

Billing

Billed per token. Input and output token counts come from result.result.usage; see typesafe/jev on the pricing page for the current price, and the usage logs for the charge of each call. Evaluations that do not succeed are not charged.

FAQ

400 saying streaming is not supported: the request contains "stream": true. Remove it.

No answers found: you may be reading a top-level answers or output_text. The answers are under result.result.answers.

The request returns an error: failed evaluations are not charged. Common causes are criteria that do not match the question type, such as a score question with fewer than two levels, a choice question without criteria, or a noul question whose criteria uses keys other than "true" and "false". Fix the request and retry.

On this page