Documentation

VigiMod API

Everything you need to call the VigiMod API.

Base URL: https://api.vigimod.com · Interactive reference: api.vigimod.com/docs

Quickstart

1. Create an account and an API key in the dashboard. 2. Send a message:

curl -X POST https://api.vigimod.com/moderate \
  -H "X-API-Key: $VIGIMOD_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text": "you are an idiot"}'

3. Read flagged and flags in the answer and decide what your bot does.

Authentication

Send your key in the X-API-Key header of every request. Keys look like vm_live_… or vm_test_… (both work the same way today; use test keys for development). Keep keys on your server: never put them in a browser or a mobile app. A revoked key stops working within a minute.

POST /moderate

Moderates one message. Only text is required.

FieldTypeDescription
textstringThe message, 1–2000 characters.
contextstring[]Previous messages, oldest first. At most 10.
rulesobjectYour rules: {"name": "rule in plain language"} or {"name": {"rule": "…", "threshold": 0.7}}. At most 10, each up to 300 characters.
categoriesstring[]Built-in categories to check. Default: all except child_safety. Fewer categories answer faster.
thresholdsobjectPer-request thresholds, e.g. {"toxic": 0.8, "rule": 0.6, "spam": 0.7}. Between 0 and 1.
block_slursbool | string[]true or a list of slur kinds to always flag (see Slurs).
user_idstringAuthor id, up to 64 characters. Turns on the spam score.
scopestringNamespace of the spam history, e.g. the Discord server id.
{
  "text": "lmao the dog dies at the end",
  "context": ["anyone watched the finale last night?", "not yet, tonight!"],
  "rules": {"no-spoilers": "No spoilers about movies or series"},
  "thresholds": {"toxic": 0.6},
  "user_id": "123456789",
  "scope": "my-server"
}

POST /moderate/batch

Up to 20 messages in one call: {"items": [ …same objects as /moderate… ]}. The answer is {"results": [ … ], "model_version": "…"} in the same order. Each item counts as one message for the rate limit.

Response

{
  "scores": {"toxic": 0.006, "insult": 0.001, …, "rule:no-spoilers": 0.998, "spam": 0.0},
  "flags":  {"toxic": false, "insult": false, …, "rule:no-spoilers": true, "spam": false},
  "flagged": true,
  "spam_info": {"repeats": 0, "messages_in_window": 1},
  "blocklist_matches": null,
  "model_version": "vigimod-1.2"
}
  • scores: probability from 0 to 1 for each checked category and rule (rule:<name>); spam is null without user_id.
  • flags: true when the score passes its threshold. An insult, hate or threat is also toxic.
  • flagged: true if any flag is true.
  • blocklist_matches: the slurs found when block_slurs is on.

Categories

CategoryFlags
toxicRude, disrespectful or aggressive messages.
insultInsults aimed at a person.
hateAttacks on people for who they are (origin, religion, gender, orientation, disability…).
threatThreats of violence or harm.
sexualSexual content.
self_harmSelf-harm or suicide intent.
advertisingAdvertising, spam links and self-promotion.
child_safety beta · opt-inAttempts to groom a minor. In VigiMod 1.2 it also flags many harmless messages, so it is only checked when you list it in categories; treat its flags as a signal for a human moderator.

Thresholds

Each category has a default threshold tuned on validation data (see GET /status). Override them per request with thresholds: a higher value flags less, a lower value catches more. rule sets the default of your custom rules; a rule can also carry its own threshold.

Custom rules

Rules are sentences in any language, checked by the same model: {"spoilers": "No spoilers", "football": "Only football talk here"}. Each rule returns rule:<name> in scores and flags. Write the behaviour you want to catch, short and concrete.

Conversation context

Pass the previous messages of the channel in context, oldest first (up to 10). They help with spoilers, replies and jokes that only make sense after the chat above. The scores are always about the message in text: the context only helps to read it.

Slurs

block_slurs flags slurs even in sentences the model does not see as attacks. Use true for every kind or a list of racial, xenophobic, antisemitic, homophobic, transphobic, ableist. Each kind has its own flag (slur:racial, …) so you can react differently. The lists cover English, Italian, Spanish, French, German and Portuguese.

Spam detection

With user_id (and optionally scope), VigiMod counts similar messages and the message rate of that user in the last minute: spam goes to 1 for repeated messages or floods. spam_info shows the counts.

GET /status

Public, no key needed: model version, categories (default and optional), thresholds and limits.

Errors and limits

StatusMeaning
401Missing, wrong or revoked key.
422Invalid request: the message says which field.
429Rate limit reached: wait Retry-After seconds.
503Key check temporarily unavailable: retry after Retry-After seconds.

Default limit: 120 messages per minute per key (a batch of N counts N). Every answer carries X-RateLimit-Limit and X-RateLimit-Remaining.

Data and privacy

Messages, context and rules are analyzed and never stored or logged. For each key we keep hourly counters (requests, messages, flags per category) for the usage dashboard and rate limits. Your messages are not used to train models.

Model changelog

  • VigiMod 1.2 (November 2026): better custom rules and conversation context, fewer false flags on everyday chat, child_safety opt-in.
  • VigiMod 1: first public model with eight categories, custom rules and context.