The 11 Moderation Categories
On this page
Updated November 3, 2026. The category table previously listed three non-existent keys (
hate,violence,unpredictable) and omitteddangerous. The eleven keys below reflectmistral-moderation-2603, based on the documentation and types from themistralaiSDK 3.7.0; descriptions follow Mistral’s definitions. Output values presented as measured data were illustrative examples and are now clearly labeled as such. Sources: Moderation & Guardrailing · Mistral Moderation 2411 (deprecated model).
Understanding Risk Categories
The Mistral Moderation model analyzes content across 11 distinct categories. Each category covers a specific risk type and returns an independent score between 0.0 and 1.0. Understanding exactly what each category detects is essential for setting meaningful thresholds. Without this clarity, you’re just guessing at numbers and wondering why content gets blocked unexpectedly.
The table below provides the exact API key for each category, what it covers, and the types of cases it catches in practice.
| Category | API Key | What Mistral Includes |
|---|---|---|
| Sexual content | sexual | Explicitly described or promoted sexual activities, nudity, or sexual services; non-explicit educational or medical content is generally exempt |
| Hate and discrimination | hate_and_discrimination | Prejudice, hostility, or calls for discrimination based on protected characteristics, including harassment |
| Violence and threats | violence_and_threats | Described, glorified, incited, or threatened physical violence, and instructions for committing it |
| Dangerous content | dangerous | Extremely dangerous behaviors with a high risk of physical harm |
| Criminal activities | criminal | Described or promoted illegal activities |
| Self-harm | selfharm | Self-harm, suicide, eating disorders: methods, glorification, intent, dangerous challenges |
| Health | health | Requests for or provision of detailed or personalized medical advice |
| Finance | financial | Requests for or provision of detailed or personalized financial advice |
| Legal | law | Requests for or provision of detailed or personalized legal advice |
| Personal data | pii | Requests, sharing, or attempts to obtain identifying data: full name, address, phone number, social security number, bank details |
| Jailbreak | jailbreaking | Attempts to bypass model rules through prompt manipulation, role-playing, or other techniques |
The dangerous, criminal, and jailbreaking categories arrived with mistral-moderation-2603. The previous model, mistral-moderation-2411, deprecated on March 31, 2026, combined the first two under a single key, dangerous_and_criminal_content, and did not detect jailbreaks. Some response examples in the documentation still show this older breakdown: always read the keys the API returns rather than assuming them.
”Hard” vs. “Soft” Categories
In practice, these 11 categories fall into two groups based on criticality, and this distinction drives your entire threshold strategy.
Hard categories — sexual, hate_and_discrimination, violence_and_threats, dangerous, criminal, and selfharm — represent serious risks where a false negative (failing to detect dangerous content) can have severe consequences. Sexual content carries legal risk and obligations to protect minors; hate speech exposes you to major reputational damage and legal liability; violence involves incitement and threats; dangerous and criminal categories cover high-risk behaviors and illegal activities; self-harm involves user safety and life-threatening situations. For these six categories, low thresholds of 0.1 to 0.2 are justified regardless of your product, and you deliberately accept some false positives.
Soft categories depend heavily on your application’s context, with adjustable thresholds between 0.3 and 0.8. A legitimate medical chatbot needs to discuss health, a fintech app requires conversations covered by financial, a legal assistant necessarily handles law, and some applications legally collect data falling under pii. One case reads differently: jailbreaking doesn’t depend on the subject matter but on the intent to manipulate the model, and remains critical for any application open to the public.
Analyzing Scores in Python
The following function transforms a raw API call into a readable verdict: it isolates categories exceeding 0.3, identifies the maximum score and its category, and returns a safe indicator you can use directly in your application logic.
from mistralai.client import Mistral
import os
client = Mistral(api_key=os.environ["MISTRAL_API_KEY"])
def analyze_content(text: str) -> dict:
"""Analyze text and return risk categories."""
response = client.classifiers.moderate(
model="mistral-moderation-2603",
inputs=[text]
)
scores = response.results[0].category_scores or {}
# Separate risk categories
risks = {}
for category, score in scores.items():
if score > 0.3:
risks[category] = round(score, 3)
return {
"text": text[:100],
"risks": risks,
"max_score": max(scores.values(), default=0.0),
"max_category": max(scores, key=lambda c: scores[c], default=None),
"safe": len(risks) == 0
}
print(analyze_content("Hello, how are you?"))
print(analyze_content("What dose of acetaminophen for a 20 kg child?"))
category_scores is optional in the SDK, hence the or {}. Run both examples on your account: the greeting should stay very low across the board, while the dosage question should spike on health. This isn’t “dangerous” content in the common sense—it’s content you must decide whether falls within your scope.
Multiple Categories: One Text Can Trigger Several Alerts
A single text can have high scores in multiple categories simultaneously—a request for help with tax fraud will hit criminal, financial, and law all at once. Your decision logic must account for this multiplicity, and above all, prioritize: the function below sorts violations by the magnitude of the threshold breach, telling you which category actually drove the block.
def evaluate_global_risk(scores: dict, thresholds: dict) -> dict:
"""Evaluate global risk considering all categories."""
violations = []
for category, threshold in thresholds.items():
score = scores.get(category, 0)
if score > threshold:
violations.append({
"category": category,
"score": score,
"threshold": threshold,
"excess": round(score - threshold, 3)
})
return {
"blocked": len(violations) > 0,
"violations": sorted(violations,
key=lambda v: v["excess"],
reverse=True),
"violation_count": len(violations)
}
# Configuration by profile
strict_thresholds = {
"sexual": 0.1, "hate_and_discrimination": 0.1, "violence_and_threats": 0.15,
"dangerous": 0.1, "criminal": 0.1, "selfharm": 0.1,
"health": 0.3, "financial": 0.3, "law": 0.3,
"pii": 0.15, "jailbreaking": 0.1,
}
The strict_thresholds profile follows exactly the hard/soft logic outlined above: thresholds of 0.1 to 0.15 on the six critical categories and jailbreak, tolerance at 0.3 for contextual domains. Keep this structure as your starting point and document any deviations you introduce.
Key Takeaways
mistral-moderation-2603analyzes content across 11 categories with fixed keys;hate,violence, orunpredictabledo not exist- Each category returns a score from 0.0 to 1.0
- “Hard” categories (
sexual,hate_and_discrimination,violence_and_threats,dangerous,criminal,selfharm) require low thresholds - “Soft” categories (health, financial, law) adjust based on your application context
- A single text can trigger multiple categories simultaneously
- Use raw scores (
category_scores) rather than default booleans