Skip to main content
The audit log records administrative actions performed in guilds. Each action generates an audit log entry that tracks who did what, when, and to whom.

Audit Log Structure

Audit log entries include:
id
snowflake
Unique ID of the audit log entry
action_type
integer
Type of action performed (see Action Types)
user_id
snowflake
ID of the user who performed the action
target_id
snowflake
ID of the affected entity (user, channel, role, etc.)
changes
array
Array of changes made (before/after values)
options
object
Additional metadata about the action
reason
string
Reason provided for the action (optional)

Action Types

All audit log action types:

Guild Actions

GUILD_UPDATE = 1  // Guild settings updated
Tracked Changes:
  • Name
  • Icon
  • Description
  • Features
  • Owner transfer
  • Region
  • Verification level

Channel Actions

CHANNEL_CREATE = 10           // Channel created
CHANNEL_UPDATE = 11           // Channel updated
CHANNEL_DELETE = 12           // Channel deleted
CHANNEL_OVERWRITE_CREATE = 13 // Permission overwrite created
CHANNEL_OVERWRITE_UPDATE = 14 // Permission overwrite updated
CHANNEL_OVERWRITE_DELETE = 15 // Permission overwrite deleted
Tracked Changes:
  • Channel name
  • Channel type
  • Topic
  • NSFW setting
  • Slowmode
  • Position
  • Permission overwrites
  • Parent category

Member Actions

MEMBER_KICK = 20         // Member kicked
MEMBER_PRUNE = 21        // Members pruned
MEMBER_BAN_ADD = 22      // Member banned
MEMBER_BAN_REMOVE = 23   // Ban removed
MEMBER_UPDATE = 24       // Member updated
MEMBER_ROLE_UPDATE = 25  // Member roles updated
MEMBER_MOVE = 26         // Member moved to voice channel
MEMBER_DISCONNECT = 27   // Member disconnected from voice
BOT_ADD = 28             // Bot added to guild
Tracked Changes:
  • Nickname
  • Roles added/removed
  • Mute status
  • Deaf status
  • Communication timeout
  • Voice channel

Role Actions

ROLE_CREATE = 30  // Role created
ROLE_UPDATE = 31  // Role updated
ROLE_DELETE = 32  // Role deleted
Tracked Changes:
  • Role name
  • Color
  • Permissions
  • Position
  • Mentionable
  • Hoisted

Invite Actions

INVITE_CREATE = 40  // Invite created
INVITE_UPDATE = 41  // Invite updated
INVITE_DELETE = 42  // Invite deleted
Tracked Changes:
  • Code
  • Max uses
  • Max age
  • Temporary membership
  • Creator

Webhook Actions

WEBHOOK_CREATE = 50  // Webhook created
WEBHOOK_UPDATE = 51  // Webhook updated
WEBHOOK_DELETE = 52  // Webhook deleted
Tracked Changes:
  • Name
  • Avatar
  • Channel

Emoji Actions

EMOJI_CREATE = 60  // Emoji created
EMOJI_UPDATE = 61  // Emoji updated
EMOJI_DELETE = 62  // Emoji deleted
Tracked Changes:
  • Name
  • Roles allowed to use

Sticker Actions

STICKER_CREATE = 90  // Sticker created
STICKER_UPDATE = 91  // Sticker updated
STICKER_DELETE = 92  // Sticker deleted
Tracked Changes:
  • Name
  • Description
  • Tags

Message Actions

MESSAGE_DELETE = 72       // Message deleted
MESSAGE_BULK_DELETE = 73  // Messages bulk deleted
MESSAGE_PIN = 74          // Message pinned
MESSAGE_UNPIN = 75        // Message unpinned
Tracked Changes:
  • Message content (for deletions)
  • Pin status

Fetching Audit Logs

Get Audit Log

GET /guilds/{guild_id}/audit-logs
Query Parameters:
user_id
snowflake
Filter by user who performed actions
action_type
integer
Filter by action type
before
snowflake
Get entries before this ID
limit
integer
Max entries to return (1-100, default 50)
Example:
const response = await fetch(
  `/api/guilds/${guildId}/audit-logs?action_type=22&limit=25`,
  {
    headers: { 'Authorization': `Bearer ${token}` }
  }
);

const auditLog = await response.json();
Response:
{
  "audit_log_entries": [
    {
      "id": "123456789",
      "action_type": 22,
      "user_id": "987654321",
      "target_id": "111222333",
      "reason": "Spamming",
      "changes": [],
      "options": {
        "delete_member_days": "7",
        "members_removed": "1"
      },
      "created_at": "2024-01-15T10:30:00.000Z"
    }
  ],
  "users": [
    {
      "id": "987654321",
      "username": "moderator",
      "avatar": "a_1234567890"
    }
  ]
}

Change Object

