VindexDocs

Concepts

Policies & presets

A policy is your content rules as one JSON document: for each check, two lines and an action for each. Every workspace has a default policy, and a check uses it unless the request names another.

The shape

One check's rule, from the adult-platform preset:

JSON
"adult": {
  "act": 0.7,
  "review": 0.35,
  "on_act": { "type": "tag", "tag": "adult" },
  "on_review": { "type": "tag", "tag": "adult-review" }
}
  • act and review: the two lines, from 0 to 1, with review at or below act (Checks).
  • on_act and on_review: what happens at each line. {"type": "block"}, {"type": "review"}, {"type": "allow"}, or {"type": "tag", "tag": "…"}, which allows and labels.
  • enabled: false switches a check off and keeps its lines for later. Optional; checks are on by default.

Around the checks, the document has:

  • adult.max_level: the highest adult level allowed, 1 to 5. Anything above takes the adult check's on_act (the adult scale).
  • youth_coded_adult: "review" or "block", for someone stated to be an adult but presented young.
  • webhooks: who to call, for which outcomes (Webhooks).
  • tags: the tags this policy may apply, with a description each. Once you list any, every tag action has to use one of them.
  • version (always 1, the document format) and name.

Presets

Four starting points, one per kind of platform. Each cell is the act line and its action, then the review line and its action. These come straight from the preset files the API loads.

Checkadult-platformchat-assistantstock-imageryfamily-app
Minors, sexualminors_sexual0.50 block0.30 review0.50 block0.30 block0.50 block0.30 block0.50 block0.30 block
Adult contentadult0.70 tag adult0.35 tag adult-review0.50 block0.30 review0.50 block0.30 review0.35 block0.20 review
Real peoplereal_person0.50 review0.30 tag real-personoff0.50 block0.30 review0.30 review0.15 tag real-person
Copyrighted IPcopyrighted_ip0.50 tag ip0.30 tag ip-reviewoff0.40 block0.20 review0.30 review0.15 tag ip
Adult level allowedadult.max_levelup to 5 of 5up to 1 of 5up to 2 of 5up to 1 of 5
Youth-coded adultsyouth_coded_adultreviewblockblockblock
  • adult-platform: adults are adults. Adult content is tagged, never blocked; real people go to review.
  • chat-assistant: no adult content. Real people and copyrighted characters aren't checked.
  • stock-imagery: anything that could be a licensing or likeness problem is blocked or reviewed.
  • family-app: the lowest lines. Adult content is blocked at 0.35.

Start from one with POST /v1/policies and {"preset": "family-app"}. GET /v1/presets returns all four in full.

What no policy can change

The API refuses a document that breaks any of these, with 422 invalid_policy and one line per problem in issues:

  • minors_sexual is in every policy, enabled, with act 0.50 blocking and review 0.30 reviewing or blocking.
  • At adult.max_level 5, the adult check may tag or review, not block.
  • A tag action uses a tag from tags, if the policy lists any.
  • A webhook has an https:// URL on a public domain name (not an IP address, localhost, a .local or .internal name, *.workers.dev or a Vindex address), at least one event, and a secret of 16 characters or more. Publishing checks the version again, so a version saved before a rule existed can't go live.
422 invalid_policy
{
  "type": "https://api.getvindex.com/problems/invalid_policy",
  "title": "Invalid policy",
  "status": 422,
  "detail": "The policy document failed validation.",
  "code": "invalid_policy",
  "issues": [
    "checks.minors_sexual.act: must be 0.5 — not overridable",
    "checks.adult.on_act: must not be {type: \"block\"} when adult.max_level is 5 — use tag or review"
  ]
}

Versions

A policy changes by adding a version, never by editing one. Every decision records the policy.id and policy.version that made it.

Shell
# 1. A new version: validated and stored, not live yet.
curl -X POST "https://api.getvindex.com/v1/policies/$POLICY_ID/versions" \
  -H "Authorization: Bearer $VINDEX_KEY" \
  -H "Content-Type: application/json" \
  -d @policy.json

# 2. Try it on real prompts without enforcing anything.
curl https://api.getvindex.com/v1/check \
  -H "Authorization: Bearer $VINDEX_KEY" \
  -H "Content-Type: application/json" \
  -H "X-Vindex-Dry-Run: true" \
  -d '{"input": {"prompt": "a lighthouse at dusk, oil painting"}, "policy": "'"$POLICY_ID"'", "policy_version": 2}'

# 3. Publish it.
curl -X POST "https://api.getvindex.com/v1/policies/$POLICY_ID/publish" \
  -H "Authorization: Bearer $VINDEX_KEY" \
  -H "Content-Type: application/json" \
  -d '{"version": 2}'

A published version reaches every check within about a minute, five at most. Publishing an older version rolls back.

GET /v1/policies/{id} returns the current document and every version. Webhook secrets read back as "redacted", and sending "redacted" in a new version keeps the stored secret.

Default policy

A workspace's first policy becomes its default. POST /v1/policies/{id}/default switches it; so does "default": true when creating one. To screen against another policy, name it in the check: "policy": "pol_…".