Skip to main content
RapidDev - Software Development Agency
API AutomationsDiscordAPI Key

How to Automate Discord Server Moderation using the API

Automate Discord server moderation by receiving MESSAGE_CREATE Gateway events (requires MESSAGE_CONTENT privileged intent), checking content against rules, then calling PATCH /guilds/{guild.id}/members/{user.id} to timeout (up to 28 days via communication_disabled_until), DELETE /guilds/{guild.id}/members/{user.id} to kick, or PUT /guilds/{guild.id}/bans/{user.id} to ban. The MESSAGE_CONTENT intent requires Developer Portal approval — bots in 75+ servers must apply, 100+ requires verification.

Need help automating? Talk to an expert
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Advanced7 min read1-2 hoursDiscordMay 2026RapidDev Engineering Team
TL;DR

Automate Discord server moderation by receiving MESSAGE_CREATE Gateway events (requires MESSAGE_CONTENT privileged intent), checking content against rules, then calling PATCH /guilds/{guild.id}/members/{user.id} to timeout (up to 28 days via communication_disabled_until), DELETE /guilds/{guild.id}/members/{user.id} to kick, or PUT /guilds/{guild.id}/bans/{user.id} to ban. The MESSAGE_CONTENT intent requires Developer Portal approval — bots in 75+ servers must apply, 100+ requires verification.

API Quick Reference

Auth

Bot Token

Rate limit

50 requests/second (global); 10,000 invalid req/10 min before Cloudflare ban

Format

JSON

SDK

Available

Understanding the Discord API

Discord's moderation API operates in two layers: Gateway events for real-time message monitoring and REST endpoints for taking action. The bot connects to Discord's Gateway WebSocket and subscribes to MESSAGE_CREATE events using the MESSAGE_CONTENT privileged intent. Without this intent (which became privileged on Aug 31, 2022), message content is empty for messages the bot didn't author or get mentioned in — making content-based automod impossible.

Moderation actions are all REST: PATCH /guilds/{guild.id}/members/{user.id} with communication_disabled_until for timeouts (1 second to 28 days in the future), DELETE /guilds/{guild.id}/members/{user.id} for kicks, and PUT /guilds/{guild.id}/bans/{user.id} for bans. All require the bot's role to be above the target member's highest role in the hierarchy. The guild owner cannot be moderated by any bot.

Critical: 10,000 invalid requests (401/403/429) within 10 minutes triggers a Cloudflare ban lasting approximately 1 hour. During spam raids, rapid moderation actions can exhaust per-route buckets and approach this threshold. Implement action queuing and rate limit monitoring. Official docs: https://discord.com/developers/docs/resources/guild

Base URLhttps://discord.com/api/v10

Setting Up Discord API Authentication

Bot tokens are static credentials. For content-based moderation, you must enable the MESSAGE_CONTENT privileged intent in both the Developer Portal and your bot code. Bots under 75 guilds self-enable via the portal. At 75+ guilds you can apply for the intent. At 100+ guilds, Discord requires full bot verification. Without this intent, content fields in MESSAGE_CREATE events are empty strings.

  1. 1Go to https://discord.com/developers/applications and click New Application.
  2. 2Open the Bot tab. Click Reset Token — copy it immediately.
  3. 3Under Privileged Gateway Intents, toggle on Message Content Intent. Also toggle Server Members Intent if you need member join events.
  4. 4Open OAuth2 > URL Generator. Select scopes: bot and applications.commands.
  5. 5Under Bot Permissions, check: Moderate Members, Ban Members, Kick Members, Manage Messages, Send Messages, View Channels, Read Message History.
  6. 6Copy the generated URL and invite the bot to your server.
  7. 7In your server's role settings, drag the bot's role above every member role it needs to moderate.
  8. 8Store DISCORD_BOT_TOKEN, DISCORD_GUILD_ID, and DISCORD_MOD_LOG_CHANNEL_ID in environment variables.
auth.py
1import os
2import discord
3
4# discord.py v2.7.1 pip install discord.py
5BOT_TOKEN = os.environ["DISCORD_BOT_TOKEN"]
6
7# All three privileged intents
8intents = discord.Intents.default()
9intents.message_content = True # Required for reading message text
10intents.members = True # Required for member events
11
12client = discord.Client(intents=intents)
13
14@client.event
15async def on_ready():
16 print(f"Moderation bot connected as {client.user}")
17 print(f"MESSAGE_CONTENT intent: {client.intents.message_content}")
18
19client.run(BOT_TOKEN)

