npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

n8n-nodes-decisions

v0.6.1

Published

Ask Decisions API typed questions and route items by the answer, with calibrated probabilities

Readme

n8n-nodes-decisions

An n8n community node for working with Decisions-compatible APIs.

It lets your n8n workflows evaluate content using AI models and receive structured answers with probabilities, making it possible to build reliable decision-making and routing workflows.

Supported APIs

  • TypeSafe AI — System One models
  • OpenRouter — access compatible models through OpenRouter
  • OpenAI — OpenAI's Decisions API (beta)

Operations

The node provides two operations:

  • Evaluate — evaluates each input item against one or more typed questions and adds the answers to the item.
  • Route — evaluates a question and routes each item to an output based on the resulting answer.

You provide the model with a state (the content you want it to evaluate) and a set of typed questions describing what you want to know. The model returns a structured answer for each question, including probabilities.

This makes the node useful for tasks such as classification, content evaluation, decision-making, filtering, and conditional workflow routing.

Installation

Follow the installation guide in the n8n community nodes documentation, and use the package name n8n-nodes-decisions.

Credentials

Add a Decisions API credential and pick a Provider:

| Provider | API Key | Base URL | | --- | --- | --- | | TypeSafe AI | Create one in the TypeSafe console | Built in (https://api.typesafe.ai) | | OpenRouter | Create one in your OpenRouter dashboard | Built in (https://openrouter.ai) | | OpenAI | Create one in the OpenAI dashboard | Built in (https://api.openai.com) | | Custom (Decisions Compatible) | Your provider key | Enter the provider base URL, e.g. https://api.custom.com/v1 |

Endpoint Path is optional. Leave it blank to use the default for your provider: /v1/systemone for TypeSafe AI and custom providers, /api/alpha/decisions for OpenRouter, /v1/decisions for OpenAI. Set a custom path only if your provider documents a different one. A custom provider speaking OpenAI's format should set API Style to OpenAI Decisions, which also switches its default path to /v1/decisions.

n8n checks the key when you save the credential.

Operations

Both operations send one request per input item. Each request includes the item's state, the Model ID, and the questions.

Model is a plain text model ID, e.g. jev-latest. The Models page describes TypeSafe models and their aliases. For OpenRouter or custom providers, enter the model ID your provider expects. Any OpenRouter model with the decisions output modality should work, e.g. typesafe/jev-latest; see the Decisions models on OpenRouter. For OpenAI, use gpt-6-luna; see OpenAI's Decisions guide.

State Format sets where the state comes from:

| State Format | State sent | | --- | --- | | Text | The State field, as plain text | | JSON | The State field, parsed as a JSON object or array | | Input Item | The incoming item's JSON | | Text + Image | The State field as text, then one image, as an array of two parts |

All the questions in a request are asked about the same state. The State page covers how to structure it.

Sending an image (Text + Image)

With State Format set to Text + Image, the node evaluates text together with one image, for the vision-capable decision models — e.g. perplexity/pplx-decider-flash-v1.2 on OpenRouter or gpt-6-luna with the OpenAI provider. Fill in the State text, then choose an Image Source:

| Image Source | What you provide | | --- | --- | | Binary Data | An image in the output of the previous node. Binary Property (default data) points at it. | | Public URL | The image's Image URL, e.g. https://example.com/listing.png. The node downloads it and sends it inline. | | Base64 | The image's Base64 Image data, without the data: prefix |

The supported formats are GIF, JPEG, PNG and WebP, detected from the image's own bytes so renamed files still work; images above 20 MB are refused. For the Base64 source, Image Format helps when detection cannot decide. A URL that fails to download or answers with an error status, base64 carrying a data: prefix, and a URL that is not a plain http:// or https:// URL are all errors. With the OpenAI provider the node sends the parts in OpenAI's Decisions API shape for you.

Text + Image works with both operations and all three question types; the image-answering models today answer Yes/No (noul) questions. A text-only model answers about the text part alone. See docs.typesafe.ai for the request shapes and each model's capabilities.

Evaluate

Evaluate asks one or more questions about the state and adds all the answers to the item. Each question is one of three question types:

| Question Type | Answer | | --- | --- | | Choice | The option the model picked from your list, and its confidence | | Score | A position along your levels, and its confidence | | Noul (Yes/No) | The probability that the answer is yes, from 0 to 1 |

You can build the questions with the node's fields. Or you can set Questions Format to Using Raw JSON and pass in a JSON object of questions in the API's format, such as one built by an earlier node. The API reference documents that format.

Each answer goes in answers, under its question's ID:

{
  "answers": {
    "is_urgent":   { "noul": 0.95 },
    "department":  { "choice": "billing", "confidence": 0.81 },
    "frustration": { "score": 1.05, "confidence": 0.92 }
  },
  "model": "jev-1.13.0"
}

When an AI Agent uses the node as a tool, the node runs Evaluate.

With OpenAI, Noul questions are sent as predicate questions and their answer is probability instead of noul. A question the model declines comes back as { "type": "refusal" }. Raw JSON can also be an array of questions in OpenAI's format.

Low confidence handling

Evaluate can flag answers the model is unsure about. Set Fallback Mode to choose how, and Confidence Threshold (0–1, default 0.7) to set when an answer counts as low confidence: an answer with confidence strictly below the threshold is low confidence. It works the same for questions built in the UI and for Raw JSON, because it runs on the API response. The raw noul, choice, score and probability values are never modified.

Confidence is normalized to 0–1. Choice and Score use the confidence the API returns. Yes/No questions have no confidence field, so it is derived as |p − 0.5| × 2, so 0.85 → 0.70. A refusal always counts as low confidence. A Choice or Score answer without a confidence value is treated as reliable. The threshold must be a finite number in 0–1; anything else is an error.

| Fallback Mode | Behaviour | | --- | --- | | Disabled (default) | Today's output, unchanged. No fields are added. | | Best Guess | One output. Every answer gains lowConfidence, plus confidence where the answer has a confidence source (derived for Yes/No, 0 for a refusal). Yes/No answers also gain value, resolved as p > 0.5. Exactly 0.5 resolves to false: with no evidence for yes, the node does not assert it. Choice and Score never gain value. | | Low Confidence Output | Two outputs: Confident and Low Confidence. Every answer gains lowConfidence, plus confidence where the answer has a confidence source, and the item gains lowConfidence plus lowConfidenceQuestions (the IDs of the doubtful questions). If any question is low confidence, the whole item goes to Low Confidence. No value is resolved. A refusal always goes to Low Confidence. |

Fallback Mode is not settable by expression. Chaining two Decisions nodes recomputes these fields, overwriting the previous node's confidence, lowConfidence, lowConfidenceQuestions and value. When an AI Agent uses the node as a tool, prefer Disabled or Best Guess so the agent receives a single result. Answers without a confidence source (for example a Score without confidence) are treated as reliable and gain no confidence field.

Best Guess output:

{
  "answers": {
    "is_urgent": { "noul": 0.55, "confidence": 0.1, "lowConfidence": true, "value": true },
    "department": { "choice": "billing", "confidence": 0.81, "lowConfidence": false }
  },
  "model": "jev-1.13.0"
}

Low Confidence Output, on the Low Confidence output:

{
  "answers": {
    "is_urgent": { "noul": 0.55, "confidence": 0.1, "lowConfidence": true },
    "department": { "choice": "billing", "confidence": 0.81, "lowConfidence": false }
  },
  "model": "jev-1.13.0",
  "lowConfidence": true,
  "lowConfidenceQuestions": ["is_urgent"]
}

Route

Route asks one question and sends the item to the output that matches the answer. Question Type sets the kind of question and the outputs you get:

| Question Type | Outputs | An item goes to | | --- | --- | --- | | Choice | One per route, labelled with its Name | The route the model picked | | Noul (Yes/No) | True and False, labelled with True Means and False Means if you fill them in | True if p > 0.5, False otherwise — or to Low Confidence when unsure, see below | | Score | One per level, labelled with the level's text | The level nearest the score |

All three question types share one confidence model. Yes/No confidence is |p − 0.5| × 2, so a threshold c means p ≥ 0.5 + c/2 (true) or p ≤ 0.5 − c/2 (false). Set Confidence Handling to Route to Separate Low Confidence Output to add an extra output for unsure items (Low Confidence in version 2; Fallback for Choice in version 1). An item goes there when its answer's confidence is below Confidence Threshold (default 0.7 for all question types since version 2 — previously 0.5 for Choice routes). A Choice or Score answer without a confidence value is treated as reliable and follows its route or level.

  • Choice: Fallback output. Set Confidence Handling to Route to Separate Low Confidence Output to add a Low Confidence output (Fallback in version 1). An item goes there when its answer's confidence is below Confidence Threshold.
  • Noul: Low Confidence output. With a separate output enabled, an unsure item goes to Low Confidence. Without it, the item follows p > 0.5.
  • Score: level boundaries. Levels are numbered from 0, lowest first. The boundary between two levels is halfway between their numbers. A score from 0.5 to just under 1.5 goes to level 1, and a score exactly on a boundary goes to the higher level. With a separate output enabled, a low-confidence item goes to Low Confidence instead of its level.

Workflows saved with node version 1 keep the old Noul behaviour: True/False Probability Thresholds with an Uncertain output for the gap between them. Those thresholds are not offered in version 2, and an asymmetric v1 gap cannot be expressed as a single confidence threshold.

The route field holds the answer in the same form Evaluate uses, and the output the item leaves from shows the decision. If the model refuses the route question, that is a failure, handled as in Errors below — it never routes to a decision output.

{ "route": { "choice": "billing", "confidence": 0.81 }, "model": "jev-1.13.0" }

Example workflow

This workflow triages inbound messages. A spam gate (Noul) drops promotions and bot mail, then a Choice question routes each real message to billing, technical or sales.

Inbound triage sample workflow: sample messages pass a spam gate, then route to the billing, technical or sales queue

Import docs/Decisions - Inbound message triage (sample).json, pick your Decisions API credential and click Execute.

More worked examples, ready to import, are documented in docs/example-workflows.md:

  • Inbound message triage — a full Route chain: spam gate, team routing, urgency check for billing/technical and lead scoring for sales, with low-confidence and failed items converging on a human review queue. Good for shared inboxes and helpdesk front doors.
  • Ticket enrichment with Evaluate — one Evaluate call asks five questions per ticket (urgent, refund, legal threat, team, frustration), then a Code node applies thresholds and a Switch routes to P1/P2/P3, legal escalation or human review. Good for priority scoring and SLA escalation where the decision combines several signals.
  • Support copilot with guardrails — a chat AI Agent that must call Decisions (Evaluate as tool) before answering: refuse politely if unsafe, prefix [URGENT] if the user is blocked, otherwise answer with the right topic vocabulary. Good for chatbots that need a calibrated safety and priority check before the LLM drafts a word.

Output

The node writes these fields to each item:

| Field | Contents | | --- | --- | | answers | Evaluate: all the answers, keyed by question ID | | route | Route: the answer to the route question | | model | The full ID of the model that answered, including its version, such as jev-1.13.0 | | usage | Token usage, when Simplify is off |

Three settings under Options change how the node calls the API and what it writes:

  • Simplify is on by default. It keeps each answer's noul, choice or score, plus confidence for question types that return it, under the API's field names. When it's off, each answer is the full answer object from the API, including probabilities, and the item also gets usage.
  • Include Other Input Fields is on by default. It keeps the incoming item's fields and binary data, then writes the node's fields on top, replacing any incoming field with the same name. When it's off, the item has only the node's fields.
  • Timeout is how long, in milliseconds, the node waits for the API to start responding. The default is 5000 and the minimum is 1000.

Errors

When something goes wrong, the node stops and shows an error. A failed request shows the HTTP status and the API's error message. A setup problem, such as empty Instructions or a duplicate route name, shows a message saying what to fix.

In the node's Settings, turn on Retry On Fail to retry failed requests, including rate-limit errors (429).

To keep the workflow running when an item fails, set On Error:

  • Continue (using error output) adds an error output to the node and sends each failed item there, with an error field.
  • Continue sends each failed item, with an error field, to one of the node's regular outputs:

| Operation | Output the failed item goes to | | --- | --- | | Evaluate | The main output, or Low Confidence when Low Confidence Output is on | | Route, Choice | Low Confidence (Fallback in version 1) if enabled, otherwise the first route | | Route, Noul (Yes/No) | Low Confidence if there is one, otherwise False (Uncertain if there is one, otherwise False, in version 1) | | Route, Score | Low Confidence if there is one, otherwise the first level |

Compatibility

Tested with n8n 2.40.

This package is a fork of typesafe-ai/n8n-nodes-typesafe-ai, renamed to n8n-nodes-decisions with the node decisions and the credential decisionsApi. It is not a drop-in upgrade: workflows built with the TypeSafe AI node need the node and credential replaced.

Resources

Version history

See CHANGELOG.md.