# 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.

- Canonical: https://discordtools.blog/blog/discord-audit-log-reference
- Published: 2026-10-09
- Author: The Index desk
- Facts checked: 2026-08-31
- Sources:
  - Discord Developer Documentation — Audit Log (https://docs.discord.com/developers/resources/audit-log) — checked 2026-08-31
  - Discord Developer Documentation — Permissions (https://docs.discord.com/developers/topics/permissions) — checked 2026-08-31
- Publication: The Index, an independent site not affiliated with Discord Inc.

---
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.