Jev AI API guide
Jev AI API Explained: Request Shape, Questions, and Results
This independent guide explains how the Jev AI API is shaped, what its typed questions mean, how a response is organized, and which failure cases matter. The examples below are for running requests in your own environment with your own API key; those calls do not go through this site. If you prefer not to manage a key, the hosted Playground and Batch CSV evaluation run requests on our servers via OpenRouter and are billed in credits (1 successful run = 1 credit).
The request shape: state, model, questions
Every Jev evaluation request has the same three top-level fields. The field names below come from the official TypeSafe API reference (checked 2026-09-18). The example values come from this site's synthetic support-routing template, version 1.0.0.
| Field | What it is | Example |
|---|---|---|
| state | The input text to evaluate, as a string | Please send my invoice for August. |
| model | The requested model identifier | jev-latest (a driftable alias, not a pinned version) |
| questions | Named structured questions with explicit criteria | department: choice of billing, technical, sales, other |
{
"state": "Please send my invoice for August.",
"model": "jev-latest",
"questions": {
"department": {
"type": "choice",
"instructions": "Route this support request to one team.",
"criteria": {
"billing": "Invoices, payments, refunds or existing charges",
"technical": "Bugs, errors, outages or integrations",
"sales": "Buying, demos, plans or presales questions",
"other": "Unclear, multi-team or out-of-scope requests"
}
}
}
}Copy-paste cURL example
The script below writes the request to a file from a base64 payload, so quotes, newlines, Unicode, and shell metacharacters in your input never become executable shell text. The key is read only from the TYPESAFE_API_KEY environment variable. It never goes into the command line or the request file.
#!/usr/bin/env bash
set -euo pipefail
: "${TYPESAFE_API_KEY:?Set TYPESAFE_API_KEY before running this example}"
curl --fail-with-body --silent --show-error --max-time 10 --retry 0 \
--request POST \
--url 'https://api.typesafe.ai/v1/systemone' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--header "Authorization: Bearer ${TYPESAFE_API_KEY}" \
--data-binary @request.jsonTypeScript example with zero retries
The Node 20+ example below performs exactly one request with a bounded 10-second timeout and an explicit zero-retry policy. This matters because a retried classification call can cost you twice. The same request JSON from the previous section is embedded as data, not string-concatenated into shell.
const endpoint = "https://api.typesafe.ai/v1/systemone";
const apiKey = process.env.TYPESAFE_API_KEY;
const timeoutMs = 10_000;
const retries = 0; // Deliberately no automatic retry.
const request = { state, model: "jev-latest", questions };
const controller = new AbortController();
const timeout = setTimeout(() => controller.abort(), timeoutMs);
const response = await fetch(endpoint, {
method: "POST",
redirect: "error",
headers: {
Accept: "application/json",
Authorization: `Bearer ${apiKey}`,
"Content-Type": "application/json",
},
body: JSON.stringify(request),
signal: controller.signal,
});Choice vs noul vs score: pick one question type
Jev documents three question types. Pick the one that matches your decision, not the one that looks most impressive. The value ranges below come from the official docs; the guidance column is this site's synthesis for support workflows.
| Type | Returns | Use it when |
|---|---|---|
| choice | selected option, probabilities, confidence | routing a ticket to exactly one team |
| noul | a 0-1 value for a yes/no proposition | deciding whether a request needs human review |
| score | zero-based level plus probability-weighted value | grading ordered levels such as priority tiers |
Error handling: the failures you will actually meet
The table below maps HTTP outcomes to what you should do. It is derived from this site's provider adapter behavior, which classifies upstream failures without retrying.
| Outcome | Meaning | Do this |
|---|---|---|
| 401 / 403 | authorization failed | check the key, do not retry blindly |
| 422 | request rejected | validate state and questions against the schema |
| 429 / 529 | rate limited or temporarily unavailable | back off, respect Retry-After, retry once later |
| 5xx | upstream failure | treat as unknown, keep the human path open |
| timeout | no response within 10 seconds | do not assume it was free; verify before resending |
A full score example: grading priority tiers
Choice gets most of the attention, but score deserves one worked example because priority grading is the second most common support task. The request below asks Jev to place a ticket on four ordered levels. Levels are zero-based: 0 means routine, 3 means urgent. The documented score is the probability-weighted value across levels, not a percentage and not a vote count.
{
"state": "The checkout API has been down for 20 minutes for all EU stores.",
"model": "jev-latest",
"questions": {
"priority": {
"type": "score",
"instructions": "Grade the urgency of this support request.",
"criteria": ["routine", "elevated", "high", "urgent"]
}
}
}Read the response in two steps. First find which level holds the highest probability: that is the recommended tier. Then read the score value itself: a score of 2.7 sits between high and urgent and tells your queue to treat it closer to urgent. Keep the legend the response returns and compare it against your own criteria order; any mismatch means the template and the response disagree and the ticket goes to a human.
Retry-After and timeout discipline
Rate limits carry a Retry-After hint. Read it as seconds when it is a plain number, or as an HTTP date otherwise, and wait at least that long before one manual retry. Timeouts are the opposite case: the request may still have executed upstream after your 10-second abort, so never auto-resend. Log the attempt as unknown, check the ticket state through your own system first, and only then decide whether a second attempt is safe. Keep request.json in your working directory and your key only in the environment; neither belongs in chat logs, screenshots, or version control.
Run it with your own key
Export your personal TypeSafe key in your own terminal, paste the request, and run. Nothing here sends your key or your text to this site: the examples execute on your machine against TypeSafe directly, and charges (if any) are between you and the provider.
export TYPESAFE_API_KEY="your-personal-key"
# write request.json from the example above, then:
curl --fail-with-body --max-time 10 --retry 0 \
--url 'https://api.typesafe.ai/v1/systemone' \
--header "Authorization: Bearer ${TYPESAFE_API_KEY}" \
--header 'Content-Type: application/json' \
--data-binary @request.jsonLimits and next steps
This page shows request mechanics, not model quality. No accuracy, latency, or cost numbers appear here because this site has made zero live calls and holds zero approved fixtures. When you are ready for a real task, continue to the worked routing scenario and the evaluation method note.
Jev ticket routing examples · What is Jev AI? · Evaluation method · Official API reference
FAQ
Does this site give me a Jev API key? No. To run this code yourself, bring your own key. To run without a key, use the hosted Playground, which consumes credits.
Does this page call Jev when I open it? No. It is a static tutorial. The code here calls the API only when you run it yourself; hosted runs happen only when you submit them in the Playground or Batch evaluation.
Which model does the example request? jev-latest, which the docs present as a movable alias. Pin a stable version in your own code when one is available to you.