Flooding

Flood detection identifies users sending large volumes of repeated or near-duplicate messages in a short window and appends flood labels and escalated actions to the moderation response. It runs per user, per moderation policy, and covers two independent detectors that can be enabled separately or together:

  • Identical — fires when a user sends the same message repeatedly. Comparison is exact after normalization (lowercase, punctuation and extra whitespace stripped).
  • Similar — fires when a user sends near-duplicate messages that vary by small edits, such as typos, punctuation, or whitespace changes. Similarity is measured with a configurable strictness.

Each detector fires once the user reaches threshold matching messages within time_window.

Configuration

Attach a flood_config block to a moderation policy via the Upsert Config API. Both detectors are opt-in and can be configured with different thresholds and actions.

client.moderation()
    .upsertConfig(UpsertConfigRequest.builder()
        .key("chat:messaging")
        .floodConfig(FloodConfig.builder()
            .identical(FloodIdenticalConfig.builder()
                .enabled(true)
                .threshold(5)
                .timeWindow("30m")
                .action("flag")
                .build())
            .similar(FloodSimilarConfig.builder()
                .enabled(true)
                .threshold(5)
                .timeWindow("30m")
                .similarityDistance(5)
                .action("remove")
                .build())
            .allowlist(List.of("gg", "well played"))
            .build())
        .build())
    .execute();

Fields

FieldTypeRequiredDescription
identical.enabledbooleanfalseTurn identical-message detection on for this policy.
identical.thresholdinteger (2 to 100)when enabledNumber of matching messages that triggers a flood verdict.
identical.time_windowstringwhen enabledRolling window over which the counter accumulates. One of 1m, 3m, 5m, 10m, 15m, 30m, 1h.
identical.actionstringwhen enabledAction applied on trigger. One of flag, remove.
similar.enabledbooleanfalseTurn similar-message detection on for this policy.
similar.thresholdinteger (2 to 100)when enabledNumber of near-matching messages that triggers a flood verdict.
similar.time_windowstringwhen enabledSame values as identical.time_window.
similar.similarity_distanceinteger (1 to 16)when enabledHow close two messages must be to count as similar. Lower is stricter (fewer false positives, more misses); higher is looser.
similar.actionstringwhen enabledSame values as identical.action.
allowliststring arrayfalseBenign phrases exempted from flood detection. Up to 100 entries, up to 200 characters each.

Enabling either detector without both threshold and time_window fails validation on upsert.

Allowlist

allowlist exempts benign phrases, such as game shout-outs or common greetings, from flood detection. Matching is exact after normalization (lowercase, punctuation and extra whitespace stripped), so gg, GG!!!, and gg with surrounding whitespace all match an entry gg, but a longer message like gg buy crypto does not.

The exemption applies only to flood detection. A phrase that both appears in the allowlist and matches a blocklist, AI text rule, or other provider is still actioned by those providers. Entries shorter than 3 characters are ignored.

Detection Labels and Actions

When a detector fires, the moderation response reflects the verdict:

  • One of the following labels is appended to labels:
    • flood_identical — identical-message detection triggered.
    • flood_similar — similar-message detection triggered.
  • recommended_action is escalated to the strictest of the flood action and any other provider's action. Existing verdicts are never demoted, so a remove from another provider is never downgraded to flag by flood detection.
  • harm_type is set to spam if it was not already set.

Example

With a policy chat:messaging configured for identical.threshold=3, time_window=30m, and action=flag, three identical messages from the same user in 30 minutes will trigger the detector on the third message:

// First message from user "u1" on policy "chat:messaging" — no flood signal yet.
// Response: { "labels": [], "recommended_action": "keep", ... }
// Second identical message from "u1" — still below threshold.
// Response: { "labels": [], "recommended_action": "keep", ... }
// Third identical message from "u1" — threshold reached.
// Response: { "labels": ["flood_identical"], "recommended_action": "flag", "harm_type": "spam", ... }