TypeSafe AI (Jev)
Pass-through endpoint for the TypeSafe AI System One API. Jev returns typed decisions (a choice, a score, or a yes/no probability) instead of text, so it is called through its own evaluate endpoint rather than /chat/completions.
| Feature | Supported | Notes |
|---|---|---|
| Cost Tracking | ✅ | Priced from the response usage and the model registry |
| Logging | ✅ | works across all integrations |
| End-user Tracking | ❌ | Tell us if you need this |
| Streaming | ❌ | Not offered by the TypeSafe API |
Just replace https://api.typesafe.ai with LITELLM_PROXY_BASE_URL/typesafe
LiteLLM adds the TypeSafe API key from the proxy environment, so clients only need a LiteLLM virtual key.
Client headers that start with TypeSafe-Danger-Zone-, such as TypeSafe-Danger-Zone-Images: true for images and box questions on Jev 1.14, are forwarded to TypeSafe. Other client headers are not.
To call Jev through your model_list with load balancing, fallbacks and per-deployment keys, or to send the same request to OpenAI, Perplexity, Cloudflare or Strands Decider, use the unified /v1/systemone endpoint instead. It takes the same System One body, and /v1/decisions takes the OpenAI Decisions format
To let JEV pick the model for a completion, configure the JEV Auto Router with classifier_type: jev and jev_classifier_config. It uses one System One Choice question for the configured tiers, then dispatches to the selected completion model. See routing context, fallback and accounting and the measured classifier comparison
The OSS classifier guide documents the canonical classifier_type: oss_classifier and opensource_classifier_config.provider: jev names, which require a gateway build containing backend #43626. Both configurations use the TypeSafe transport; the new backend continues to accept the existing Jev names.
Quick Start
- Set the TypeSafe API key in the proxy environment
export TYPESAFE_API_KEY=""
# optional, defaults to https://api.typesafe.ai
export TYPESAFE_API_BASE="https://api.typesafe.ai"
- Start the proxy
litellm
# RUNNING on http://0.0.0.0:4000
- Ask Jev a question through the proxy
curl -X POST 'http://0.0.0.0:4000/typesafe/v1/systemone' \
-H "Authorization: Bearer $LITELLM_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
"state": "Help! My payouts have been failing for 3 days.",
"model": "jev-latest",
"questions": {
"department": {
"type": "choice",
"instructions": "Which team should handle this?",
"criteria": {
"billing": "Payments, invoicing, refunds",
"technical": "Bugs, outages, integrations",
"sales": "Pricing, upgrades, new accounts"
}
}
}
}'
The response is TypeSafe's own, unchanged:
{
"model": "jev-1.13.0",
"answers": {
"department": {
"type": "choice",
"choice": "technical",
"probabilities": {"billing": 0.08, "technical": 0.85, "sales": 0.07},
"confidence": 0.82
}
},
"usage": {"input_tokens": 312, "output_tokens": 48}
}
Any path under /typesafe/ is forwarded, so GET /typesafe/v1/models lists the available models. See the TypeSafe API reference
Limit which keys can call Jev
The pass-through runs the same model access check as /chat/completions. When a key, its team or its project has a models list, a /typesafe/ call is allowed only if each list allows the model in the request body, which is the bare Jev name such as jev-latest.
Entry in models | Allows |
|---|---|
jev-latest | jev-latest only |
typesafe/* | jev-latest, jev-preview and the versioned names LiteLLM prices, such as jev-1.14.0 |
typesafe/jev-latest | Not a bare jev-latest call |
A call whose model a list does not allow gets a 403, such as team_model_access_denied for a team list. For example, this team allows the published Jev models:
curl -X POST "$LITELLM_PROXY_BASE_URL/team/new" \
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
-H "Content-Type: application/json" \
-d '{"team_alias": "jev-users", "models": ["typesafe/*"]}'
In the Admin UI, the team and organization Models dropdowns, and the key dropdown when no team is picked, offer All Typesafe models (typesafe/*) and each Jev model when TYPESAFE_API_KEY is set in the proxy environment.
The proxy offers these dropdown options Since v1.109.0. typesafe/* matching comes from LiteLLM's model registry, so a proxy that loads the registry from GitHub, which is the default, gets it before upgrading.
Try it in the Admin UI
The Playground Decisions tab (Beta) sends Jev requests without curl. It calls the proxy's /v1/systemone route rather than this pass-through, so add a typesafe/ model to your model_list first, for example jev from the proxy setup on the Decisions page, and set TYPESAFE_API_KEY. Open LITELLM_PROXY_BASE_URL/ui/?page=llm-playground&tab=system-one, or go to Playground and pick Decisions.
Pick /v1/systemone under Endpoint and your Jev model under Model. Load example fills in a request, such as Triage a bug report, which asks one question of each type: area (choice), has_repro_steps (yes / no) and severity (score). The eraser button clears the form.
The editor opens on the Form tab, so you can build a request without writing JSON. Type the text the model should read into Input, then fill in each question card: its Name, its Answer type (Choice, Yes / no or Score), its Instructions and its criteria. A choice takes Options with descriptions, a yes / no question takes Yes means and No means, and a score takes Levels, lowest first, numbered from 0. Add question, Add option and Add level add rows, and the trash buttons remove them.
The cURL tab shows the request as a read-only curl command for the proxy's /v1/systemone, and it follows your edits. Once the form has no issues, Copy cURL copies it, and you replace $LITELLM_API_KEY with a virtual key. To tag the call in LiteLLM's spend logs, which the form has no input for, copy the curl and add "metadata": {"tags": ["triage"]} to its -d body.
The form checks the request as you type. Problems are listed above Send, such as Add the text the model should decide about. for an empty Input and Give every question a name. for an unnamed question, and Send stays disabled until they are fixed. TypeSafe checks the rest when you send, so a yes / no question with no instructions and no Yes means or No means comes back as a 400.
API key picks the key. Current UI Session uses your dashboard login, and Virtual Key lets you paste one so the call is attributed and budgeted against that key. Send posts to /v1/systemone through your model_list, so spend and logs land under the proxy model name like any other request. The /typesafe/v1/systemone pass-through from the curl above is not selectable in the Playground.
Once the call returns, the Response card shows one card per question: the picked choice with its confidence and a bar per option, the yes / no probability, and the score with its confidence and a bar per level. Its header shows the latency, the model name from the response and the input and output tokens, and Raw response opens the JSON body. Auth and upstream errors, such as a 401 for an unknown key, replace the answers with Decisions request failed and the error.
Cost Tracking
Spend uses usage.input_tokens and usage.output_tokens from the response and the typesafe/<model> entry in LiteLLM's model registry (jev-1.13.0, jev-1.14.0, jev-latest, jev-preview). The request is logged under the versioned model TypeSafe reports, for example typesafe/jev-1.13.0, even when the request used an alias.