Skip to content
DecisionNodeDecisionNdedocs
  • Guides
  • API reference
  • Examples
  • Playground

start here

  • QuickstartGet startedGet an API key, send one request with three questions, and branch your code on the typed answers. Plain HTTPS, no SDK to install.
  • POST /v1/decideAPI referenceAnswer typed questions about a state and optional images. One request, one buffered JSON response, one answer per question.
  • QuestionsConceptsQuestions say what to decide. Each one has a type that fixes the shape of its answer: a choice from your options, a score on your scale, a…
  • ConfidenceConceptsProbabilities are calibrated per question type, so a threshold means what it says.
  • ImagesConceptsSend images and text in the same request. The model reads printed and handwritten text, amounts, dates, objects and layout, and answers…
  • Pricing and billingYou pay for input tokens only. Output is free because the model generates no text.
↑↓ moveopen6 suggestions
Get API keyGet API key
DecisionNodeDecisionNde

Get started

  • Introduction
  • Quickstart
  • With coding agents
  • Examples

Concepts

  • State
  • Questions
  • Choice
  • Score
  • Truth
  • Number
  • Images
  • Confidence
  • Determinism

Models

  • DecisionNode-1.0
  • DecisionNode-1.0 Flash
  • Limits

Patterns

  • Confidence-gated routing
  • Fan-out
  • Guardrails
  • Control loopscomingcoming soon

API reference

  • POST/v1/decide
  • POST/v1/sessionscomingcoming soon
  • GET/v1/models
  • Errors
  • Rate limits

Pricing and billing

  • Pricing and billing

Policies

  • Responsible use

Migrate

  • Coming from a Jev-shaped API
  • Benchmarks
  • Pricing
  • Playground
Get API key
  • Guides
  • API reference
  • Examples
  • Playground

Get started

  • Introduction
  • Quickstart
  • With coding agents
  • Examples

Concepts

  • State
  • Questions
  • Choice
  • Score
  • Truth
  • Number
  • Images
  • Confidence
  • Determinism

Models

  • DecisionNode-1.0
  • DecisionNode-1.0 Flash
  • Limits

Patterns

  • Confidence-gated routing
  • Fan-out
  • Guardrails
  • Control loopscomingcoming soon

API reference

  • POST/v1/decide
  • POST/v1/sessionscomingcoming soon
  • GET/v1/models
  • Errors
  • Rate limits

Pricing and billing

  • Pricing and billing

Policies

  • Responsible use

Migrate

  • Coming from a Jev-shaped API
  1. docs
  2. /
  3. Patterns

Guardrails

Gate an agent's tool calls: before the agent acts, ask DecisionNode whether the action is safe and in scope, and run it only above your bar.

Where the check goes#

Put the check between the agent deciding to call a tool and the tool running. The state is the proposed call plus the context that matters; the questions are your policy, written as Truth and Choice questions.

Gate request
{
  "model": "decisionnode-flash-latest",
  "state": {
    "user_request": "Clean up the old staging data",
    "proposed_call": {
      "tool": "run_sql",
      "args": {
        "database": "production",
        "sql": "DELETE FROM orders WHERE created_at < '2026-01-01'"
      }
    }
  },
  "questions": {
    "safe": {
      "type": "truth",
      "instructions": "Is it safe to run this call right now?",
      "criteria": {
        "true": "read-only, reversible, or clearly what the user asked for",
        "false": "destructive, irreversible, or outside what the user asked for"
      }
    },
    "in_scope": {
      "type": "truth",
      "instructions": "Does the call do what the user asked, and nothing more?"
    },
    "risk": {
      "type": "choice",
      "instructions": "What is the main risk of this call?",
      "criteria": {
        "none": "no meaningful risk",
        "data_loss": "deletes or overwrites data",
        "money": "moves money or changes billing",
        "privacy": "exposes personal data",
        "other": "another kind of risk"
      }
    }
  }
}
Gate
const BAR = { safe: 0.95, inScope: 0.9 };

export async function guardedCall(call: ToolCall, context: Context) {
  let answers;
  try {
    answers = await decide(gateRequest(call, context));
  } catch {
    return block(call, { reason: "guardrail unavailable" }); // fail closed: the agent re-plans
  }

  const { safe, in_scope, risk } = answers;
  if (safe.truth >= BAR.safe && in_scope.truth >= BAR.inScope) {
    return runTool(call);
  }
  return block(call, { reason: risk.choice, safe: safe.truth, inScope: in_scope.truth });
}

Fail closed

If the gate cannot answer (a timeout, a 529), do not run the tool. Block the call and hand the reason back to the agent so it re-plans. A guardrail that fails open is not a guardrail.

Why it works as a gate#

  • Fast enough for every step: Flash answers short requests in milliseconds, so the check fits in front of every tool call.
  • Deterministic: the same proposed call gets the same verdict, so you can test your policy with fixed cases in CI.
  • Calibrated: a bar of 0.95 means what it says. Pin decisionnode-1.0 or decisionnode-1.0-flash once the bar is tuned.
previousFan-outnextControl loopscomingcoming soon

DecisionNode is built and run by Bynn Intelligence, Inc.

  • Home
  • Playground
  • Examples
  • Console
  • Responsible use
  • Terms
  • Acceptable use
  • Privacy
  • Data processing
  • Defence addendum
  • Cookies

on this page

  1. Where the check goes
  2. Why it works as a gate