Guild moderation
A guild ban keeps one account out of one guild, and it outlives the membership it removes. Removing a member is a separate operation with its own permission, and Remove guild member defines it.
Every route here requires BAN_MEMBERS, which is an elevated permission. In a guild whose MFA level is elevated, every caller except the guild owner also needs an enrolled multi-factor authenticator. A guild an operator has marked unavailable returns 403 MISSING_ACCESS before the route runs.
List guild bans is the only operation that reads a ban record, and there is no bulk ban operation.
Guild ban object
Section titled “Guild ban object”A guild ban object names the banned account, the moderator, the reason, and any expiry. Creating a ban for a user who is already banned replaces the existing record.
Structure
Section titled “Structure”| Field | Type | Description |
|---|---|---|
| user | partial user object | The banned account |
| reason1 | ?string | The stored ban reason, or null when none was recorded |
| moderator_id | snowflake | The account that issued or most recently replaced the ban |
| banned_at2 | ISO8601 timestamp | Time the ban was issued or most recently replaced |
| expires_at3 | ?ISO8601 timestamp | Time a temporary ban stops applying, or null for a permanent ban |
1 The body reason when that field is supplied, and the X-Audit-Log-Reason value when it is omitted or null
2 Replacing a ban rewrites this value, so it records the most recent issuance
3 An expired temporary ban is removed and never returned with a past expires_at
Example
Section titled “Example”{ "user": {"id": "1489002177550843906", "username": "spammer", "discriminator": "0042"}, "reason": "Advertising", "moderator_id": "1489002177550843905", "banned_at": "2026-08-14T09:12:44.000Z", "expires_at": null}Accepting an invite compares the joining account against the banned account identifier, the stored address, and the stored email. The address comparison uses a normalised decision key: the exact address for IPv4, the mapped IPv4 address for an IPv4-mapped IPv6 address, and the /64 network for every other IPv6 address. An address match refuses the join with 403 USER_IP_BANNED_FROM_GUILD.
Fluxer skips the address match when the joining address is on the instance exemption list, and also when the banned address is a single address and the joining address is reported as high mobile or carrier-grade NAT blast radius. The match runs when that report is unavailable or fails.
The email comparison is exact and runs only when an invite is accepted. An email match refuses the join with 403 USER_BANNED_FROM_GUILD. Every other path that adds a member compares the account identifier and the address alone, and several compare nothing. Grant OAuth2 consent installing a bot, the admin membership operations, the stock community auto-join, and the premium entitlement guild join all add the member without consulting the ban list.
Remove guild ban releases both blocks. Permanently deleting the banned account deletes every guild ban it holds, and that releases both blocks in every guild at once.
List guild bans
Section titled “List guild bans”GET/v1/guilds/{guild_id}/bansReturns every guild ban object of the guild. Requires BAN_MEMBERS.
A non-member cannot hold BAN_MEMBERS, so a caller outside the guild receives 403 MISSING_PERMISSIONS.
The operation returns the complete collection in one response and has no limit or cursor parameters. The response excludes an expired temporary ban, and omits a ban whose account can no longer be resolved, so the array can be shorter than the number of stored bans.
Path parameters
Section titled “Path parameters”| Field | Type | Description |
|---|---|---|
| guild_id | snowflake | The ID of the guild |
Response
Section titled “Response”| Status | Body | Condition |
|---|---|---|
| 200 | array[guild ban object] | Bans were returned |
| 4001 | error response | Caller holds BAN_MEMBERS without an enrolled authenticator in an elevated-MFA guild |
| 4032 | error response | Guild is unavailable, or BAN_MEMBERS is absent |
| 404 | error response | Guild does not exist and the request returns UNKNOWN_GUILD |
1 The error code is TWO_FACTOR_REQUIRED, returned only after the permission itself has been confirmed
2 The error code is MISSING_ACCESS for an unavailable guild and MISSING_PERMISSIONS otherwise
Rate limit
Section titled “Rate limit”40 requests per 10 seconds for each authenticated user and guild ID, on the shared guild:members::guild_id bucket.
Create or replace guild ban
Section titled “Create or replace guild ban”PUT/v1/guilds/{guild_id}/bans/{user_id}Creates a guild ban, or replaces an existing one, and returns 204 with an empty body. Requires BAN_MEMBERS. Emits a Guild Ban Add Gateway event.
Limitations
Section titled “Limitations”- The caller cannot ban themselves, and Fluxer reports a self-target as 404
UNKNOWN_MEMBER. - Banning a target who is currently a member also requires role hierarchy authority over that member. The guild owner holds that authority over everyone, and no other caller holds it over the owner.
- A target who is not a member can still be banned, and the ban pre-empts a future join.
Fluxer scans every string in a JSON request body against the instance phrase and URL blocklists, and that includes reason. A blocked value returns 403 CONTENT_BLOCKED before the rate limit bucket, the credential check, and the permission check.
Path parameters
Section titled “Path parameters”| Field | Type | Description |
|---|---|---|
| guild_id | snowflake | The ID of the guild |
| user_id | snowflake | The ID of the account to ban |
JSON body
Section titled “JSON body”The body is optional, and so is every field in it. Fluxer reads an omitted or whitespace-only body as an empty object, so a bare request creates a permanent ban that deletes no messages and records no body reason. A body that is not valid JSON returns 400 INVALID_FORM_BODY with the validation code INVALID_FORMAT at the body path.
| Field | Type | Description |
|---|---|---|
| delete_message_seconds?1 | integer | Age of the target’s recent guild messages to delete, in seconds (0-604800) |
| delete_message_days?2 | integer | Legacy age of those messages, in whole days (0-7, default 0) |
| reason?3 | ?string | Reason stored on the ban record (max 512 characters) |
| ban_duration_seconds?4 | integer | Ban duration in seconds, either 0 or 60 through 63072000 |
1 Zero and an omitted field delete nothing. The field takes precedence over delete_message_days whenever it is present, including when it is 0
2 Multiplied by 86400 to produce the effective interval, and only when delete_message_seconds is absent
3 Stripped of removed control and format code points and trimmed before its length is measured. A longer result fails with STRING_LENGTH_INVALID at the reason path
4 Zero and an omitted field both create a permanent ban. Any value outside 60 through 63072000, which is two years, fails with INVALID_FORMAT
delete_message_days defaults to 0, so a MEMBER_BAN_ADD entry always records options.delete_member_days. That option is 0 for a ban that supplied only delete_message_seconds.
An omitted or null reason falls back to the X-Audit-Log-Reason value, while a supplied value that normalises to the empty string is stored as null without falling back. The header remains the audit entry reason in every case.
Response
Section titled “Response”| Status | Body | Condition |
|---|---|---|
| 204 | empty | Ban was created or replaced |
| 4001 | error response | Duration, deletion interval, or reason is invalid, or the caller holds BAN_MEMBERS without an enrolled authenticator in an elevated-MFA guild |
| 4032 | error response | Guild is unavailable, blocked content was supplied, BAN_MEMBERS is absent, or hierarchy authority over a member target is absent |
| 404 | error response | Guild does not exist and the request returns UNKNOWN_GUILD |
| 4043 | error response | Target account does not exist, or the target is the caller |
1 The missing-authenticator error code is TWO_FACTOR_REQUIRED, returned only after the permission itself has been confirmed
2 The error code is MISSING_ACCESS for an unavailable guild, CONTENT_BLOCKED for a blocked string, and MISSING_PERMISSIONS otherwise
3 The error code is UNKNOWN_USER for an account that does not exist and UNKNOWN_MEMBER for a caller that names itself, and the self-target check runs first
Side effects
Section titled “Side effects”The operation stores the ban together with the target’s last known IP address and account email. It records a MEMBER_BAN_ADD audit entry whose change list has the stored guild ban change fields, emits Guild Audit Log Entry Create, and emits Guild Ban Add to the guild’s sessions, subject to event filtering. A positive deletion interval schedules permanent deletion of the target’s newer guild messages.
A target that is a current member also loses that membership. The guild member count decreases, the guild’s sessions receive Guild Member Remove, the banned account’s sessions receive Guild Delete, and the membership is dropped from the member search index of an indexed guild. Fluxer records no MEMBER_KICK entry alongside the ban entry.
A ban does not preserve an active communication timeout for a later rejoin, and Remove guild member does. The banned account loses its guild nickname, guild avatar hash, guild banner hash, biography, pronouns, accent colour, and role set. Its read states and guild settings stay in place.
From that point Fluxer refuses a join attempt by the banned account. The address and email matches described under the guild ban object apply as well. A ban therefore restricts more than one account when an address or an email is shared.
Rate limit
Section titled “Rate limit”20 requests per 10 seconds for each authenticated user and guild ID, on the guild:member:remove::guild_id bucket.
Remove guild ban
Section titled “Remove guild ban”DELETE/v1/guilds/{guild_id}/bans/{user_id}Removes an existing guild ban and returns 204 with an empty body. Requires BAN_MEMBERS. Emits a Guild Ban Remove Gateway event.
Fluxer rejects a target that is not currently banned with 400 INVALID_FORM_BODY.
Path parameters
Section titled “Path parameters”| Field | Type | Description |
|---|---|---|
| guild_id | snowflake | The ID of the guild |
| user_id | snowflake | The ID of the banned account |
Response
Section titled “Response”| Status | Body | Condition |
|---|---|---|
| 204 | empty | Ban was removed |
| 4001 | error response | Target is not banned, or the caller holds BAN_MEMBERS without an enrolled authenticator in an elevated-MFA guild |
| 4032 | error response | Guild is unavailable, or BAN_MEMBERS is absent |
| 404 | error response | Guild does not exist and the request returns UNKNOWN_GUILD |
1 A target that is not banned returns INVALID_FORM_BODY with USER_IS_NOT_BANNED against user_id. The missing-authenticator code is TWO_FACTOR_REQUIRED, returned only after the permission is confirmed
2 The error code is MISSING_ACCESS for an unavailable guild and MISSING_PERMISSIONS otherwise
Side effects
Section titled “Side effects”The operation deletes the ban together with the address and email blocks it had. It records a MEMBER_BAN_REMOVE audit entry whose change list has the removed guild ban change fields, emits Guild Audit Log Entry Create, and emits Guild Ban Remove to the guild’s sessions, subject to event filtering.
It does not restore the removed membership, the guild profile fields and roles that membership had, or the deleted messages. The unbanned account can rejoin through an ordinary invite.
An instance-wide IP ban is a separate mechanism this operation does not touch. Every request from an address it covers is still refused with 403 GLOBAL_IP_BANNED for a permanent ban and 403 GLOBAL_IP_TEMPORARILY_BANNED for a 24 hour one.
Rate limit
Section titled “Rate limit”20 requests per 10 seconds for each authenticated user and guild ID, on the guild:member:remove::guild_id bucket.