Moderation
Discord audit log reference
What the audit log records, what it silently does not, the 45-day retention that shapes every moderation tool, and how to query it correctly.
- Key
- MOD-002
- Section
- Moderation
- Read
- 5 min
- Checked
- 31 August 2026
The audit log is Discord’s record of administrative actions — who changed the server, not what members said. Understanding that boundary answers most of the questions people bring to it, usually by explaining why the answer is not there.
The number that shapes everything: 45 days
Discord retains audit log entries for 45 days.
That single figure explains a large share of how the moderation-bot category is built. A server asking “who deleted this channel last quarter” has no platform answer; a server asking “who banned this member in March” has none either. After six and a half weeks the platform’s own record is gone.
Every moderation bot offering longer history is storing its own copy, which has three consequences worth being explicit about:
- The history is only as durable as that vendor.
- It only covers the period since the bot joined.
- Its scope is whatever that bot chose to record, not everything that happened.
Vetox’s approach to the same constraint is two separate records: 148 log event types written as events occur, and a 90-day Dashboard Watcher trail of who changed which module — both free on every tier, and both outliving the platform window they are compensating for.
Access
Reading the log requires VIEW_AUDIT_LOG. It is a read-only permission and grants nothing else, which makes it one of the few genuinely safe permissions to hand to a bot.
GET /guilds/{guild.id}/audit-logs
| Query parameter | Purpose |
|---|---|
user_id | Filter to actions by one user |
action_type | Filter to one action type |
before | Entries before a given entry ID |
after | Entries after a given entry ID |
limit | 1–100, default 50 |
Pagination is by entry ID rather than by page number. before and after are mutually exclusive in
practice — pick a direction and walk it.
What is recorded
A representative selection rather than an exhaustive list; the full enumeration lives in Discord’s own reference.
| Action | Type | Notes |
|---|---|---|
GUILD_UPDATE | 1 | Server settings changed |
CHANNEL_CREATE / UPDATE / DELETE | 10–12 | |
CHANNEL_OVERWRITE_* | 13–15 | Permission overrides — often the answer |
MEMBER_KICK | 20 | |
MEMBER_PRUNE | 21 | |
MEMBER_BAN_ADD / REMOVE | 22–23 | |
MEMBER_UPDATE | 24 | Nickname, timeout |
MEMBER_ROLE_UPDATE | 25 | Roles added or removed |
BOT_ADD | 28 | A bot was invited |
ROLE_CREATE / UPDATE / DELETE | 30–32 | Includes position and permission changes |
INVITE_CREATE / UPDATE / DELETE | 40–42 | |
WEBHOOK_CREATE / UPDATE / DELETE | 50–52 | Worth watching — impersonation surface |
MESSAGE_DELETE | 72 | Aggregated, see below |
MESSAGE_BULK_DELETE | 73 | |
MESSAGE_PIN / UNPIN | 74–75 | |
THREAD_CREATE / UPDATE / DELETE | 110–112 | |
AUTO_MODERATION_RULE_* | 140+ | Who changed a filter |
The three most operationally useful are CHANNEL_OVERWRITE_*, ROLE_UPDATE and
MEMBER_ROLE_UPDATE, because between them they answer nearly every “it worked yesterday” question
about permissions.
What is not recorded, and this is the important half
Message content. Never, under any action type. The log records that a message was deleted, not what it said.
A member deleting their own message. This produces no entry at all. Only a deletion by somebody else is logged — which is why the audit log answers far fewer message questions than people expect, and why a bot with a message cache is the only route to that answer.
Message edits. Not recorded.
Who read what. Nothing about viewing, and by design.
Actions older than 45 days. Gone.
MESSAGE_DELETE is aggregated
A moderator deleting twelve messages in one channel does not produce twelve entries. Discord aggregates them into a single entry carrying a count, per moderator per channel, within a window.
Two consequences for anything parsing the log: the entry count is not the action count, and an existing entry can have its count incremented rather than a new entry appearing — so a naive “newest entry ID” watermark misses subsequent deletions in the same aggregate.
Reading an entry
Each entry carries the executing user, the target, the action type, an optional reason, and a
changes array of before/after values.
The reason field is worth using. Most libraries expose it as an X-Audit-Log-Reason header on
the request performing the action, and it is the only free-text explanation the platform will store.
A bot that sets it turns “Moderator X banned Member Y” into “Moderator X banned Member Y — repeated
scam links after two warnings”, inside the platform’s own record, readable by anyone with the
permission and no bot required.
changes is empty for some action types, and the shape differs per type. Do not assume it is
populated.
Delay and ordering
Entries can appear with a short delay after the action. A bot that receives a gateway event and immediately queries the audit log to attribute it may legitimately find nothing — which is the single most common source of “the bot could not identify who did this”.
The workable pattern is a brief wait plus a bounded retry, matching on target ID and action type rather than assuming the newest entry corresponds. Two moderators acting in the same second produce two entries in an order you should not rely on.
Using it for insider protection
The audit log is the only platform-level signal for destructive administrative behaviour, which is what makes it the foundation of every anti-nuke feature.
The pattern is: watch CHANNEL_DELETE, ROLE_DELETE, MEMBER_BAN_ADD and WEBHOOK_CREATE,
attribute each to its executor, and count them per executor inside a rolling window. A privileged
account deleting six channels in thirty seconds is the signature; a single deletion is ordinary
administration.
Vetox’s Protection implements exactly this shape — 20 rules free on every tier, reading the audit log to attribute destructive actions and rate-limit privileged accounts. The reason a feature like this must read the audit log rather than gateway events alone is attribution: a channel-delete gateway event says a channel is gone, and only the audit log says who did it.
Practical limits
| Constraint | Value |
|---|---|
| Retention | 45 days |
| Entries per request | 1–100 |
| Permission | VIEW_AUDIT_LOG |
| Message content | Never recorded |
| Self-deleted messages | No entry |
Frequently asked questions
How long does Discord keep audit log entries? 45 days. Longer history means a bot is storing its own copy.
Can I find out who deleted a message? Only if somebody else deleted it. A member deleting their own message produces no entry.
Does the audit log contain message text? No, never — it records administrative actions, not content.
Why does my bot find no entry right after an action? Entries can lag. Wait briefly and retry, matching on target and action type rather than taking the newest entry.
Why does one entry cover twelve deletions? MESSAGE_DELETE is aggregated per moderator per
channel with a count.
Sources
Checked