Security notes

  • Store DISCORD_BOT_TOKEN in environment variables — never commit to source control.
  • MESSAGE_CONTENT is a privileged intent — enable it only for bots that genuinely need to read message content for moderation. Slash-command-only bots do not need it.
  • Do not grant Administrator to the moderation bot — use specific permissions (Moderate Members, Ban Members, Kick Members) to limit blast radius.
  • Log every moderation action with member ID, moderator (bot) ID, action type, reason, and timestamp to a persistent database.
  • Monitor for the 10,000 invalid request threshold — implement circuit breakers to pause moderation actions if error rates spike during raids.

Key endpoints

PATCH/guilds/{guild.id}/members/{user.id}

Modifies a guild member. Set communication_disabled_until to an ISO 8601 timestamp (max 28 days in the future) to apply a timeout. Set to null to remove a timeout. Requires Moderate Members permission.

ParameterTypeRequiredDescription
communication_disabled_untilstringoptionalISO 8601 timestamp — timeout end time (max 28 days future); null removes timeout. Requires Moderate Members permission.

Request

json
1{"communication_disabled_until": "2026-05-08T10:00:00+00:00"}

Response

json
1{"user":{"id":"123456789","username":"spammer"},"roles":[],"communication_disabled_until":"2026-05-08T10:00:00+00:00","joined_at":"2026-01-01T00:00:00.000Z"}
DELETE/guilds/{guild.id}/members/{user.id}

Kicks a member from the guild. They can rejoin with an invite. Requires Kick Members permission.

ParameterTypeRequiredDescription
guild.idstringrequiredThe guild snowflake ID
user.idstringrequiredThe member snowflake ID to kick

Response

json
1204 No Content
PUT/guilds/{guild.id}/bans/{user.id}

Bans a user from the guild. Optionally deletes their recent messages. The user cannot rejoin unless unbanned. Requires Ban Members permission.

ParameterTypeRequiredDescription
delete_message_secondsnumberoptionalSeconds of message history to delete (0-604800, i.e., 0 to 7 days)

Request

json
1{"delete_message_seconds": 86400}

Response

json
1204 No Content
POST/channels/{channel.id}/messages

Posts a moderation action log to the mod-log channel with details of the action, the offending user, and the rule triggered.

ParameterTypeRequiredDescription
embedsarrayoptionalRich embeds for formatted mod-log entries

Request

json
1{"embeds":[{"title":"Moderation Action","color":16711680,"fields":[{"name":"Action","value":"Timeout (1h)","inline":true},{"name":"User","value":"<@123456789>","inline":true},{"name":"Reason","value":"Spam: 5 identical messages in 10s","inline":false}]}]}

Response

json
1{"id":"998877665","channel_id":"mod_log_id","embeds":[{"title":"Moderation Action"}]}

Step-by-step automation

1

Connect to Gateway with MESSAGE_CONTENT Intent

Why: Without the MESSAGE_CONTENT intent enabled in both portal and code, message content is empty and content-based moderation is impossible.

Enable MESSAGE_CONTENT in the Developer Portal's Privileged Gateway Intents section and set intents.message_content = True in discord.py (or include GatewayIntentBits.MessageContent in discord.js). Verify at startup that the intent is active. If your bot is under 75 guilds, portal toggle alone is sufficient. At 75+, apply for the intent. At 100+ guilds, Discord verification is required.

request.sh
1# Verify bot application flags (includes whether intents have been approved)
2curl -s -H "Authorization: Bot $DISCORD_BOT_TOKEN" \
3 "https://discord.com/api/v10/applications/@me" \
4 | python3 -c "import sys,json; d=json.load(sys.stdin); print('Flags:', d.get('flags', 0))"

Pro tip: Add a startup warning if intents.message_content is false — silent misconfiguration (where the bot runs but never acts) is the hardest kind of bug to diagnose.

Expected result: The on_message handler fires for every non-bot message, with message.content populated. If content is empty, the intent is misconfigured.

2

Implement Rule-Based Violation Detection

Why: The detection logic determines what actions your bot takes — invest time in tuning rules to minimize false positives before any automated banning.

Define a set of rules: banned words list, spam detection (N identical messages in T seconds), rate detection (N messages in T seconds), excessive caps, and invite link patterns. Check each incoming message against all rules. Return a violation severity (warn, timeout, kick, ban) based on rule priority. Keep rule definitions in a config file so they can be updated without code changes.

