Try it
Copy the code ↓- Data source
- Decision schema
- Model inference
- Structured result
2 Decision schema 5 typed questions
topicchoicebilling_disputebug_reportfeature_requestcancellationotherurgencyscorelownormalhighcriticalchurn_riskscorenonelowmediumhighthreatnoulprobability 0–1needs_humannoulprobability 0–1
3 Model inference typesafe/jev-1.13
Waiting for a run.
4 Structured result
Raw JSON
Run the demo to see the JSON answers, the highlighted pick and the final action.
FLATKEY_API_KEY and run.curl -sS https://router.flatkey.ai/api/alpha/decisions \
-H "Authorization: Bearer $FLATKEY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "typesafe/jev-1.13",
"state": "I'\''ve been charged for the Team plan twice this month and support hasn'\''t answered in 5 days. Honestly we'\''re evaluating other tools now. Fix the charge or I'\''m filing a chargeback.",
"questions": {
"topic": {
"type": "choice",
"instructions": "What is this message mainly about?",
"criteria": {
"billing_dispute": "Disputed charges, refunds or double billing",
"bug_report": "Something in the product is broken",
"feature_request": "Asking for something the product doesn'\''t do",
"cancellation": "Wants to cancel or downgrade",
"other": "None of these"
}
},
"urgency": {
"type": "score",
"instructions": "How time-sensitive is this message?",
"criteria": [
"low",
"normal",
"high",
"critical"
]
},
"churn_risk": {
"type": "score",
"instructions": "How likely is this customer to leave, even if they don'\''t say so directly?",
"criteria": [
"none",
"low",
"medium",
"high"
]
},
"threat": {
"type": "noul",
"instructions": "The message threatens legal action, a chargeback or public escalation, beyond ordinary frustration."
},
"needs_human": {
"type": "noul",
"instructions": "A person should read this message before any automated action."
}
}
}'// Node.js 18+ (built-in fetch). Run: FLATKEY_API_KEY=... node jev.mjs
const body = {
"model": "typesafe/jev-1.13",
"state": "I've been charged for the Team plan twice this month and support hasn't answered in 5 days. Honestly we're evaluating other tools now. Fix the charge or I'm filing a chargeback.",
"questions": {
"topic": {
"type": "choice",
"instructions": "What is this message mainly about?",
"criteria": {
"billing_dispute": "Disputed charges, refunds or double billing",
"bug_report": "Something in the product is broken",
"feature_request": "Asking for something the product doesn't do",
"cancellation": "Wants to cancel or downgrade",
"other": "None of these"
}
},
"urgency": {
"type": "score",
"instructions": "How time-sensitive is this message?",
"criteria": [
"low",
"normal",
"high",
"critical"
]
},
"churn_risk": {
"type": "score",
"instructions": "How likely is this customer to leave, even if they don't say so directly?",
"criteria": [
"none",
"low",
"medium",
"high"
]
},
"threat": {
"type": "noul",
"instructions": "The message threatens legal action, a chargeback or public escalation, beyond ordinary frustration."
},
"needs_human": {
"type": "noul",
"instructions": "A person should read this message before any automated action."
}
}
};
const res = await fetch("https://router.flatkey.ai/api/alpha/decisions", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.FLATKEY_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify(body),
});
if (!res.ok) throw new Error(`Jev request failed: ${res.status} ${await res.text()}`);
const { answers, usage } = await res.json();
console.log(JSON.stringify(answers, null, 2), usage);# Python 3.8+ (pip install requests). Run: FLATKEY_API_KEY=... python jev.py
import json, os, requests
body = json.loads(r"""{
"model": "typesafe/jev-1.13",
"state": "I've been charged for the Team plan twice this month and support hasn't answered in 5 days. Honestly we're evaluating other tools now. Fix the charge or I'm filing a chargeback.",
"questions": {
"topic": {
"type": "choice",
"instructions": "What is this message mainly about?",
"criteria": {
"billing_dispute": "Disputed charges, refunds or double billing",
"bug_report": "Something in the product is broken",
"feature_request": "Asking for something the product doesn't do",
"cancellation": "Wants to cancel or downgrade",
"other": "None of these"
}
},
"urgency": {
"type": "score",
"instructions": "How time-sensitive is this message?",
"criteria": [
"low",
"normal",
"high",
"critical"
]
},
"churn_risk": {
"type": "score",
"instructions": "How likely is this customer to leave, even if they don't say so directly?",
"criteria": [
"none",
"low",
"medium",
"high"
]
},
"threat": {
"type": "noul",
"instructions": "The message threatens legal action, a chargeback or public escalation, beyond ordinary frustration."
},
"needs_human": {
"type": "noul",
"instructions": "A person should read this message before any automated action."
}
}
}""")
res = requests.post(
"https://router.flatkey.ai/api/alpha/decisions",
headers={"Authorization": f"Bearer {os.environ['FLATKEY_API_KEY']}"},
json=body,
timeout=60,
)
res.raise_for_status()
data = res.json()
print(json.dumps(data["answers"], indent=2), data.get("usage"))
No Flatkey key yet? Get one for Jev 1.13 →
About this use case

