Policies
Overview
Moderation configurations (also called policies) define how content is moderated within your application. Each configuration specifies which moderation engines are active, what rules apply to detected content categories, and what actions to take when rules are triggered. Configurations are identified by a unique key and can be scoped to specific teams for multi-tenancy support.
You can combine multiple moderation engines in a single configuration -- for example, AI text analysis for detecting harassment, blocklists for filtering profanity, and image moderation for detecting nudity. Each engine has its own set of rules that map detected labels or patterns to actions such as flagging, removing, or shadow-blocking content.
After you change a policy, use Evaluations to re-run a fixed batch of content and see what improved or drifted.
Upsert Config
Creates or updates a moderation configuration. If a configuration with the specified key already exists, it will be replaced. A configuration can include any combination of moderation engines: AI text analysis, AI image moderation, blocklist filtering, toxicity detection, platform circumvention detection, velocity filters, and video call rules.
client.moderation().upsert_config(
key="my_config",
ai_text_config=AITextConfig(
rules=[
AITextRule(label="SPAM", action="flag"),
AITextRule(label="HARASSMENT", severity_rules=[
SeverityRule(severity="low", action="flag"),
SeverityRule(severity="high", action="remove"),
]),
],
),
block_list_config=BlockListConfig(
rules=[BlockListRule(name="profanity_en", action="remove")],
),
ai_image_config=AIImageConfig(
rules=[AIImageRule(label="Non-Explicit Nudity", action="flag")],
),
)Request Parameters
| key | required | type | description |
|---|---|---|---|
| key | true | string | Unique identifier for the config. Used when sending content for moderation check. |
| team | false | string | Team identifier for multi-tenancy. Scopes the config to a specific team. |
| async | false | boolean | When true, moderation checks using this config run asynchronously. |
| ai_text_config | false | object | Configuration for AI text analysis. Define rules mapping harm labels to actions. |
| ai_image_config | false | object | Configuration for AI image moderation (e.g., nudity, violence detection). |
| ai_video_config | false | object | Configuration for AI video moderation. |
| ai_audio_config | false | object | Configuration for AI audio moderation. |
| block_list_config | false | object | Configuration for blocklist-based filtering. Define which blocklists to use and their actions. |
| automod_toxicity_config | false | object | Configuration for Stream's built-in toxicity detection engine. |
| automod_platform_circumvention_config | false | object | Configuration for platform circumvention detection (phone numbers, external links, etc.). |
| velocity_filter_config | false | object | Configuration for velocity-based filtering (rate limiting repeated content). |
| llm_config | false | object | Configuration for LLM-based moderation. See LLM config. |
| flood_config | false | object | Configuration for per-user flood detection (identical and similar message detectors). |
Config Key Conventions
The config key follows a hierarchical naming convention that determines its scope:
- Chat channel:
chat:messaging:channel_id-- applies to a specific channel - Chat channel type:
chat:messaging-- applies to all channels of a given type - All chat channels:
chat-- applies to all chat channels - Activity Feeds:
feeds:default-- applies to activity feeds - Polls:
polls:default-- applies to poll text (questions, options and answers); see Moderate poll text
When content is submitted for moderation, the system looks for the most specific config key first, then falls back to broader scopes.
Get Config
Retrieve a specific moderation configuration by its key. Returns the full configuration object including all engine settings and rules.
client.moderation().get_config("my_config")Request Parameters
| key | required | type | description |
|---|---|---|---|
| key | true | string | The unique identifier of the config to retrieve. |
| team | false | string | Team identifier for multi-tenancy. |
Response
| key | type | description |
|---|---|---|
| config | object | The full moderation configuration object. |
Delete Config
Delete a moderation configuration. Once deleted, any content moderation checks referencing this config key will no longer apply.
client.moderation().delete_config("my_config")Request Parameters
| key | required | type | description |
|---|---|---|---|
| key | true | string | The unique identifier of the config to delete. |
| team | false | string | Team identifier for multi-tenancy. |
Query Configs
Search and filter moderation configurations with support for sorting and pagination. Use this endpoint to list all configurations or find specific ones matching filter criteria.
client.moderation().query_moderation_configs(
filter={},
sort=[{"field": "created_at", "direction": -1}],
limit=10,
)Request Parameters
| key | required | type | description |
|---|---|---|---|
| filter | false | object | Filter conditions for configs. |
| sort | false | array | Sort parameters (e.g., by created_at). |
| limit | false | number | Maximum number of configs to return. |
| next | false | string | Cursor for pagination. |
Response
| key | type | description |
|---|---|---|
| configs | array | List of moderation config objects. |
| next | string | Next cursor for pagination. |
Config Structure Reference
Each moderation configuration can include one or more engine-specific sub-configurations. The following table summarizes the available config types and where to find detailed documentation for each engine.
| Config Field | Description | Engine Documentation |
|---|---|---|
| ai_text_config | AI-powered text analysis for detecting harm categories | AI Text |
| ai_image_config | AI-powered image moderation for nudity, violence, and more | Image Moderation |
| block_list_config | Blocklist and regex-based filtering for known bad words or patterns | Blocklists and Regex Filters |
| automod_toxicity_config | Stream's built-in toxicity scoring engine | -- |
| automod_platform_circumvention_config | Detection of phone numbers, emails, and external links | -- |
| velocity_filter_config | Rate limiting for repeated or high-volume content | -- |
| ai_video_config | AI-powered video call moderation | -- |
| ai_audio_config | AI-powered audio moderation via transcription | Audio Moderation |
| llm_config | LLM-based moderation for custom policies | AI Text (LLM) |
| flood_config | Per-user detection of repeated or near-duplicate messages | Flooding |
LLM config
llm_config sets up the AI Text (LLM) engine. Upserting the config replaces the whole llm_config, so send every field you want to keep.
| key | type | description |
|---|---|---|
| app_context | string | Short description of your application and how users interact, so the LLM understands the setting. |
| rules | array | Harm labels. Each rule has a label (required), a plain-language description of what to detect (optional; without it the LLM uses the label name alone), an action (flag, shadow, remove, bounce, bounce_flag, bounce_remove or keep) and optional severity_rules. The engine runs when rules contains at least one rule with an action. |
| severity_descriptions | object | Optional. What each severity means to the LLM, keyed LOW, MEDIUM, HIGH and CRITICAL. When omitted, Stream fills in defaults, for example LOW is "Content that needs review but may be acceptable" and HIGH is "Content that must be removed immediately". |
| async | boolean | Optional. Runs LLM moderation asynchronously. Defaults to false: the check waits for the LLM verdict. |
| context_custom_keys | array of strings | Top-level moderation_payload.custom keys passed to the LLM as background context. Never moderated themselves. Up to 10 keys, each 1-64 characters. See Context from custom data. |
| custom_keys_context_description | string | How the LLM should read the context keys. Up to 1000 characters (UTF-8 bytes). Requires context_custom_keys. |
LLM severity rules
severity_rules is an array of { severity, action }, with severity one of low, medium, high or critical. When the verdict's severity has a severity rule, that action is used; otherwise the rule's own action applies. For example, { "severity": "low", "action": "flag" } sends low-severity matches to review instead of removing them.
Rule Actions
Each rule within a config maps a detected label or pattern to an action. The following actions are available:
| Action | Description |
|---|---|
flag |
Flag the content for human review. The content remains visible but appears in the moderation review queue. |
remove |
Remove the content immediately. The content is deleted and a review queue item is created. |
shadow_block |
Shadow-block the content. The content appears visible to the author but is hidden from other users. |
bounce |
Bounce the content back to the sender. The content is rejected before it is published, and the user is notified. |
Severity Levels
For AI text analysis rules, you can define severity-based rules instead of a single action. This allows different actions depending on how severe the detected violation is. The available severity levels are:
| Severity | Description |
|---|---|
low |
Minor or borderline violations. Typically used for flagging or monitoring. |
medium |
Moderate violations that may warrant content removal or closer review. |
high |
Serious violations that typically result in content removal. |
critical |
The most severe violations requiring immediate action. |
When using severity rules, each severity level can be mapped to a different action. For example, you might flag low-severity harassment but automatically remove high-severity harassment, as shown in the Upsert Config example above.