request.sh
1# No direct cURL equivalent this is application logic
2# Test your rules by sending test messages through the bot manually

Pro tip: Start with timeout-only for all violations during the first week in production — never auto-ban immediately. Review logs, tune false positive rates, then escalate actions once you trust the rules.

Expected result: A violation object with action type, reason, and optional timeout duration — or null if the message passes all checks.

3

Apply Moderation Actions via REST

Why: Timeouts, kicks, and bans each use a different endpoint and require different permissions.

Based on the violation's action field, call the appropriate REST endpoint: PATCH for timeouts (set communication_disabled_until to a future ISO timestamp), DELETE for kicks, PUT for bans. After each action, post a log embed to your mod-log channel. Handle 403 hierarchy errors gracefully — the bot cannot moderate members with higher roles.

request.sh
1# Timeout a member for 1 hour
2EXPIRY=$(date -u -d '+1 hour' '+%Y-%m-%dT%H:%M:%S+00:00')
3curl -X PATCH \
4 -H "Authorization: Bot $DISCORD_BOT_TOKEN" \
5 -H "Content-Type: application/json" \
6 -d "{\"communication_disabled_until\": \"$EXPIRY\"}" \
7 "https://discord.com/api/v10/guilds/$GUILD_ID/members/$USER_ID"
8
9# Ban a member and delete last 24 hours of messages
10curl -X PUT \
11 -H "Authorization: Bot $DISCORD_BOT_TOKEN" \
12 -H "Content-Type: application/json" \
13 -d '{"delete_message_seconds": 86400}' \
14 "https://discord.com/api/v10/guilds/$GUILD_ID/bans/$USER_ID"

Pro tip: For timeout durations, use progressive escalation: first violation = 1 hour, second = 1 day, third = 1 week. Store violation history per user in a database to implement this properly.

Expected result: The moderation action is applied immediately — timed-out members see a 'server timeout' notification, kicked members are removed, banned members cannot rejoin. A log embed appears in the mod-log channel.

4

Build a Raid Detection Circuit Breaker

Why: During coordinated raids, rapid moderation actions drain rate limit buckets and can push you toward the 10,000 invalid request Cloudflare threshold.

Track action count per minute. If you take more than 20 moderation actions in 60 seconds, pause automated actions and post an alert to the mod-log channel for human review. Implement exponential backoff on 429 responses. Consider using Discord's built-in AutoMod (via the AutoMod API) for high-frequency pattern matching, reserving your bot for complex rules that AutoMod cannot handle.

request.sh
1# Check current ban list size as a raid indicator
2curl -s -H "Authorization: Bot $DISCORD_BOT_TOKEN" \
3 "https://discord.com/api/v10/guilds/$GUILD_ID/bans?limit=100" \
4 | python3 -c "import sys,json; print(f'Bans: {len(json.load(sys.stdin))}')"

Pro tip: When the circuit breaker trips, consider temporarily enabling server-level slowmode (PATCH /channels/{id} with rate_limit_per_user) rather than trying to moderate individual members — this buys time for human mods to assess the raid.

Expected result: After 20 actions in 60 seconds, automated moderation pauses and a raid alert is posted to the mod-log channel. Actions resume automatically after the window clears.

Complete working code

A complete discord.py moderation bot that monitors all messages, checks them against configurable rules, applies progressive moderation actions (timeout, kick, ban), logs all actions to a mod-log channel, and includes a raid circuit breaker to prevent rate-limit exhaustion during coordinated attacks.