Who / when
Audience
- data teams sitting on tables of free-text messages, reviews or documents
- analysts who need semantic filters SQL cannot express
- builders enriching rows in batch jobs or spreadsheets
Triggers
- you need "sounds ready to churn" or "is a threat" as a column, not a vibe
- several judgments are asked about the same document
- a batch job re-sends the same long text to a model once per question
- downstream rules need typed values, not prose
The workflow
- 01Text stateOne message, ticket or documentInput
- 02ChoiceTopic columnJev
- 03Score + NoulUrgency, churn risk, threat, needs-humanJev
- 04Code gateWrite the row, flag or leave nullYour code
Question shape
{
"topic": {
"type": "choice",
"instructions": "What is this message mainly about?",
"criteria": {
"billing_dispute": "Disputed charges, refunds or double billing",
"bug_report": "Something in the product is broken",
"feature_request": "Asking for something the product doesn't do",
"cancellation": "Wants to cancel or downgrade",
"other": "None of these"
}
},
"urgency": {
"type": "score",
"instructions": "How time-sensitive is this message?",
"criteria": [
"low",
"normal",
"high",
"critical"
]
},
"churn_risk": {
"type": "score",
"instructions": "How likely is this customer to leave, even if they don't say so directly?",
"criteria": [
"none",
"low",
"medium",
"high"
]
},
"threat": {
"type": "noul",
"instructions": "The message threatens legal action, a chargeback or public escalation, beyond ordinary frustration."
},
"needs_human": {
"type": "noul",
"instructions": "A person should read this message before any automated action."
}
}Gate policy
≥ 0.90
Write the columns; SQL filters and dashboards use them directly.
0.65–0.90
Write the columns and flag the row for a human.
< 0.65
Leave the columns null and queue the text for review.
Failure modes
Pre-launch checks before you trust auto-routing:
- Questions that overlap, so two columns answer the same thing;
- Asking Jev to extract values (amounts, dates, names) instead of judging;
- Very long documents beyond the state limit; chunk and aggregate in code;
- Sarcasm and indirect churn signals;
- Schema drift when columns are renamed but old rows are not recomputed;
FAQ
Why ask all the questions in one call?
Because Jev is billed on input and every question in a request shares the same state. In the run Fluixo describes (post below), 13 bounded questions about a 53,777-character GDPR article cost $0.000497 in one call finishing in 0.27 s, against $0.006090 and 2.71 s for thirteen sequential calls, 12.2× more. Concurrency closes part of the time gap but not the repeated input cost.
What kinds of columns work well?
Judgments a person could make quickly: topic, urgency, churn risk, threat versus frustration, needs a human. Keep facts such as amounts, dates and names in deterministic parsers.
Is this the same as JSON mode?
No. JSON mode makes a generative model's output parseable. Here the answer space is defined first and every answer comes with probabilities, so columns can be thresholded, cached and audited like any other data.
Can I bring my own API key?
Yes. Try the free demo above without signing in. To run it live on your own text, sign in with Google and connect a Flatkey or OpenRouter key (a quick test call runs when you save it). Manage or delete it anytime under Dashboard → BYOK. Keys are stored encrypted on the server, used only for runs you trigger, and never sent back to the browser. Need a Flatkey key? Get one for Jev 1.13 on Flatkey.
Is this the official TypeSafe Jev product page?
No. jev-llm.com is an independent research and practice site. Verify pricing, models and terms at the original TypeSafe sources.
Sources
13 AI QUESTIONS COST $0.000497 IN ONE JEV CALL THE SAME QUESTIONS COST $0.006090 WHEN SENT SEPARATELY The input was a 53,777-character GDPR article … Jev lets those judgments share one input and execute together The best Jev product may not ask one brilliant question It may ask hundreds of boring questions about the same state cheaply enough that every answer becomes infrastructure
— @fluixoo View the post on X →
JEV TURNS TEXT INTO COLUMNS. THAT MAY MATTER MORE THAN 200× SPEED. Imagine a database with 100,000 customer messages. You need to find the billing disputes, estimate urgency, detect likely churn, separate threats from frustration, and decide which cases deserve a human.
— @fluixoo View the post on X →
Wire this gate with your own key
Bring your own key through Flatkey / OpenRouter. Keep exact checks in code.