VindexDocs

Concepts

Decisions

Every check returns a decision, and every decision has one of three outcomes. It's the only field your app has to act on.

YES · allow

Generate. Nothing in your policy stopped it. It may carry tags, like adult, for you to label, filter or age-gate the result.

HMM · review

Hold it. A person should look first. The prompt is waiting in your review queue.

NO · block

Don't generate. Tell the user it isn't allowed. Nothing was rendered, so there's nothing to take down.

In your app

Node
// decide.mjs · Node 18+ · VINDEX_KEY=vx_test_... node decide.mjs "a prompt"
const prompt = process.argv[2] ?? "a lighthouse at dusk, oil painting";
const res = await fetch("https://api.getvindex.com/v1/check", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.VINDEX_KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({ input: { prompt } }),
});
if (!res.ok) throw new Error(`Vindex ${res.status}: ${await res.text()}`);
const decision = await res.json();

if (decision.shadow_mode) {
  console.log("shadow mode: log it, enforce nothing", decision.outcome);
} else if (decision.outcome === "allow") {
  console.log("generate", decision.tags);
} else if (decision.outcome === "review") {
  console.log("hold until a person rules on", decision.id);
} else {
  console.log("refuse", decision.id);
}

shadow_mode is true while your workspace is in shadow mode: log those decisions, don't enforce them yet.

How the outcome is chosen

Your policy gives every check two lines and an action for each. A check whose score reaches the act line takes the first action (on_act); one that reaches only the review line takes the second (on_review). Below both, it does nothing.

The actions are block, review, tag and allow. The decision takes the most severe action any check chose: block over review over allow. A tag counts as allow, and every tag applied lands in tags.

Four real decisions

Same four checks, two presets. Numbers from the live API with a test key.

PromptPolicyOutcomeWhy
a lighthouse at dusk, oil paintingadult-platformYES · allowNo check reached its review line.
a woman in lingerie, boudoir photo, soft window lightadult-platformYES · allowadult 0.91 reached its act line, 0.70: tag adult.
a woman in lingerie, boudoir photo, soft window lightfamily-appNO · blockadult 0.91 reached its act line, 0.35: block.
Abraham Lincoln giving a speech, black and white photographadult-platformHMM · reviewreal_person 0.99 reached its act line, 0.50: review.

The block, as the API returned it:

Response
{
  "id": "dec_60b500b8ab8d4b5882530f2ea8115f14",
  "outcome": "block",
  "tags": [],
  "checks": {
    "minors_sexual": {
      "score": 0.0255,
      "review_score": 0.03,
      "fired": []
    },
    "adult": {
      "score": 0.91,
      "review_score": 0.91,
      "fired": [
        "adult_nsfw"
      ]
    },
    "real_person": {
      "score": 0.02,
      "review_score": 0.02,
      "fired": []
    },
    "copyrighted_ip": {
      "score": 0.02,
      "review_score": 0.02,
      "fired": []
    }
  },
  "policy": {
    "id": "pol_69ea6e25ab524a98944b8e83407df74a",
    "version": 1
  },
  "engine_version": "2026.09",
  "latency_ms": 376,
  "dry_run": false,
  "mode": "test",
  "shadow_mode": false
}

Explain turns any decision into those sentences.

Your ids: user and metadata

Two optional fields on POST /v1/check are stored with the decision and returned with it:

  • user: your id for the person who wrote the prompt, up to 128 characters. Rules count, tag and pause per user, and you can filter the log by it. If a rule has paused that user, the decision is a block with user_paused: true, whatever the checks said.
  • metadata: any JSON of your own, up to 4,096 bytes: an order id, a model name, a session.
Shell
curl https://api.getvindex.com/v1/check \
  -H "Authorization: Bearer $VINDEX_KEY" \
  -H "Content-Type: application/json" \
  -d '{"input": {"prompt": "a lighthouse at dusk, oil painting"}, "user": "u_42", "metadata": {"order": "1234"}}'

The decision log

Every decision is kept, newest first. Filter by outcome, policy, mode, dry_run, check, user, and a time range (since, until), then page with cursor.

Shell
curl "https://api.getvindex.com/v1/decisions?outcome=review&dry_run=false&limit=20" \
  -H "Authorization: Bearer $VINDEX_KEY"

GET /v1/decisions/{id} returns one decision with its input, your metadata and the actions that ran. The full list of fields is in the reference.