Getting Started

Stream's Moderation API lets you integrate content moderation into any application. This guide walks you through installing one of the backend SDKs, configuration, and your first moderation check.

Moderation lives in the Stream Dashboard, where you can create and tune policies, manage AI rules and blocklists, and review flagged content across your app.

Start here

Stream CLI and Agent Skills

Manage moderation from your terminal with the Stream CLI, including scripting policy setup and AI-agent workflows. Install the CLI and the default Agent Skills:

curl -fsSL https://getstream.io/cli.sh | bash
getstream skills

Then ask your agent in plain English, for example:

/stream Show flagged content in the review queue.

See the CLI docs and Agent Skills docs for more.

Installation

pip install getstream

Initialize the client

from getstream import Stream

client = Stream(api_key="YOUR_API_KEY", api_secret="YOUR_API_SECRET")

Create a moderation policy

Before checking content, create a moderation configuration that defines which rules to apply:

client.moderation().upsert_config(
    key="my_config",
    ai_text_config={
        "rules": [
            {"label": "SPAM", "action": "flag"},
            {"label": "HARASSMENT", "action": "remove"},
        ],
    },
    block_list_config={
        "rules": [{"name": "profanity_en", "action": "remove"}],
    },
)

For Stream Chat, use config key chat:messaging. For Stream Feeds, use feeds. See Configuration for details.

Check content

from getstream.models import ModerationPayload

response = client.moderation().check(
    entity_type="stream:chat:v1:message",
    entity_id="message-123",
    entity_creator_id="user-456",
    moderation_payload=ModerationPayload(
        texts=["Hello, this is a test message"],
    ),
    config_key="my_config",
)

print(response.data.recommended_action)  # "keep", "flag", or "remove"

Handle the response

The response includes:

  • recommended_action -- "keep", "flag", or "remove"
  • status -- "complete" or "partial" (if async checks are still running)
  • item -- the review queue item (if content was flagged or removed)

The check returns a recommendation for your code to enforce. Stream adds flagged and removed content to the review queue:

flowchart LR
  content[User content] --> check[Moderation check]
  check --> rec{recommended_action}
  rec -->|keep| keep[Your app keeps it]
  rec -->|flag| queue[Review queue]
  rec -->|remove| removed[Your app removes it]
  removed -.->|for audit and appeals| queue
action = response.data.recommended_action

if action == "keep":
    # Content is safe, no action needed
    pass
elif action == "flag":
    # Content is suspicious; Stream has queued it for review
    print("Flagged for review:", response.data.item)
elif action == "remove":
    # Content violates policies, remove it
    print("Content removed:", response.data.item)

What's next