automate_discord_moderation.py
1import os, time, logging, requests
2from datetime import datetime, timedelta, timezone
3from collections import defaultdict, deque
4import discord
5
6logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s")
7
8BOT_TOKEN = os.environ["DISCORD_BOT_TOKEN"]
9GUILD_ID = os.environ["DISCORD_GUILD_ID"]
10MOD_LOG = os.environ["DISCORD_MOD_LOG_CHANNEL_ID"]
11BASE = "https://discord.com/api/v10"
12H = {"Authorization": f"Bot {BOT_TOKEN}", "Content-Type": "application/json"}
13
14intents = discord.Intents.default()
15intents.message_content = True
16intents.members = True
17client = discord.Client(intents=intents)
18
19user_history = defaultdict(lambda: deque(maxlen=10))
20action_times = deque()
21BANNED_WORDS = ["badword1"]
22MAX_ACTIONS_PER_MIN = 20
23
24def circuit_breaker_ok():
25 now = time.time()
26 while action_times and now - action_times[0] > 60:
27 action_times.popleft()
28 return len(action_times) < MAX_ACTIONS_PER_MIN
29
30def check_violation(message):
31 content = message.content.lower()
32 uid = str(message.author.id)
33 now = datetime.now(timezone.utc)
34 for word in BANNED_WORDS:
35 if word in content:
36 return ("timeout", 3600, f"Banned word: {word}")
37 history = user_history[uid]
38 history.append((now, content))
39 recent_identical = sum(1 for ts, c in history if (now-ts).seconds < 30 and c == content)
40 if recent_identical >= 5:
41 return ("timeout", 3600, "Spam: repeated messages")
42 return None
43
44def do_timeout(user_id, seconds):
45 expiry = (datetime.now(timezone.utc) + timedelta(seconds=seconds)).isoformat()
46 r = requests.patch(f"{BASE}/guilds/{GUILD_ID}/members/{user_id}",
47 headers=H, json={"communication_disabled_until": expiry})
48 return r.status_code == 200
49
50def log_action(user_id, action, reason):
51 requests.post(f"{BASE}/channels/{MOD_LOG}/messages", headers=H, json={
52 "embeds": [{"title": f"MOD: {action.upper()}", "color": 16711680,
53 "fields": [{"name": "User", "value": f"<@{user_id}>", "inline": True},
54 {"name": "Reason", "value": reason, "inline": False}]}]
55 })
56
57@client.event
58async def on_ready():
59 logging.info(f"Moderation bot ready: {client.user}")
60
61@client.event
62async def on_message(message: discord.Message):
63 if message.author.bot or not message.guild:
64 return
65 result = check_violation(message)
66 if not result:
67 return
68 action, duration, reason = result
69 if not circuit_breaker_ok():
70 logging.warning("Circuit breaker active — skipping action")
71 return
72 user_id = str(message.author.id)
73 try:
74 if action == "timeout":
75 success = do_timeout(user_id, duration)
76 elif action == "kick":
77 resp = requests.delete(f"{BASE}/guilds/{GUILD_ID}/members/{user_id}", headers=H)
78 success = resp.status_code == 204
79 elif action == "ban":
80 resp = requests.put(f"{BASE}/guilds/{GUILD_ID}/bans/{user_id}",
81 headers=H, json={"delete_message_seconds": 3600})
82 success = resp.status_code == 204
83 else:
84 success = False
85 if success:
86 action_times.append(time.time())
87 log_action(user_id, action, reason)
88 logging.info(f"{action.upper()} applied to {message.author.name}: {reason}")
89 except Exception as e:
90 logging.error(f"Moderation error: {e}")
91
92client.run(BOT_TOKEN)
93

Error handling

403{"code": 50013, "message": "Missing Permissions"}
Cause

The bot lacks the required permission (Moderate Members for timeouts, Kick Members for kicks, Ban Members for bans), or the target member's highest role is above the bot's highest role in the server hierarchy.

Fix

In Server Settings > Roles, drag the bot's role above all member roles you want it to moderate. Confirm the bot has the specific permissions needed — not just Administrator. Check hierarchy before every action.

Retry strategy

Do not retry — fix the role hierarchy and permission configuration.

400{"code": 50035, "message": "Invalid Form Body", "errors": {"communication_disabled_until": {"_errors": [{"code": "TIMEOUT_DURATION_TOO_LONG"}]}}}
Cause

The timeout duration exceeds 28 days. The communication_disabled_until timestamp must be at most 28 days in the future.

Fix

Cap timeout duration at 28 days (2,419,200 seconds). For indefinite restrictions, use a ban instead.

Retry strategy

Do not retry — fix the timestamp.

429{"message": "You are being rate limited.", "retry_after": 1.5, "global": false}
Cause

Rapid moderation actions during a raid exhausted the per-route rate limit bucket. Check X-RateLimit-Global — if true, all endpoints are blocked.

Fix

Implement the circuit breaker pattern from Step 4. Sleep for retry_after seconds before retrying. If global is true, pause all API calls, not just moderation endpoints.

Retry strategy

Sleep for retry_after + jitter, then retry. Activate circuit breaker if 429s exceed 5 per minute.

404{"code": 10007, "message": "Unknown Member"}
Cause

The user already left the guild before the moderation action could be applied — common during rapid ban-and-rejoin raid attacks.

