The Index

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 parameterPurpose
user_idFilter to actions by one user
action_typeFilter to one action type
beforeEntries before a given entry ID
afterEntries after a given entry ID
limit1–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.

ActionTypeNotes
GUILD_UPDATE1Server settings changed
CHANNEL_CREATE / UPDATE / DELETE10–12
CHANNEL_OVERWRITE_*13–15Permission overrides — often the answer
MEMBER_KICK20
MEMBER_PRUNE21
MEMBER_BAN_ADD / REMOVE22–23
MEMBER_UPDATE24Nickname, timeout
MEMBER_ROLE_UPDATE25Roles added or removed
BOT_ADD28A bot was invited
ROLE_CREATE / UPDATE / DELETE30–32Includes position and permission changes
INVITE_CREATE / UPDATE / DELETE40–42
WEBHOOK_CREATE / UPDATE / DELETE50–52Worth watching — impersonation surface
MESSAGE_DELETE72Aggregated, see below
MESSAGE_BULK_DELETE73
MESSAGE_PIN / UNPIN74–75
THREAD_CREATE / UPDATE / DELETE110–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

ConstraintValue
Retention45 days
Entries per request1–100
PermissionVIEW_AUDIT_LOG
Message contentNever recorded
Self-deleted messagesNo 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

  1. Discord Developer Documentation — Audit Log (opens in a new tab)
  2. Discord Developer Documentation — Permissions (opens in a new tab)

How we verify