Changes track before/after values:
{
  "key": "name",
  "old_value": "Old Channel Name",
  "new_value": "New Channel Name"
}
key
string
Property that was changed
old_value
any
Value before the change
new_value
any
Value after the change

Options Object

Additional metadata for specific actions:

Member Prune

{
  "delete_member_days": "7",
  "members_removed": "15"
}

Message Delete

{
  "channel_id": "123456789",
  "count": "5"
}

Member Move/Disconnect

{
  "channel_id": "123456789",
  "count": "3"
}

Role/Permission Update

{
  "role_name": "Admin",
  "type": "0"
}

Required Permissions

Viewing audit logs requires the VIEW_AUDIT_LOG permission.
import { Permissions } from '@fluxer/constants';

// Check permission before accessing
await requirePermission(gatewayService, {
  guildId,
  userId,
  permission: Permissions.VIEW_AUDIT_LOG
});

Filtering Examples

Get All Bans

const response = await fetch(
  `/api/guilds/${guildId}/audit-logs?action_type=22`,
  { headers: { 'Authorization': `Bearer ${token}` } }
);

Get Actions by Specific User

const response = await fetch(
  `/api/guilds/${guildId}/audit-logs?user_id=${moderatorId}`,
  { headers: { 'Authorization': `Bearer ${token}` } }
);

Get Recent Channel Changes

const channelActions = [10, 11, 12]; // CREATE, UPDATE, DELETE

for (const action of channelActions) {
  const response = await fetch(
    `/api/guilds/${guildId}/audit-logs?action_type=${action}&limit=10`,
    { headers: { 'Authorization': `Bearer ${token}` } }
  );
}

Pagination

Audit logs support snowflake-based pagination:
let lastId: string | null = null;
const allEntries = [];

while (true) {
  const url = lastId
    ? `/api/guilds/${guildId}/audit-logs?before=${lastId}&limit=100`
    : `/api/guilds/${guildId}/audit-logs?limit=100`;
  
  const response = await fetch(url, {
    headers: { 'Authorization': `Bearer ${token}` }
  });
  
  const data = await response.json();
  
  if (data.audit_log_entries.length === 0) break;
  
  allEntries.push(...data.audit_log_entries);
  lastId = data.audit_log_entries[data.audit_log_entries.length - 1].id;
}

Providing Reasons

Include an audit log reason when performing actions:
DELETE /guilds/{guild_id}/members/{user_id}
X-Audit-Log-Reason: Spamming in #general
await fetch(`/api/guilds/${guildId}/members/${userId}`, {
  method: 'DELETE',
  headers: {
    'Authorization': `Bearer ${token}`,
    'X-Audit-Log-Reason': 'Spamming in #general'
  }
});
Reasons are limited to 512 characters and will appear in the audit log.

Retention

Audit log entries are retained for 90 days after creation.

Search Limitations

The audit log API does not support full-text search. Filter by user_id or action_type for best results.

Best Practices

Always Provide Reasons

Include clear, descriptive reasons for moderation actions to maintain transparency.

Regular Reviews

Regularly review audit logs to monitor for unauthorized actions or suspicious behavior.

Automate Monitoring

Set up automated alerts for critical actions (bans, role changes, permission updates).

Export Important Logs

Export and archive critical audit log entries before they expire (90 days).

Action Type Reference

export enum AuditLogActionType {
  GUILD_UPDATE = 1,
  
  CHANNEL_CREATE = 10,
  CHANNEL_UPDATE = 11,
  CHANNEL_DELETE = 12,
  CHANNEL_OVERWRITE_CREATE = 13,
  CHANNEL_OVERWRITE_UPDATE = 14,
  CHANNEL_OVERWRITE_DELETE = 15,
  
  MEMBER_KICK = 20,
  MEMBER_PRUNE = 21,
  MEMBER_BAN_ADD = 22,
  MEMBER_BAN_REMOVE = 23,
  MEMBER_UPDATE = 24,
  MEMBER_ROLE_UPDATE = 25,
  MEMBER_MOVE = 26,
  MEMBER_DISCONNECT = 27,
  BOT_ADD = 28,
  
  ROLE_CREATE = 30,
  ROLE_UPDATE = 31,
  ROLE_DELETE = 32,
  
  INVITE_CREATE = 40,
  INVITE_UPDATE = 41,
  INVITE_DELETE = 42,
  
  WEBHOOK_CREATE = 50,
  WEBHOOK_UPDATE = 51,
  WEBHOOK_DELETE = 52,
  
  EMOJI_CREATE = 60,
  EMOJI_UPDATE = 61,
  EMOJI_DELETE = 62,
  
  STICKER_CREATE = 90,
  STICKER_UPDATE = 91,
  STICKER_DELETE = 92,
  
  MESSAGE_DELETE = 72,
  MESSAGE_BULK_DELETE = 73,
  MESSAGE_PIN = 74,
  MESSAGE_UNPIN = 75
}

Build docs developers (and LLMs) love