cd /news/ai-tools/typesafe-jev-fails-on-openrouter-cha… · home › topics › ai-tools › article
[ARTICLE · art-148078] src=dev.to ↗ pub= topic=ai-tools verified=true sentiment=· neutral

typesafe/jev fails on OpenRouter chat/completions: how to call it (and the three response shapes that trip people up)

A developer documented how to call TypeSafe's Jev decision model through OpenRouter after the OpenAI-style chat/completions endpoint returned a 400 error stating that typesafe/jev-1.13 is a decisions model. The writeup shows the working request to OpenRouter's /api/alpha/decisions endpoint, which takes a state and typed questions and returns per-question probabilities, and flags three common parsing pitfalls: score values run 0 to n−1 rather than 0–1, score probabilities are keyed by string indices, and noul answers omit the confidence field entirely. A sample three-decision call cost $0.0000177, with output tokens unbilled.

by read2 min views1 publishedOct 9, 2026

If you point an OpenAI-style client at OpenRouter and ask for typesafe/jev-1.13, you get this back:

{"error":{"message":"typesafe/jev-1.13 is a decisions model and cannot be used with the chat/completions endpoint. Use the /api/alpha/decisions endpoint instead.","code":400}}

That is the whole story in one line: Jev doesn't write text, so it doesn't live on the chat endpoint. It is a decision model (TypeSafe calls the class "System One"): you send one input and a set of typed questions, and it answers each with probabilities. This post shows the request that works, the response it returns, and the three fields that cause most of the bugs I've seen.

Recorded 2026-10-09 against OpenRouter. With a TypeSafe key you can skip the gateway: the same state and questions go to TypeSafe's own API, POST https://api.typesafe.ai/v1/systemone, with "model": "jev-latest".

curl https://openrouter.ai/api/alpha/decisions \
  -H "Authorization: Bearer $OPENROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "typesafe/jev-1.13",
    "state": "I was charged twice for September and I am cancelling on Friday unless it is refunded.",
    "questions": {
      "team":    { "type": "choice", "instructions": "Which team should handle this ticket?",
                   "criteria": { "billing": "Payments, invoices, refunds", "technical": "Bugs and outages", "sales": "Plans and upgrades" } },
      "urgency": { "type": "score",  "instructions": "How urgent is this ticket?",
                   "criteria": ["Low", "Normal", "High", "Urgent"] },
      "churn":   { "type": "noul",   "instructions": "The customer threatens to cancel.",
                   "criteria": { "true": "Yes", "false": "No" } }
    }
  }'

state is what you are asking about — a string, a JSON object, or an array.questions is an

{
  "model": "typesafe/jev-1.13-20260917",
  "answers": {
    "team":    { "type": "choice", "choice": "billing",
                 "probabilities": { "billing": 1, "technical": 0, "sales": 0 }, "confidence": 1 },
    "urgency": { "type": "score", "score": 2.38,
                 "legend": { "0": "Low", "1": "Normal", "2": "High", "3": "Urgent" },
                 "probabilities": { "0": 0, "1": 0.02, "2": 0.58, "3": 0.4 }, "confidence": 0.58 },
    "churn":   { "type": "noul", "noul": 0.96 }
  },
  "usage": { "input_tokens": 421, "output_tokens": 70, "cost": 0.000017682 },
  "provider": "TypeSafe"
}

$0.0000177 for three decisions: 421 input tokens at $0.042 per million. Output isn't billed.

1. score is not 0–1. It is the probability-weighted mean of the rubric indices, so it runs from 0 to n−1. 2.38 on a four-level rubric means "between High and Urgent, closer to High". Round it for the band; the fraction tells you which way the probability mass leans.

2. Score probabilities are keyed by index, as strings — "0", "1" — never by your label. Map back through legend.

3. A noul has no confidence field. Not null: absent. The distance of noul from 0.5 is all you have, so answers.churn.confidence ?? 0 silently treats every yes/no as zero-confidence.

GET https://openrouter.ai/api/v1/models?output_modalities=decisions to list every decision model. I run jev-agent.com (Jagent), an independent Jev site, not affiliated with TypeSafe or OpenRouter.

── more in #ai-tools 4 stories · sorted by recency
── more on @typesafe 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
→ Live at https://your-agent.zahid.host ✓
Get free account → Pricing
from €0/mo · no card required
LIVE [news/typesafe-jev-fails-o…] indexed:0 read:2min 2026-10-09 · —