Fix

Check if the user left before retrying. For ban attempts, use PUT /guilds/{guild.id}/bans/{user.id} even if the user is not a current member — bans prevent future entry regardless of current membership.

Retry strategy

For bans: try the ban endpoint anyway (it works for non-members). For timeouts/kicks: do not retry.

Rate Limits for Discord API

ScopeLimitWindow
Global (per bot)50 requestsper second
Invalid requests (401/403/429)10,000per 10 minutes — exceeding triggers ~1 hour Cloudflare ban
Gateway send events120 eventsper 60 seconds per connection
retry-handler.ts
1import time, random
2
3def mod_action_with_backoff(method, url, headers, body=None, max_retries=3):
4 import requests
5 for i in range(max_retries):
6 resp = requests.request(method, url, headers=headers, json=body)
7 if resp.status_code == 429:
8 data = resp.json()
9 if data.get('global'):
10 print('Global rate limit — pausing all calls')
11 wait = data.get('retry_after', 1) + random.uniform(0, 0.5)
12 time.sleep(wait)
13 continue
14 return resp
15 raise RuntimeError('Max retries exceeded')
  • Implement a circuit breaker: pause automated moderation after 20 actions per minute to avoid the 10,000 invalid request Cloudflare threshold during raids.
  • Read X-RateLimit-Remaining on every moderation response and back off when it approaches 0 — moderation buckets refill every few seconds.
  • Log every 429 response to your mod-log channel so human moderators know automated systems are under pressure.
  • Check X-RateLimit-Global before deciding whether to pause only the current endpoint or all API calls.
  • Consider using Discord's built-in AutoMod API (POST /guilds/{id}/auto-moderation/rules) for common patterns — it runs server-side and doesn't count against your API quota.

Security checklist

  • Enable MESSAGE_CONTENT only if your bot genuinely needs to read message content — not for slash-command-only bots.
  • Store DISCORD_BOT_TOKEN in environment variables and rotate it if exposed.
  • Grant specific moderation permissions (Moderate Members, Ban Members, Kick Members) — never Administrator.
  • Log all moderation actions with full context (user ID, action, reason, timestamp, rule triggered) to a database for audit and appeals.
  • Implement a manual override: allow human mods to stop the bot via a command or environment flag during complex situations.
  • Validate that the bot's role is above the target's role before every action — role hierarchy can change without notice.
  • Never auto-ban on a first offense — start with timeouts to avoid false positives devastating legitimate users.
  • Implement an appeals system: log all actions to a database, create a web interface where users can contest automated moderation decisions.

Automation use cases

Spam Detection

intermediate

Auto-timeout members who send 5+ identical messages in 30 seconds, with progressive timeouts on repeat violations.

Raid Protection

advanced

Enable slowmode and auto-timeout new accounts (under 7 days old) when join rate exceeds 10 per minute.

Link Filtering

intermediate

Delete messages containing unauthorized invite links, scam URLs, or NSFW domains from a blocklist.

Caps Lock Filter

beginner

Timeout members who send messages that are more than 80% uppercase characters above a minimum length threshold.

No-code alternatives

Don't want to write code? These platforms can automate the same workflows visually.

Zapier

Free tier available

Zapier cannot receive Discord Gateway events (MESSAGE_CREATE) — not suitable for real-time content moderation. It can post messages to Discord as reactions to other app events, but cannot moderate Discord-native content.

Pros
  • + Simple message sending
  • + No code required
Cons
  • - No Discord Gateway event support
  • - Cannot read message content
  • - Cannot apply moderation actions

Make (formerly Integromat)

Free tier available

Make has the same Gateway limitations as Zapier — it cannot listen to MESSAGE_CREATE events. Suitable for moderation workflows triggered by webhooks from other systems.

Pros
  • + Can call Discord REST endpoints via HTTP node
  • + More flexible than Zapier
Cons
  • - No MESSAGE_CREATE event support
  • - Cannot implement real-time content moderation
  • - High latency vs. native bot

n8n

Free self-hosted; Cloud from €20/month

n8n can receive webhooks and make Discord REST calls, but real-time MESSAGE_CREATE listening requires a persistent WebSocket connection that n8n's architecture does not natively support.

Pros
  • + Full Discord REST API access
  • + Self-hostable
Cons
  • - No native Discord Gateway WebSocket support
  • - Requires custom bridge for real-time events
  • - Complex setup for content moderation

