mirror of
https://github.com/fluxerapp/fluxer
synced 2026-10-18 05:25:40 +09:00
569 lines
42 KiB
Plaintext
569 lines
42 KiB
Plaintext
---
|
|
# SPDX-License-Identifier: AGPL-3.0-or-later
|
|
title: Guild audit logs
|
|
description: Guild audit log entries, their action registry, and the audit reason contract.
|
|
---
|
|
|
|
import RouteHeader from '@/components/RouteHeader.astro';
|
|
|
|
An audit log entry records one change made to a guild and the account that made it. Only [List guild audit logs](#list-guild-audit-logs) and its [Admin API counterpart](/admin-api/guilds/#list-guild-audit-logs) read them.
|
|
|
|
## Audit log reason
|
|
|
|
A route marked Audit reason accepts the `X-Audit-Log-Reason` request header, listed with the other [standard request headers](/http-api/#standard-request-headers). Fluxer reads the value verbatim and never percent-decodes it, so a caller that percent-encodes the reason stores and reads back the percent-encoded form.
|
|
|
|
Fluxer trims the value. A value that is blank before trimming, empty after it, or longer than 512 characters after it counts as no reason at all. None of those values fails the request, so a reason that misses the bound is dropped and the operation still succeeds.
|
|
|
|
[Modify channel](/http-api/channels/#modify-channel), [Delete or leave channel](/http-api/channels/#delete-or-leave-channel), [Set channel permission overwrite](/http-api/channels/#set-channel-permission-overwrite), [Delete channel permission overwrite](/http-api/channels/#delete-channel-permission-overwrite), [Delete message](/http-api/messages/#delete-message), [Bulk delete messages](/http-api/messages/#bulk-delete-messages), [Pin message](/http-api/messages/#pin-message), and [Unpin message](/http-api/messages/#unpin-message) record the header as well. [Start thread from message](/http-api/threads/#start-thread-from-message) and [Start thread](/http-api/threads/#start-thread) record it on their thread entries. [Create forum tag](/http-api/forums/#create-forum-tag), [Modify forum tag](/http-api/forums/#modify-forum-tag), and [Delete forum tag](/http-api/forums/#delete-forum-tag) record it on their channel update entries.
|
|
|
|
Two operations use a reason from the request body when the header supplies none:
|
|
|
|
- [Create or replace guild ban](/http-api/guild-moderation/#create-or-replace-guild-ban) uses the body `reason`.
|
|
- [Modify guild member](/http-api/guild-members/#modify-guild-member) uses the trimmed `timeout_reason` when the body also has `communication_disabled_until`.
|
|
|
|
Fluxer never percent-decodes a body reason either. The operation writes the accepted reason onto its entry, returns it as the entry `reason` field, and sends it in the [Guild Audit Log Entry Create](/gateway/events/#guild-audit-log-entry-create) Dispatch.
|
|
|
|
Fluxer resolves the reason again when it reads an entry. A [MEMBER_BAN_ADD](#audit-actions) entry with a blank stored reason returns the ban `reason` from its change list, and a [MEMBER_UPDATE](#audit-actions) entry with a blank stored reason returns the timeout reason stored with it, when it has one. The result is trimmed, and a blank result is omitted.
|
|
|
|
:::note[Some operations record no reason at all]
|
|
Bot addition, the role Fluxer creates and assigns to a bot it adds with permissions, a Visionary role grant, a message deletion made by [Delete message attachment](/http-api/messages/#delete-message-attachment), and a consolidated bulk deletion entry never have one.
|
|
:::
|
|
|
|
## Guild audit log response object
|
|
|
|
One page of audit history together with the accounts and webhooks it references. Only `audit_log_entries` is paginated.
|
|
|
|
### Structure
|
|
|
|
| Field | Type | Description |
|
|
| --- | --- | --- |
|
|
| audit_log_entries<sup>1</sup> | array[[guild audit log entry](#guild-audit-log-entry-object) object] | The page of entries this request returned |
|
|
| users<sup>2</sup> | array[[partial user](/http-api/users/#partial-user-object) object] | The accounts the returned entries name |
|
|
| webhooks<sup>3</sup> | array[[audit log webhook](#audit-log-webhook-object) object] | The webhooks a returned webhook action targets |
|
|
| threads?<sup>4</sup> | array[[thread](/http-api/threads/#thread-object) object] | The threads a returned thread action targets |
|
|
|
|
<sup>1</sup> The page ordering is defined by the [query parameters](#query-parameters) of the request that produced it
|
|
|
|
<sup>2</sup> Deduplicated by user ID, and a referenced value that is not a snowflake names no account
|
|
|
|
<sup>3</sup> One object for each distinct webhook that a returned webhook action targets and that still exists, so a deleted webhook resolves to no object
|
|
|
|
<sup>4</sup> Present only for a bot and for a user session that declares the [`channel_threads` client capability](/http-api/threads/#client-capability). One object for each distinct thread that a returned [thread action](#audit-actions) targets and that still exists
|
|
|
|
`users` has the actor of every returned entry and each account the entry references:
|
|
|
|
- `target_id` of every action from [MEMBER_KICK](#audit-actions) through [MEMBER_DISCONNECT](#audit-actions), and of [BOT_ADD](#audit-actions)
|
|
- `target_id` of a [channel overwrite action](#audit-actions) whose `options.type` is `1`
|
|
- the `owner_id` change `new_value` of [GUILD_UPDATE](#audit-actions)
|
|
- the `moderator_id` change `old_value` of [MEMBER_BAN_REMOVE](#audit-actions)
|
|
- `options.inviter_id` of [INVITE_DELETE](#audit-actions)
|
|
- the `creator_id` change `old_value` of [WEBHOOK_DELETE](#audit-actions), [EMOJI_DELETE](#audit-actions), and [STICKER_DELETE](#audit-actions)
|
|
|
|
An account that can no longer be resolved is still returned, as the deleted-account representation with the username `DeletedUser`, the discriminator `0000`, the global name `Deleted User`, a null avatar, a null avatar colour, and `flags` of `0`.
|
|
|
|
## Guild audit log entry object
|
|
|
|
One recorded guild change. An entry is immutable once written, except for a run of message deletion entries, which [List guild audit logs](#list-guild-audit-logs) can replace with a single consolidated entry.
|
|
|
|
### Structure
|
|
|
|
| Field | Type | Description |
|
|
| --- | --- | --- |
|
|
| id | snowflake | The ID of the entry, whose [snowflake](/snowflakes/) timestamp is the time it was written |
|
|
| action_type | integer | [Audit action](#audit-actions) value that identifies the recorded operation |
|
|
| user_id<sup>1</sup> | snowflake | The ID of the user that did the action |
|
|
| target_id<sup>2</sup> | ?string | The ID of the affected entity |
|
|
| reason?<sup>3</sup> | string | The [audit log reason](#audit-log-reason) recorded with the operation |
|
|
| options?<sup>4</sup> | [audit log options](#audit-log-options-object) object | The context fields this [audit action](#audit-actions) records |
|
|
| changes?<sup>5</sup> | array[[audit log change](#audit-log-change-object) object] | The fields the mutation changed |
|
|
|
|
<sup>1</sup> Every entry has the acting user ID, and an entry produced by consolidation has the actor of the consolidated run
|
|
|
|
<sup>2</sup> A decimal snowflake string for every action except [INVITE_CREATE](#audit-actions) and [INVITE_DELETE](#audit-actions), where it is the invite code, and null for [MESSAGE_BULK_DELETE](#audit-actions)
|
|
|
|
<sup>3</sup> The field is omitted when no non-blank reason resolves as described under [audit log reason](#audit-log-reason), so an entry written by consolidation never has one
|
|
|
|
<sup>4</sup> The field is omitted when the action recorded no option key that this registry publishes
|
|
|
|
<sup>5</sup> The field is omitted when the action records no field change, so it is never returned as an empty array
|
|
|
|
:::note[An entry expires 45 days after the write]
|
|
Entries remain available for 45 days. A consolidated entry starts a new 45-day period.
|
|
:::
|
|
|
|
### Example
|
|
|
|
```json
|
|
{
|
|
"id": "1501314428688998184",
|
|
"action_type": 24,
|
|
"user_id": "1489002177550843905",
|
|
"target_id": "1489002177550843906",
|
|
"reason": "Nickname violated the rules",
|
|
"changes": [{"key": "nick", "old_value": "spam bot", "new_value": null}]
|
|
}
|
|
```
|
|
|
|
## Audit actions
|
|
|
|
The Value column is the numeric `action_type`, which is also the value the `action_type` query filter accepts. Each description names what `target_id` identifies and which [audit log options](#audit-log-options-object) the action records. The overwrite options are `id`, `type`, `channel_id`, and `role_name`<sup>10</sup>. The invite options are `max_age`, `max_uses`, `temporary`, `channel_id`<sup>7</sup>, and `inviter_id`<sup>7</sup>.
|
|
|
|
| Value | Name | Description |
|
|
| --- | --- | --- |
|
|
| 1 | GUILD_UPDATE<sup>1</sup> | Guild settings or ownership were changed. `target_id` is the guild, and the action records no options |
|
|
| 10 | CHANNEL_CREATE | Guild channel was created. `target_id` is the channel, and the action records `type` |
|
|
| 11 | CHANNEL_UPDATE | Guild channel was changed. `target_id` is the channel, and the action records `type` |
|
|
| 12 | CHANNEL_DELETE | Guild channel was deleted. `target_id` is the channel, and the action records `type` |
|
|
| 13 | CHANNEL_OVERWRITE_CREATE | Channel permission overwrite was created. `target_id` is the role or member, and the action records the overwrite options |
|
|
| 14 | CHANNEL_OVERWRITE_UPDATE | Channel permission overwrite was changed. `target_id` is the role or member, and the action records the overwrite options |
|
|
| 15 | CHANNEL_OVERWRITE_DELETE | Channel permission overwrite was deleted. `target_id` is the role or member, and the action records the overwrite options |
|
|
| 20 | MEMBER_KICK<sup>2</sup> | Member was removed by a moderator. `target_id` is the user, and the action records no options |
|
|
| 21 | MEMBER_PRUNE<sup>3</sup> | Inactive members were pruned. `target_id` is nothing, and the action records no options |
|
|
| 22 | MEMBER_BAN_ADD | Guild ban was created or replaced. `target_id` is the user, and the action records `delete_message_seconds`<sup>4</sup> |
|
|
| 23 | MEMBER_BAN_REMOVE | Guild ban was removed. `target_id` is the user, and the action records no options |
|
|
| 24 | MEMBER_UPDATE | Guild member state was changed. `target_id` is the user, and the action records no options |
|
|
| 25 | MEMBER_ROLE_UPDATE | One role was added to or removed from a member. `target_id` is the user, and the action records `role_name`<sup>5</sup> |
|
|
| 26 | MEMBER_MOVE<sup>6</sup> | Member voice session was moved to another channel. `target_id` is the user, and the action records `channel_id` and `count` |
|
|
| 27 | MEMBER_DISCONNECT<sup>6</sup> | Member voice session was disconnected. `target_id` is the user, and the action records `channel_id` and `count` |
|
|
| 28 | BOT_ADD | Bot was added to the guild. `target_id` is the user, and the action records `temporary` |
|
|
| 30 | ROLE_CREATE | Role was created. `target_id` is the role, and the action records no options |
|
|
| 31 | ROLE_UPDATE | Role was changed. `target_id` is the role, and the action records `role_name` |
|
|
| 32 | ROLE_DELETE | Role was deleted. `target_id` is the role, and the action records no options |
|
|
| 40 | INVITE_CREATE | Invite was created. `target_id` is the invite code, and the action records the invite options |
|
|
| 41 | INVITE_UPDATE<sup>8</sup> | Invite was changed. `target_id` is the invite code, and the action records no options |
|
|
| 42 | INVITE_DELETE | Invite was deleted. `target_id` is the invite code, and the action records the invite options |
|
|
| 50 | WEBHOOK_CREATE<sup>11</sup> | Webhook was created. `target_id` is the webhook, and the action records `channel_id` and `type`<sup>7</sup> |
|
|
| 51 | WEBHOOK_UPDATE | Webhook was changed. `target_id` is the webhook, and the action records `channel_id` and `type`<sup>7</sup> |
|
|
| 52 | WEBHOOK_DELETE<sup>11</sup> | Webhook was deleted. `target_id` is the webhook, and the action records `channel_id` and `type`<sup>7</sup> |
|
|
| 60 | EMOJI_CREATE | Emoji was created. `target_id` is the emoji, and the action records no options |
|
|
| 61 | EMOJI_UPDATE | Emoji was changed. `target_id` is the emoji, and the action records no options |
|
|
| 62 | EMOJI_DELETE | Emoji was deleted. `target_id` is the emoji, and the action records no options |
|
|
| 72 | MESSAGE_DELETE | Single message was deleted. `target_id` is the message, and the action records `channel_id` |
|
|
| 73 | MESSAGE_BULK_DELETE<sup>9</sup> | Several messages were deleted in one operation. `target_id` is nothing, and the action records `channel_id` and `count` |
|
|
| 74 | MESSAGE_PIN | Message was pinned. `target_id` is the message, and the action records `channel_id` and `message_id` |
|
|
| 75 | MESSAGE_UNPIN | Message was unpinned. `target_id` is the message, and the action records `channel_id` and `message_id` |
|
|
| 90 | STICKER_CREATE | Sticker was created. `target_id` is the sticker, and the action records no options |
|
|
| 91 | STICKER_UPDATE | Sticker was changed. `target_id` is the sticker, and the action records no options |
|
|
| 92 | STICKER_DELETE | Sticker was deleted. `target_id` is the sticker, and the action records no options |
|
|
| 110 | THREAD_CREATE | Thread was created. `target_id` is the thread, and the action records no options |
|
|
| 111 | THREAD_UPDATE | Thread was changed. `target_id` is the thread, and the action records `type` |
|
|
| 112 | THREAD_DELETE | Thread was deleted. `target_id` is the thread, and the action records `type` |
|
|
|
|
<sup>1</sup> Recorded by [Modify guild](/http-api/guilds/#modify-guild), by [Modify guild custom invite URL](/http-api/guilds/#modify-guild-custom-invite-url), and by [Transfer guild ownership](/http-api/guild-members/#transfer-guild-ownership), and `target_id` is the guild in every case
|
|
|
|
<sup>2</sup> A kick entry is always recorded with no change list, so the removed membership state is not published through the entry
|
|
|
|
<sup>3</sup> The value is defined by the wire contract and is accepted by the `action_type` filter, and no current guild operation records it
|
|
|
|
<sup>4</sup> The option is recorded when the resolved message deletion window of the ban is positive. An older ban entry can have the deprecated `delete_member_days` option
|
|
|
|
<sup>5</sup> Recorded when the role exists at the write. The role ID is the difference between the `roles` change values in the [guild member change fields](#guild-member-change-fields)
|
|
|
|
<sup>6</sup> `count` is always `1`, and `channel_id` is the destination channel for a move and the vacated channel for a disconnect. A move into the channel the session already occupies records no entry
|
|
|
|
<sup>7</sup> The option is recorded only when the recorded entity has that value, so an invite with no channel or no inviter records neither, and a webhook with no channel records no option at all
|
|
|
|
<sup>8</sup> The filter accepts this value, and no current guild operation records this action
|
|
|
|
<sup>9</sup> A bulk deletion entry is recorded either by a bulk message deletion operation or by the consolidation described under [List guild audit logs](#list-guild-audit-logs)
|
|
|
|
<sup>10</sup> Recorded for an overwrite whose target is a role other than `@everyone`, when that role exists at the write
|
|
|
|
<sup>11</sup> [Follow announcement channel](/http-api/channels/#follow-announcement-channel) records `WEBHOOK_CREATE` in the following guild with `type` `2`, and deleting that webhook records `WEBHOOK_DELETE` the same way. Follower webhooks that Fluxer removes because the announcement channel was deleted or converted record no entry
|
|
|
|
Deleting a text, announcement, forum, or media channel deletes its threads and records only [CHANNEL_DELETE](#audit-actions). [Delete thread](/http-api/threads/#delete-thread) records `THREAD_DELETE`. Fluxer records [THREAD_UPDATE](#audit-actions) only when a [thread change field](#thread-change-fields) differs.
|
|
|
|
:::note[An update that changes nothing records no entry]
|
|
GUILD_UPDATE, CHANNEL_UPDATE, CHANNEL_OVERWRITE_UPDATE, MEMBER_UPDATE, MEMBER_ROLE_UPDATE, MEMBER_MOVE, ROLE_UPDATE, WEBHOOK_UPDATE, EMOJI_UPDATE, and STICKER_UPDATE need a change other than `ip`. GUILD_UPDATE also ignores `guild_id`, `member_count`, and the image width and height fields. A reason alone records nothing.
|
|
:::
|
|
|
|
## Audit log options object
|
|
|
|
Every field is present only for the actions listed against it in the [audit actions](#audit-actions) registry. Only the keys in this registry are published, and the response omits `options` entirely when an entry recorded none of them.
|
|
|
|
### Structure
|
|
|
|
| Field | Type | Description |
|
|
| --- | --- | --- |
|
|
| channel_id | string | The decimal ID of the channel the action concerns |
|
|
| count<sup>1</sup> | number | The number of entities the action affected |
|
|
| delete_member_days<sup>2</sup> | string | The whole days of the banned member's messages the ban deleted |
|
|
| delete_message_seconds<sup>3</sup> | number | The seconds of the banned member's messages the ban deleted |
|
|
| id | string | The decimal ID of the role or member an overwrite applies to |
|
|
| integration_type<sup>4</sup> | number | The type of the integration the entry names |
|
|
| message_id | string | The decimal ID of the single message the action concerns |
|
|
| members_removed<sup>4</sup> | number | The number of memberships the action removed |
|
|
| role_name<sup>5</sup> | string | The name of the role the action concerns, as it was when the entry was written |
|
|
| type<sup>6</sup> | number | The channel type, the permission overwrite type, or the webhook type |
|
|
| inviter_id | string | The decimal ID of the user that created the invite |
|
|
| max_age | number | The configured invite lifetime in seconds |
|
|
| max_uses | number | The configured maximum use count |
|
|
| temporary | boolean | Whether the recorded entity is temporary |
|
|
| uses<sup>4</sup> | number | The invite use count recorded with the action |
|
|
|
|
<sup>1</sup> The value is the length of the consolidated run for [MESSAGE_BULK_DELETE](#audit-actions) and is always `1` for the voice actions
|
|
|
|
<sup>2</sup> Deprecated, and present only on a ban entry recorded before `delete_message_seconds`. Its value is the legacy `delete_message_days` body field of [Create or replace guild ban](/http-api/guild-moderation/#create-or-replace-guild-ban), so a ban that sent only `delete_message_seconds` has `"0"`
|
|
|
|
<sup>3</sup> Present when the resolved deletion window of [Create or replace guild ban](/http-api/guild-moderation/#create-or-replace-guild-ban) is positive, whichever body field set it
|
|
|
|
<sup>4</sup> The field is defined by the wire contract and no current guild operation records it
|
|
|
|
<sup>5</sup> Recorded by [MEMBER_ROLE_UPDATE](#audit-actions), [ROLE_UPDATE](#audit-actions), and an overwrite action whose target is a role other than `@everyone`
|
|
|
|
<sup>6</sup> The value is a [channel type](/http-api/channels/#channel-types) for the channel and thread actions, a [permission overwrite type](/http-api/channels/#permission-overwrite-types) for the overwrite actions, and a [webhook type](/http-api/webhooks/#webhook-types) for the webhook actions
|
|
|
|
## Audit log change object
|
|
|
|
One field a mutation changed, with the value on each side of the change.
|
|
|
|
### Structure
|
|
|
|
| Field | Type | Description |
|
|
| --- | --- | --- |
|
|
| key<sup>1</sup> | string | The name of the field that changed, drawn from the [change fields](#change-fields) of the entity the action targets |
|
|
| old_value?<sup>2</sup> | audit log change value | The value the field held before the mutation |
|
|
| new_value?<sup>2</sup> | audit log change value | The value the field holds after the mutation |
|
|
|
|
<sup>1</sup> A change whose key is `ip` is never published through this resource, and `changes` is omitted entirely when no other change remains
|
|
|
|
<sup>2</sup> A creation has only `new_value`, a deletion has only `old_value`, and a modification has both, so a change object always has at least one of the two
|
|
|
|
A change value is a string, a JSON number, a boolean, `null`, an array of strings, an array of numbers, or an object with `added` and `removed` string arrays. The last shape comes only from the [permissions_diff](#guild-role-change-fields) key of a role modification. The `available_tags` and `default_reaction_emoji` [channel change fields](#channel-change-fields) record an array of objects and an object.
|
|
|
|
:::note[A 64-bit domain value is a decimal string]
|
|
Fluxer serialises a permission mask or a snowflake as a decimal string. A bounded number such as a position or a colour remains a JSON number.
|
|
:::
|
|
|
|
:::caution[A change list holds only the differing fields]
|
|
An update records one change object per differing field, so an unchanged field is absent. The field that holds the entity's own ID, such as `channel_id` or `role_id`, never appears in an update change list, though it does appear in a creation or deletion list, where only one side of the comparison exists.
|
|
:::
|
|
|
|
### Change fields
|
|
|
|
Each table below names the fields an action of that family can record.
|
|
|
|
#### Guild change fields
|
|
|
|
Recorded by [GUILD_UPDATE](#audit-actions).
|
|
|
|
| Field | Type | Description |
|
|
| --- | --- | --- |
|
|
| guild_id<sup>1</sup> | string | The decimal ID of the guild itself |
|
|
| name | string | The name the guild was given by this change (1-100 characters) |
|
|
| owner_id | string | The decimal ID of the guild owner |
|
|
| vanity_url_code | ?string | The configured custom invite code, or null when the guild has none |
|
|
| icon_hash | ?string | The guild icon hash, or null when the guild has no icon |
|
|
| banner_hash | ?string | The guild banner hash, or null when the guild has no banner |
|
|
| banner_width | ?number | The guild banner width in pixels, or null when the guild has no banner |
|
|
| banner_height | ?number | The guild banner height in pixels, or null when the guild has no banner |
|
|
| splash_hash | ?string | The guild splash hash, or null when the guild has no splash |
|
|
| splash_width | ?number | The guild splash width in pixels, or null when the guild has no splash |
|
|
| splash_height | ?number | The guild splash height in pixels, or null when the guild has no splash |
|
|
| splash_card_alignment | number | The [splash card alignment](/http-api/guilds/#splash-card-alignments) recorded with the change |
|
|
| embed_splash_hash | ?string | The guild embed splash hash, or null when the guild has no embed splash |
|
|
| embed_splash_width | ?number | The guild embed splash width in pixels, or null when the guild has no embed splash |
|
|
| embed_splash_height | ?number | The guild embed splash height in pixels, or null when the guild has no embed splash |
|
|
| features<sup>2</sup> | array[string] | The [guild features](/http-api/guilds/#guild-features) held at this side of the change, in ascending order |
|
|
| verification_level | number | The [verification level](/http-api/guilds/#verification-levels) recorded with the change |
|
|
| mfa_level | number | The [MFA level](/http-api/guilds/#mfa-levels) recorded with the change |
|
|
| nsfw_level | number | The [NSFW level](/http-api/guilds/#nsfw-levels) recorded with the change |
|
|
| nsfw | boolean | Whether the guild is marked age restricted |
|
|
| content_warning_level | number | The [guild content warning level](/http-api/guilds/#guild-content-warning-levels) recorded with the change |
|
|
| content_warning_text | ?string | The configured content warning text, or null when the guild sets none |
|
|
| explicit_content_filter | number | The [guild explicit content filter level](/http-api/guilds/#guild-explicit-content-filter-levels) recorded with the change |
|
|
| default_message_notifications | number | The [default message notification level](/http-api/guilds/#default-message-notification-levels) recorded with the change |
|
|
| system_channel_id | ?string | The decimal ID of the configured system channel, or null when the guild sets none |
|
|
| system_channel_flags | number | The [system channel flags](/http-api/guilds/#system-channel-flags) mask recorded with the change |
|
|
| rules_channel_id<sup>3</sup> | ?string | The decimal ID of the configured rules channel, or null when the guild sets none |
|
|
| afk_channel_id | ?string | The decimal ID of the configured AFK voice channel, or null when the guild sets none |
|
|
| afk_timeout | number | The AFK timeout in seconds |
|
|
| disabled_operations<sup>3</sup> | number | The [disabled guild operations](/http-api/guilds/#disabled-guild-operations) mask recorded with the change |
|
|
| member_count<sup>3</sup> | number | The member count recorded with the mutation |
|
|
| message_history_cutoff | ?ISO8601 timestamp | The configured message history cutoff, or null when the guild sets none |
|
|
|
|
<sup>1</sup> The field holds the same value on both sides of every guild action, so it never produces a change object
|
|
|
|
<sup>2</sup> A change object appears only when a feature was added or removed
|
|
|
|
<sup>3</sup> No current guild operation records the field
|
|
|
|
[Modify guild](/http-api/guilds/#modify-guild) records every field in this table except `guild_id`, `owner_id`, `vanity_url_code`, `rules_channel_id`, `disabled_operations`, and `member_count`. [Transfer guild ownership](/http-api/guild-members/#transfer-guild-ownership) records only `owner_id`, and [Modify guild custom invite URL](/http-api/guilds/#modify-guild-custom-invite-url) records only `vanity_url_code`.
|
|
|
|
#### Channel change fields
|
|
|
|
Recorded by [CHANNEL_CREATE](#audit-actions), [CHANNEL_UPDATE](#audit-actions), and [CHANNEL_DELETE](#audit-actions).
|
|
|
|
| Field | Type | Description |
|
|
| --- | --- | --- |
|
|
| channel_id | string | The decimal ID of the channel itself |
|
|
| type | number | The [channel type](/http-api/channels/#channel-types) recorded with the change |
|
|
| name | ?string | The name the channel was given by this change |
|
|
| topic | ?string | The topic the channel was given by this change, or null when it has none |
|
|
| url<sup>1</sup> | ?string | The destination URL of the channel, or null when it has none |
|
|
| parent_id | ?string | The decimal ID of the parent category, or null when the channel sits at the top level |
|
|
| position | number | The position of the channel among its siblings |
|
|
| nsfw | ?boolean | Whether the channel is marked age restricted, or null when it has no override |
|
|
| content_warning_level | number | The [content warning level](/http-api/channels/#content-warning-levels) recorded with the change |
|
|
| content_warning_text | ?string | The configured content warning text, or null when the channel sets none |
|
|
| rate_limit_per_user | number | The slowmode interval in seconds |
|
|
| user_limit | ?number | The configured voice occupancy limit |
|
|
| voice_connection_limit | ?number | The configured per-user voice connection limit |
|
|
| bitrate | ?number | The voice bitrate in bits per second |
|
|
| rtc_region | ?string | The pinned voice region, or null when the channel is routed automatically |
|
|
| rtc_p2p | boolean | Whether the channel is pinned to peer-to-peer voice |
|
|
| permission_overwrite_count<sup>2</sup> | number | The number of permission overwrites the channel has |
|
|
| flags<sup>3</sup> | number | The [channel flags](/http-api/forums/#channel-flags) of the channel |
|
|
| default_auto_archive_duration<sup>3</sup> | number | The stored default [auto archive duration](/http-api/threads/#auto-archive-durations) |
|
|
| default_thread_rate_limit_per_user<sup>3</sup> | number | The slowmode interval in seconds new threads inherit |
|
|
| available_tags<sup>3</sup> | array[[forum tag](/http-api/forums/#forum-tag-object) object] | The tags a post can apply |
|
|
| default_reaction_emoji<sup>3</sup> | [default reaction](/http-api/forums/#default-reaction-object) object | The reaction clients show on each post |
|
|
| default_sort_order<sup>3</sup> | number | The default [sort order](/http-api/forums/#forum-sort-orders) of posts |
|
|
| default_forum_layout<sup>3</sup> | number | The default [layout](/http-api/forums/#forum-layouts) of posts |
|
|
| default_tag_setting<sup>3</sup> | string | The default [tag matching](/http-api/forums/#forum-tag-settings) of a post search |
|
|
|
|
<sup>1</sup> Recorded only for a `GUILD_LINK` [channel type](/http-api/channels/#channel-types)
|
|
|
|
<sup>2</sup> No current channel operation records the field. An individual overwrite mutation records its own [permission overwrite](#permission-overwrite-change-fields) entry
|
|
|
|
<sup>3</sup> Recorded only by [CHANNEL_CREATE](#audit-actions) and [CHANNEL_UPDATE](#audit-actions), and only for a channel that stores thread or forum settings. No value is null
|
|
|
|
`default_auto_archive_duration` and `default_thread_rate_limit_per_user` apply to a guild text, announcement, forum, or media channel. `default_forum_layout` applies to a forum channel. `flags`, `available_tags`, `default_reaction_emoji`, `default_sort_order`, and `default_tag_setting` apply to a forum or media channel.
|
|
|
|
Changing `permission_overwrites` through [Modify channel](/http-api/channels/#modify-channel) records overwrite entries and adds no change to the [CHANNEL_UPDATE](#audit-actions) entry.
|
|
|
|
#### Thread change fields
|
|
|
|
Recorded by [THREAD_CREATE](#audit-actions), [THREAD_UPDATE](#audit-actions), and [THREAD_DELETE](#audit-actions).
|
|
|
|
| Field | Type | Description |
|
|
| --- | --- | --- |
|
|
| name | string | The name of the thread |
|
|
| type | number | The [thread type](/http-api/threads/#thread-types) |
|
|
| archived | boolean | Whether the thread is archived |
|
|
| locked | boolean | Whether the thread is locked |
|
|
| auto_archive_duration | number | The [auto archive duration](/http-api/threads/#auto-archive-durations) in minutes |
|
|
| rate_limit_per_user | number | The slowmode interval in seconds |
|
|
| flags | number | The [channel flags](/http-api/forums/#channel-flags) of the thread |
|
|
| invitable<sup>1</sup> | boolean | Whether a member who is not a thread moderator can add members who are not thread moderators |
|
|
| applied_tags<sup>2</sup> | array[string] | The decimal IDs of the applied [forum tags](/http-api/forums/#forum-tag-object) |
|
|
|
|
<sup>1</sup> Recorded only for a private thread
|
|
|
|
<sup>2</sup> Recorded only for a thread whose parent is a forum or media channel
|
|
|
|
#### Permission overwrite change fields
|
|
|
|
Recorded by the [channel overwrite actions](#audit-actions). Every value in this family is a string.
|
|
|
|
| Field | Type | Description |
|
|
| --- | --- | --- |
|
|
| id | string | The decimal ID of the role or member the overwrite applies to |
|
|
| type | string | The decimal [permission overwrite type](/http-api/channels/#permission-overwrite-types) |
|
|
| allow | string | The decimal [permission](/http-api/permissions/) mask the overwrite grants |
|
|
| deny | string | The decimal [permission](/http-api/permissions/) mask the overwrite denies |
|
|
|
|
#### Guild member change fields
|
|
|
|
Recorded by [MEMBER_UPDATE](#audit-actions) and [MEMBER_ROLE_UPDATE](#audit-actions).
|
|
|
|
| Field | Type | Description |
|
|
| --- | --- | --- |
|
|
| user_id | string | The decimal ID of the member itself |
|
|
| nick | ?string | The nickname the member holds in this guild, or null when none is set |
|
|
| roles | array[string] | The assigned role IDs as decimal strings, in ascending string order |
|
|
| avatar_hash | ?string | The guild avatar hash, or null when the member has no guild avatar |
|
|
| banner_hash | ?string | The guild banner hash, or null when the member has no guild banner |
|
|
| bio | ?string | The guild profile bio, or null when none is set |
|
|
| pronouns | ?string | The guild profile pronouns, or null when none is set |
|
|
| accent_color | ?number | The guild profile accent colour, or null when none is set |
|
|
| deaf | boolean | Whether a moderator has deafened the member |
|
|
| mute | boolean | Whether a moderator has muted the member |
|
|
| communication_disabled_until | ?ISO8601 timestamp | The time the communication restriction expires, or null when the member is not restricted |
|
|
| temporary | boolean | Whether the membership is temporary |
|
|
|
|
#### Voice move change fields
|
|
|
|
Recorded by [MEMBER_MOVE](#audit-actions) and [MEMBER_DISCONNECT](#audit-actions).
|
|
|
|
| Field | Type | Description |
|
|
| --- | --- | --- |
|
|
| channel_id<sup>1</sup> | string | The decimal ID of the voice channel the session occupied |
|
|
|
|
<sup>1</sup> A move records the previous channel as `old_value` and the destination as `new_value`, while a disconnect records only `old_value`
|
|
|
|
#### Guild ban change fields
|
|
|
|
Recorded by [MEMBER_BAN_ADD](#audit-actions) and [MEMBER_BAN_REMOVE](#audit-actions).
|
|
|
|
| Field | Type | Description |
|
|
| --- | --- | --- |
|
|
| user_id | string | The decimal ID of the banned user |
|
|
| moderator_id | string | The decimal ID of the user that issued the ban |
|
|
| banned_at | ISO8601 timestamp | The time the ban was issued |
|
|
| expires_at | ?ISO8601 timestamp | The expiry of a temporary ban, or null for a permanent ban |
|
|
| reason<sup>1</sup> | ?string | The stored [ban](/http-api/guild-moderation/#guild-ban-object) reason |
|
|
|
|
<sup>1</sup> The body `reason` when the request sent one, and the `X-Audit-Log-Reason` value otherwise. The entry `reason` is the header when one was sent, so the two differ when a request sends both with different values
|
|
|
|
#### Guild role change fields
|
|
|
|
Recorded by [ROLE_CREATE](#audit-actions), [ROLE_UPDATE](#audit-actions), and [ROLE_DELETE](#audit-actions).
|
|
|
|
| Field | Type | Description |
|
|
| --- | --- | --- |
|
|
| role_id | string | The decimal ID of the role itself |
|
|
| name | string | The name the role was given by this change (1-100 characters) |
|
|
| permissions | string | The decimal [permission](/http-api/permissions/) mask the role grants |
|
|
| position | number | The position of the role in the guild hierarchy |
|
|
| hoist_position | ?number | The separate hoisting position, or null when the role has none |
|
|
| color | number | The colour recorded for the role |
|
|
| icon_hash | ?string | The role icon hash, or null when the role has no icon |
|
|
| unicode_emoji | ?string | The role Unicode emoji, or null when the role has none |
|
|
| hoist | boolean | Whether the role is displayed separately |
|
|
| mentionable | boolean | Whether the role is mentionable |
|
|
| permissions_diff<sup>1</sup> | object | The permission names this change added and removed |
|
|
|
|
<sup>1</sup> Recorded only by [Modify guild role](/http-api/permissions/#modify-guild-role), and only when the mask changed. The value is an object with `added` and `removed` string arrays of permission names
|
|
|
|
`permissions_diff` arrives as `new_value` with no `old_value`, and the same change list still has the `permissions` change.
|
|
|
|
[Modify guild role positions](/http-api/permissions/#modify-guild-role-positions) records one [ROLE_UPDATE](#audit-actions) entry for each role that moved, with only the `position` change. Fluxer orders the roles other than `@everyone` by `position` descending, then by ID ascending, before and after the write. The largest set of roles that keep their relative order counts as unmoved, and where several sets qualify, the set whose roles come earliest in the new order is used. A request that only renumbers positions records no entry.
|
|
|
|
[Modify role hoist positions](/http-api/permissions/#modify-role-hoist-positions) and [Reset role hoist positions](/http-api/permissions/#reset-role-hoist-positions) apply the same rule to the member list order, with only the `hoist_position` change in each entry. That order is the hoisted roles other than `@everyone`, by `hoist_position` descending with `position` used when a role has no hoist position, then by ID ascending. A role that is not hoisted has an entry whenever its `hoist_position` changed.
|
|
|
|
#### Invite change fields
|
|
|
|
Recorded by [INVITE_CREATE](#audit-actions) and [INVITE_DELETE](#audit-actions).
|
|
|
|
| Field | Type | Description |
|
|
| --- | --- | --- |
|
|
| code | string | The code that identifies the invite |
|
|
| channel_id | ?string | The decimal ID of the channel the invite points at |
|
|
| guild_id | ?string | The decimal ID of the guild the invite belongs to |
|
|
| inviter_id | ?string | The decimal ID of the user that created the invite |
|
|
| uses | number | The use count recorded with the change |
|
|
| max_uses | number | The configured maximum use count |
|
|
| max_age | number | The configured invite lifetime in seconds |
|
|
| temporary | boolean | Whether accepting the invite grants a temporary membership |
|
|
| created_at | ISO8601 timestamp | The time the invite was created |
|
|
|
|
#### Webhook change fields
|
|
|
|
Recorded by [WEBHOOK_CREATE](#audit-actions), [WEBHOOK_UPDATE](#audit-actions), and [WEBHOOK_DELETE](#audit-actions).
|
|
|
|
| Field | Type | Description |
|
|
| --- | --- | --- |
|
|
| id | string | The decimal ID of the webhook itself |
|
|
| guild_id | ?string | The decimal ID of the guild the webhook belongs to |
|
|
| channel_id | ?string | The decimal ID of the channel the webhook posts to |
|
|
| name | string | The name the webhook posts under (1-80 characters) |
|
|
| creator_id | ?string | The decimal ID of the user that created the webhook |
|
|
| avatar_hash | ?string | The webhook avatar hash, or null when no avatar is set |
|
|
| type<sup>1</sup> | number | The kind of webhook the change recorded |
|
|
|
|
<sup>1</sup> The value is 1 for an incoming webhook and 2 for a channel follower webhook
|
|
|
|
#### Emoji change fields
|
|
|
|
Recorded by [EMOJI_CREATE](#audit-actions), [EMOJI_UPDATE](#audit-actions), and [EMOJI_DELETE](#audit-actions).
|
|
|
|
| Field | Type | Description |
|
|
| --- | --- | --- |
|
|
| emoji_id | string | The decimal ID of the emoji itself |
|
|
| name | string | The name the emoji was given by this change (2-32 characters) |
|
|
| animated | boolean | Whether the emoji is animated |
|
|
| creator_id | string | The decimal ID of the user that created the emoji |
|
|
|
|
#### Sticker change fields
|
|
|
|
Recorded by [STICKER_CREATE](#audit-actions), [STICKER_UPDATE](#audit-actions), and [STICKER_DELETE](#audit-actions).
|
|
|
|
| Field | Type | Description |
|
|
| --- | --- | --- |
|
|
| sticker_id | string | The decimal ID of the sticker itself |
|
|
| name | string | The name the sticker was given by this change (2-30 characters) |
|
|
| description | ?string | The sticker description, or null when it has none |
|
|
| animated | boolean | Whether the sticker is animated |
|
|
| creator_id | string | The decimal ID of the user that created the sticker |
|
|
|
|
## Audit log webhook object
|
|
|
|
A reduced [webhook object](/http-api/webhooks/#webhook-object). It omits the execution token, application ID, and creating user, and it names the avatar hash `avatar_hash` where the full object names it `avatar`.
|
|
|
|
### Structure
|
|
|
|
| Field | Type | Description |
|
|
| --- | --- | --- |
|
|
| id | snowflake | The ID of the webhook |
|
|
| type<sup>1</sup> | integer | The kind of webhook this record describes |
|
|
| guild_id | ?snowflake | The ID of the guild containing the webhook |
|
|
| channel_id | ?snowflake | The ID of the channel the webhook sends messages to |
|
|
| name | string | The name the webhook posts under |
|
|
| avatar_hash | ?string | The avatar hash of the webhook, or null when no avatar is set |
|
|
|
|
<sup>1</sup> The value is 1 for an incoming webhook and 2 for a channel follower webhook
|
|
|
|
## List guild audit logs
|
|
|
|
<RouteHeader method="GET" path="/v1/guilds/{guild_id}/audit-logs" bot />
|
|
|
|
Returns one page of guild audit history as a [guild audit log response](#guild-audit-log-response-object) object. Requires [VIEW_AUDIT_LOG](/http-api/permissions/) in the target guild, and no MFA elevation applies.
|
|
|
|
A guild ID that names no guild returns 404 `UNKNOWN_GUILD`. A non-member of an existing guild returns 403 `MISSING_PERMISSIONS`, so guild existence is visible to any authenticated caller.
|
|
|
|
### Path parameters
|
|
|
|
| Field | Type | Description |
|
|
| --- | --- | --- |
|
|
| guild_id | snowflake | The ID of the guild whose audit log is read |
|
|
|
|
### Query parameters
|
|
|
|
| Field | Type | Description |
|
|
| --- | --- | --- |
|
|
| limit?<sup>1</sup> | integer | The maximum number of entries to return (0-100, default 50) |
|
|
| before?<sup>2</sup> | snowflake | The cursor selecting entries older than this audit entry ID |
|
|
| after?<sup>2</sup> | snowflake | The cursor selecting entries newer than this audit entry ID |
|
|
| user_id?<sup>3</sup> | snowflake | The acting user ID the page is filtered by |
|
|
| action_type?<sup>3</sup> <sup>4</sup> | integer | The [audit action](#audit-actions) value the page is filtered by |
|
|
|
|
<sup>1</sup> A negative value and a value above 100 are both rejected, and the accepted value `0` is processed as `1`
|
|
|
|
<sup>2</sup> The cursors are mutually exclusive, and supplying both returns 400 `INVALID_FORM_BODY` with [`CANNOT_SPECIFY_BOTH_BEFORE_AND_AFTER`](/http-api/errors/#validation-error-code-registry) against `before`
|
|
|
|
<sup>3</sup> Supplying either filter disables message deletion consolidation for the request, so a page filtered by actor or action returns the unconsolidated entries
|
|
|
|
<sup>4</sup> A caller other than a bot or a user session that declares `channel_threads` receives 400 `INVALID_FORM_BODY` for 110, 111, or 112
|
|
|
|
The read is ordered from newest to oldest by entry ID. `before` selects entries below the cursor and `after` selects entries above it, both read in that same descending order. An `after` page therefore begins with the newest entry above the cursor.
|
|
|
|
Consolidated entries have new IDs but retain the position of the run they replace. Sort the page by ID if a strictly descending array is required.
|
|
|
|
A caller other than a bot or a user session that declares `channel_threads` receives no entry about a thread, a forum channel, or a media channel. Its remaining entries lose the thread and forum keys of the [channel change fields](#channel-change-fields) and every [thread permission bit](/http-api/threads/#thread-permissions). The `webhooks` array also omits each webhook of a forum or media channel.
|
|
|
|
A stored update entry that fails the [no-change rule](#audit-actions) is skipped and does not count towards `limit`. A page holds fewer entries than `limit` only when the guild has no further matching entries in that direction.
|
|
|
|
### Response
|
|
|
|
| Status | Body | Condition |
|
|
| --- | --- | --- |
|
|
| 200 | [guild audit log response](#guild-audit-log-response-object) object | Page was returned |
|
|
| 400 | [error response](/http-api/#error-response) | Both cursors were supplied, or a filter value is invalid |
|
|
| 403<sup>1</sup> | [error response](/http-api/#error-response) | Guild is unavailable, or `VIEW_AUDIT_LOG` is absent |
|
|
| 404 | [error response](/http-api/#error-response) | Guild does not exist and the request returns `UNKNOWN_GUILD` |
|
|
|
|
<sup>1</sup> The [error code](/http-api/errors/) is `MISSING_ACCESS` for a guild with [UNAVAILABLE_FOR_EVERYONE](/http-api/guilds/#guild-features), or [UNAVAILABLE_FOR_EVERYONE_BUT_STAFF](/http-api/guilds/#guild-features) without the instance staff flag, and `MISSING_PERMISSIONS` otherwise
|
|
|
|
:::caution[An unfiltered read consolidates message deletion entries]
|
|
Without `user_id` or `action_type`, runs of two or more consecutive [MESSAGE_DELETE](#audit-actions) entries sharing one actor and one channel become a single [MESSAGE_BULK_DELETE](#audit-actions) entry.
|
|
:::
|
|
|
|
### Side effects
|
|
|
|
A consolidated entry has a new ID, `options.count` equal to the number of replaced entries and no reason. It emits [Guild Audit Log Entry Create](/gateway/events/#guild-audit-log-entry-create) to guild sessions holding `VIEW_AUDIT_LOG`.
|
|
|
|
### Rate limit
|
|
|
|
20 requests per 10 seconds for each authenticated user and guild ID, on the `guild:audit_logs::guild_id` bucket.
|