Last updated: September 2026
Jev in n8n: score a post, branch on the number, then publish
There is no Jev node for n8n, and you do not need one. Jev is one HTTP POST to https://api.typesafe.ai/v1/systemone that returns typed numbers. An HTTP Request node makes the call, an IF node compares the numbers, and the OpenTweet node publishes whatever came down the true branch.
Three nodes, two API keys, no glue code. The full workflow JSON is below and you can paste it straight onto a canvas.
What each node does
The division of labour matters more than the node count. Jev decides. n8n branches. OpenTweet ships.
Nothing in the middle is AI. The IF node runs two numeric comparisons you wrote down, which is exactly what makes the gate auditable. See how to pick those two numbers.
Node 1: the HTTP Request node that calls Jev
Store the TypeSafe key as a credential, not as a header typed into the node. In n8n, set Authentication to Generic Credential Type, pick Header Auth, and create a credential whose name is Authorization and whose value is Bearer followed by your key. Every workflow that needs Jev then reuses the one credential.
The body is where the work happens. Jev takes a state (the thing you are judging), a model and a map of questions. Every question is answered in one pass, so asking two costs barely more than asking one.
{
"model": "jev-1.13.0",
"state": {
"draft_post": "We cut our p95 checkout latency from 1.9s to 240ms by moving one join out of the request path.",
"platform": "X"
},
"questions": {
"strength": {
"type": "score",
"instructions": "How far will this post travel compared to a typical post from the same author?",
"criteria": [
"Flops. Gets less attention than a typical post from the same account.",
"Typical. Performs about the same as the account usually does.",
"Above typical. Noticeably more reach and replies than usual.",
"Strong. Several times the usual reach. Spreads past the existing audience.",
"Breakout. Orders of magnitude beyond usual."
]
},
"slop": {
"type": "noul",
"instructions": "This reads like it was generated by an AI rather than written by a person."
}
}
}Pin the model. jev-latest is an alias, and when it moves your thresholds move with it. jev-1.13.0 is the current pinned version per TypeSafe's model docs.
What comes back
{
"model": "jev-1.13.0",
"answers": {
"strength": {
"type": "score",
"score": 2.41,
"legend": {
"0": "Flops. Gets less attention than a typical post from the same account.",
"1": "Typical. Performs about the same as the account usually does.",
"2": "Above typical. Noticeably more reach and replies than usual.",
"3": "Strong. Several times the usual reach. Spreads past the existing audience.",
"4": "Breakout. Orders of magnitude beyond usual."
},
"confidence": 0.71
},
"slop": {
"type": "noul",
"noul": 0.08
}
},
"usage": { "input_tokens": 412, "output_tokens": 24 }
}Note the asymmetry, because it is the thing most n8n workflows get wrong. The Score answer carries a confidence. The Noul answer does not. A Noul returns a single float and nothing else, and that float is the probability.
Full breakdown of the three types is on Choice, Score and Noul.
Node 2: the IF node
Two comparisons, both reading the Jev response of the previous node:
- Number, is greater than or equal to.
{{ $json.answers.strength.score }}against2. - Number, is less than.
{{ $json.answers.slop.noul }}against0.5.
Combinator AND. A draft has to be both worth posting and not obviously machine written. Those two numbers are yours to set, and setting them by feel is the most common way this workflow goes wrong.
n8n versions the IF node
The JSON below uses the version 2 condition format. If your n8n instance imports it into an older IF node, the two comparisons above are all you need to rebuild it in the UI. Nothing else about the workflow changes.Node 3: publishing with OpenTweet
The OpenTweet community node is n8n-nodes-opentweet on npm. Install it under Settings, Community Nodes. It adds one credential, OpenTweet API, which holds a single field: an API key starting with ot_ that you create at /developer. No X developer account is involved.
The node exposes three resources:
- Post. Create publishes immediately, Schedule takes a future date, Create Batch sends up to 50 in one request.
- Thread. An ordered list of tweets, the first one being the opening post.
- Analytics. Get returns your posting overview.
For the true branch of this workflow you want Resource Post, Operation Create, and a Text field pointing back at the original draft. The Jev node replaced the item payload with Jev's answer, so reference the trigger item rather than $json.text.
When to use HTTP Request instead
The npm release of the community node has no platforms selector, so it posts to X. The REST API behind it accepts aplatforms array of x, bluesky and linkedin. If you want all three, swap the node for an HTTP Request node.{
"method": "POST",
"url": "https://opentweet.io/api/v1/posts",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{ "name": "Authorization", "value": "Bearer ot_your_key" }
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ JSON.stringify({ text: $json.text, platforms: ['x', 'bluesky', 'linkedin'], publish_now: true }) }}"
}The whole workflow, ready to paste
Copy this, open a blank n8n canvas and paste. Then attach your two credentials where the JSON says REPLACE_ME.
{
"name": "Score with Jev, publish with OpenTweet",
"nodes": [
{
"parameters": {},
"id": "1a2b3c4d-0001-4a10-9f01-0e1d2c3b4a51",
"name": "When clicking Test workflow",
"type": "n8n-nodes-base.manualTrigger",
"typeVersion": 1,
"position": [0, 0]
},
{
"parameters": {
"method": "POST",
"url": "https://api.typesafe.ai/v1/systemone",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ JSON.stringify({ model: 'jev-1.13.0', state: { draft_post: $json.text, platform: 'X' }, questions: { strength: { type: 'score', instructions: 'How far will this post travel compared to a typical post from the same author?', criteria: ['Flops.', 'Typical.', 'Above typical.', 'Strong.', 'Breakout.'] }, slop: { type: 'noul', instructions: 'This reads like it was generated by an AI rather than written by a person.' } } }) }}",
"options": {}
},
"id": "1a2b3c4d-0002-4a10-9f01-0e1d2c3b4a52",
"name": "Score with Jev",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [240, 0],
"retryOnFail": true,
"maxTries": 3,
"credentials": {
"httpHeaderAuth": { "id": "REPLACE_ME", "name": "TypeSafe Jev" }
}
},
{
"parameters": {
"conditions": {
"options": { "caseSensitive": true, "typeValidation": "strict", "version": 2 },
"combinator": "and",
"conditions": [
{
"id": "strength-gate",
"leftValue": "={{ $json.answers.strength.score }}",
"rightValue": 2,
"operator": { "type": "number", "operation": "gte" }
},
{
"id": "slop-gate",
"leftValue": "={{ $json.answers.slop.noul }}",
"rightValue": 0.5,
"operator": { "type": "number", "operation": "lt" }
}
]
},
"options": {}
},
"id": "1a2b3c4d-0003-4a10-9f01-0e1d2c3b4a53",
"name": "Clears the bar?",
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [480, 0]
},
{
"parameters": {
"resource": "post",
"operation": "create",
"text": "={{ $('When clicking Test workflow').item.json.text }}",
"additionalFields": { "category": "Scored" }
},
"id": "1a2b3c4d-0004-4a10-9f01-0e1d2c3b4a54",
"name": "Publish with OpenTweet",
"type": "n8n-nodes-opentweet.openTweet",
"typeVersion": 1,
"position": [720, -80],
"credentials": {
"openTweetApi": { "id": "REPLACE_ME", "name": "OpenTweet API" }
}
}
],
"connections": {
"When clicking Test workflow": {
"main": [[{ "node": "Score with Jev", "type": "main", "index": 0 }]]
},
"Score with Jev": {
"main": [[{ "node": "Clears the bar?", "type": "main", "index": 0 }]]
},
"Clears the bar?": {
"main": [
[{ "node": "Publish with OpenTweet", "type": "main", "index": 0 }],
[]
]
}
},
"settings": { "executionOrder": "v1" }
}The false branch is deliberately empty in the JSON. Fill it. Send rejected drafts to a Slack channel, a Google Sheet or an OpenTweet draft so a person sees them. A gate that silently discards work looks identical to a broken workflow.
What it costs to run
Jev charges $0.042 per million input tokens and does not charge for output tokens at all, per TypeSafe's pricing. That is the whole pricing page.
A worked example: the free post scorer runs seven Jev questions against every submitted draft, one Score for reach strength on a five level rubric, three Scores for hook, clarity and specificity, and three Nouls for AI slop, engagement bait and toxicity. The two-question workflow on this page sends less text than that.
At the rate Jev lists, scoring a thousand short drafts costs a few cents. The reason to think about the threshold at all is not the money.
Where this breaks
- Jev cannot write the post. It has no free-form text output. If your workflow also drafts the content, that is an LLM node upstream, and Jev only judges what the LLM produced.
- A valid answer can still be the wrong answer. Jev cannot return a value outside the answer space you declared, which eliminates schema errors. It does not eliminate being wrong about the post. TypeSafe's own launch post says the zero hallucination figure "is not empirical" and that schema matching is what is guaranteed.
- Dates and counting are unreliable. TypeSafe's own limitations page says to count in code and keep arithmetic out of the model. Do not ask Jev whether a post is scheduled inside a window. Compute that in n8n.
- Irrelevant context lowers accuracy. Send the draft text, not the entire item payload. Filter in n8n first.
- User-controlled text can steer the answer. Jev does not treat state as hostile. If the thing you are scoring came from a stranger, assume it may contain instructions aimed at your criteria.
The honest version of the limits is on what Jev is bad at.
Frequently asked questions
Is there a Jev node for n8n?
No. TypeSafe has not published an n8n node and none exists in the n8n community registry as of September 2026. You do not need one. Jev is a single HTTP POST to https://api.typesafe.ai/v1/systemone with a Bearer token, which the built-in HTTP Request node handles directly.
What does a Jev call cost inside an n8n workflow?
Jev bills $0.042 per million input tokens and does not bill output tokens at all, per docs.typesafe.ai/models, so a short draft carrying seven questions is a small fraction of a cent. A leaner two-question workflow costs less.
Which field do I branch on in the IF node?
It depends on the question type. A Score answer returns a probability-weighted score plus a confidence, so you branch on answers.<id>.score. A Noul answer returns only a noul float between 0 and 1 and has no confidence field at all, so you branch on answers.<id>.noul. A Choice answer returns choice, probabilities and confidence.
Can the OpenTweet n8n node post to Bluesky and LinkedIn too?
The OpenTweet REST API accepts a platforms array of x, bluesky and linkedin on every post, so an HTTP Request node can target all three in one call. The community node release on npm does not expose a platforms selector, so use the HTTP Request node when you need multi-platform targeting from n8n.
Can Jev write the post as well as score it?
No. Jev cannot generate text of any kind. It has no free-form string output, so it cannot write a draft, a summary or an explanation. It returns typed values from an answer space you declare. Use an LLM node for writing, Jev for the decision, and OpenTweet for publishing.
What happens if Jev is rate limited mid-workflow?
The API returns 429 for rate limits and 529 when TypeSafe is temporarily overloaded. Enable retry on the HTTP Request node with a backoff, and decide up front whether a failed score should block the publish or fall through to a human. A silent fall-through that publishes anyway defeats the point of the gate.
Keep exploring
The decision layer, the thresholds, and the API that ships the post.
How to set a Jev confidence threshold
Pick the number in the IF node from how hard the action is to undo, not from a gut feeling.
Choice, Score and Noul
The three question types, what each one returns, and which field you can actually branch on.
Jev and MCP: judgment plus action
The same split as this workflow, wired into an agent instead of a canvas.
OpenTweet n8n integration
Installing the community node, the credential, and the operations it exposes.
One n8n node, three networks
Post the same content to X, Bluesky and LinkedIn in a single API call.
Will it go viral
The same scoring questions, running live, free and with no signup.
Get the key that publishes
The Jev key comes from TypeSafe. The one that posts to X, Bluesky and LinkedIn comes from OpenTweet, and the same key works in the n8n node, the REST API, the CLI and the MCP server.
7-day free trial. No X developer account needed.