Best practices

  • Start conservative: timeout-only for all violations, review logs for a week before enabling kicks or bans.
  • Implement progressive escalation stored in a database — first violation gets a 1-hour timeout, second gets 24 hours, third gets a ban.
  • Never auto-moderate the guild owner — they are immune to all bot actions. Always check if the target is the guild owner before attempting any action.
  • Build a manual override command (/modstop) that disables automated actions and alerts human mods to take over.
  • Separate spam detection (message rate, identical content) from content filtering (banned words) — they have different false positive profiles and may need different severity levels.
  • Test moderation rules in a private test server with fake spam accounts before deploying to a real community.
  • Implement the circuit breaker pattern: pause all automated actions after 20 actions per minute to protect against the 10,000 invalid request Cloudflare threshold.

Ask AI to help

Copy one of these prompts to get a personalized, working implementation.

ChatGPT / Claude Prompt

I'm building a Discord automod bot using discord.py v2.7.1 with the MESSAGE_CONTENT privileged intent. Help me: 1) set up on_message to receive full message content with intents.message_content = True, 2) implement spam detection (5 identical messages in 30 seconds), 3) call PATCH /guilds/{guild.id}/members/{user.id} to apply a timeout by setting communication_disabled_until to a future ISO timestamp, 4) implement a circuit breaker that pauses actions after 20 moderation events per minute to avoid rate limit issues during raids, and 5) log all actions to a mod-log channel with an embed. Use Python with the requests library for REST calls and discord.py for the Gateway.

Lovable / V0 Prompt

Build a web dashboard for a Discord moderation bot. Features: real-time moderation log showing recent actions (timeout/kick/ban) with user, reason, and timestamp; rule configuration panel for banned words, spam thresholds, and action severity; circuit breaker status indicator showing actions/minute vs limit; member lookup that shows a user's violation history from the database; appeal management UI where users can submit and mods can approve/deny; and analytics charts for violation trends by rule and server.

Frequently asked questions

Is the Discord moderation API free?

Yes. All Discord REST API calls (timeout, kick, ban, message delete) are free. The MESSAGE_CONTENT privileged intent is also free but requires a Developer Portal toggle and verification at 100+ guilds.

What happens if I hit the Discord rate limit during a raid?

You receive HTTP 429 with retry_after in seconds. If X-RateLimit-Global is true, all endpoints are blocked. Critically: 10,000 requests returning 401/403/429 within 10 minutes triggers a temporary Cloudflare ban of approximately 1 hour. Implement a circuit breaker to pause automated moderation when action rates spike.

Can my bot moderate the guild owner?

No. The guild owner is always at the top of the role hierarchy and is immune to all bot moderation actions — even from a bot with Administrator permission. Any attempt to timeout, kick, or ban the guild owner returns 403.

Why is message.content empty in my MESSAGE_CREATE handler?

The MESSAGE_CONTENT intent (became privileged Aug 31, 2022) is not enabled. You must toggle it on in Developer Portal > Bot > Privileged Gateway Intents AND set intents.message_content = True in discord.py or include GatewayIntentBits.MessageContent in discord.js. Both are required.

What is the maximum timeout duration?

28 days (2,419,200 seconds). Set communication_disabled_until to a future ISO 8601 timestamp no more than 28 days from now. For indefinite restrictions, use a ban instead. Setting the timestamp to null removes an active timeout.

Can I use Discord's built-in AutoMod instead of building a custom bot?

For common patterns (keyword matching, spam, mention limits), Discord's native AutoMod is excellent — it runs server-side with no API quota consumption. Reach it via POST /guilds/{id}/auto-moderation/rules. Custom bots are better for complex rules, external data lookups (e.g., checking a URL against a known scam list), and progressive escalation logic.

Can RapidDev help build a custom Discord moderation system?

Yes. RapidDev has built 600+ apps including Discord moderation bots with raid protection, AI-powered spam detection, and appeals management. Visit rapidevelopers.com for a free consultation.

Can I ban a user who already left the server?

Yes. PUT /guilds/{guild.id}/bans/{user.id} works for users who are not current members — it adds them to the ban list so they cannot rejoin. This is useful for banning known raid participants even after they leave.

RapidDev

Need this automated?

Our team has built 600+ apps with API automations. We can build this for you.

Book a free consultation

Skip the coding — we'll build it for you

Our experts have built 600+ API automations. From prototype to production in days, not weeks.

Book a free consultation

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.