How to Use Jev in n8n Workflows (Decision Nodes That Don't Break)
TL;DR: In n8n, Jev becomes the decision node your automation can trust. One HTTP Request node calls the OpenAI-compatible OpenRouter endpoint, a small Code node parses the structured
{answer, confidence, rationale}response, and IF nodes branch on the answer plus a confidence threshold. Failures go down an explicit fallback path instead of breaking the run. Node-by-node setup below.
The workflow at a glance
Trigger (webhook / schedule / new record)
|
v
Set node (build the question text from input fields)
|
v
HTTP Request node -> OpenRouter chat/completions (model: Jev)
|
+--> HTTP error --> Retry (built-in, 2-3 tries, backoff)
| |
| +--> still failing --> Fallback path (notify / default action)
|
v
Code node (parse choices[0].message.content as JSON)
|
+--> invalid JSON --> Fallback path
|
v
IF node (confidence >= 0.85 ?)
|
+--> yes --> branch on answer (e.g. route, tag, approve)
|
+--> no --> Fallback path (human queue with rationale)
Every exit leads somewhere defined. That is the whole trick: the decision node either decides confidently or hands off.
HTTP Request node configuration
| Field | Value |
|---|---|
| Method | POST |
| URL | https://openrouter.ai/api/v1/chat/completions |
| Authentication | Header auth: Authorization: Bearer <OPENROUTER_API_KEY> (store the key in n8n credentials, not in the node) |
| Body (JSON) | {"model":"typesafe/jev-1.13","temperature":0,"messages":[{"role":"system","content":"Answer yes, no, or unclear."},{"role":"user","content":"{{ $json.question }}"}]} |
| Retry on fail | Enabled, 2-3 attempts, with backoff |
| Timeout | ~30 seconds |
The model id used here is typesafe/jev-1.13 — confirm the exact model slug on the OpenRouter model page before going live.
Parsing node (Code node, JavaScript)
// Input: HTTP Request node output from OpenRouter
const raw = $input.first().json;
let parsed;
try {
// example fixture:
// {"answer":"yes","confidence":0.97,"rationale":"..."}
parsed = JSON.parse(raw.choices[0].message.content);
} catch (e) {
return [{ json: { branch: "fallback", reason: "invalid-json", raw } }];
}
const lowConfidence = parsed.confidence < 0.85;
if (lowConfidence) {
return [{ json: { branch: "fallback", reason: "low-confidence", ...parsed } }];
}
return [{ json: { branch: parsed.answer, ...parsed } }];
Downstream IF nodes now switch on $json.branch — clean values like yes, no, or fallback, never scraped prose.
Wiring the fallback path
The fallback branch should do three things: record the raw response and rationale, notify a human (email, Slack, ticket), and optionally take a safe default action so the run completes. The ticket triage and sentiment case study shows a fallback wired to a support queue in exactly this style.
For the channel itself — OpenRouter versus the official API — see the API channels guide, and for your first call from scratch see the first API call guide. Official API endpoints and fields should always be verified against the typesafe.ai documentation.
Applies to Jev 1.13.
FAQ
- How do I call Jev from n8n? An HTTP Request node posting to
https://openrouter.ai/api/v1/chat/completionswith header auth, the model id, and your question in the messages array. - How do I read the structured answer? A Code node parses
choices[0].message.contentas JSON, then the workflow branches on theanswerandconfidencefields. - What does the error branch do? Built-in retries for transient failures; low-confidence, invalid JSON, or repeated failures go to a fallback path — a human queue or safe default — so the run never dies silently.