Skip to content
Fluxer API

Admin users

These routes read and change any account on the instance. Each field group has its own route and ACL, and every route except Get current Admin user records an Admin audit entry, reads included.

On an instance where members sign in with a username, the email routes return 400 EMAIL_UNAVAILABLE_ON_INSTANCE and you reset a password with Create password reset link, which also works on an email instance that doesn't send email. On routes that record an enforcement decision, the X-Audit-Log-Reason header is required and becomes the decision's first note. Blocking a user's avatar is on Blocklists.

The full admin view of one account, with the flags, lifecycle, contact and network fields the public user object leaves out. Without user:view:email, user:view:dob or user:view:ip, the fields that ACL protects are null (or false for the email booleans) and the request still succeeds.

FieldTypeDescription
idsnowflakeThe ID of the account
usernamestringThe username (1-32 characters)
discriminator1integerThe discriminator from 0 to 9999, unpadded
global_name?stringThe display name
botbooleanWhether the account is a bot
systembooleanWhether the account is an official system account
flagsstringAccount flags as a decimal string
premium_flagsintegerPremium flags
avatar?stringThe avatar hash
banner?stringThe profile banner hash
bio?stringThe profile bio
pronouns?stringThe profile pronouns
accent_color?integerThe profile accent color
email2?stringThe email address
email_verified2booleanWhether the email address is verified
email_bounced2booleanWhether mail to the address hard bounced
date_of_birth3?stringThe date of birth as YYYY-MM-DD
locale?stringThe saved locale
premium_type?integerPremium type
premium_since?ISO8601 timestampWhen premium started
premium_until?ISO8601 timestampWhen premium ends
premium_grace_ends_at?ISO8601 timestampWhen the payment grace period ends
premium_lifetime_sequence?integerThe sequence number of the lifetime purchase
profile_badgesarray[Admin profile badge object]Every badge the account qualifies for, including hidden ones
temp_banned_until?ISO8601 timestampWhen the current suspension ends, or null when none is in force
pending_deletion_at?ISO8601 timestampWhen the scheduled deletion runs
pending_bulk_message_deletion_at?ISO8601 timestampWhen the account holder's own scheduled message deletion runs
deletion_reason_code?integerDeletion reason
deletion_public_reason?stringThe reason shown to the account holder, set only on older deletions
deletion_audit_log_reason?stringThe private deletion reason, null without audit_log:view
deletion_scheduled_by?snowflakeThe ID of the account that scheduled the deletion
deletion_scheduled_at?ISO8601 timestampWhen the deletion was scheduled
enforcement_decision_id?snowflakeThe enforcement decision that owns the account's state
aclsarray[string]The Admin ACLs set on the account
traitsarray[string]The operator labels on the account, sorted (at most 100)
badge_idsarray[snowflake]The custom badges given to the account (at most 1000)
has_totpbooleanWhether a TOTP authenticator is registered
has_passwordbooleanWhether the account has a password
claimedbooleanWhether the account can sign in from another device
account_tierstringThe account tier
date_of_birth_requiredbooleanWhether the account still has to set its date of birth
authenticator_typesarray[integer]Second-factor authenticator types (at most 10)
last_active_at?ISO8601 timestampWhen the account was last active
last_active_ip4?stringThe IP address the account was last active from
last_active_ip_reverse4?stringThe reverse DNS name of that address
last_active_location4?stringThe approximate location of that address

1 Other Admin objects use a zero-padded string. On an instance with the none tag style, every account that is not a bot has 0

2 Needs user:view:email

3 Needs user:view:dob

4 Needs user:view:ip

{
"id": "1493004551122763776",
"username": "subject",
"discriminator": 7,
"global_name": null,
"bot": false,
"system": false,
"flags": "8796093022208",
"premium_flags": 0,
"avatar": "a1b2c3d4e5f60718293a4b5c6d7e8f90",
"email": "subject@example.com",
"email_verified": true,
"email_bounced": false,
"date_of_birth": "1998-03-21",
"temp_banned_until": null,
"pending_deletion_at": null,
"deletion_reason_code": null,
"acls": [],
"traits": ["early-signup"],
"badge_ids": [],
"has_totp": true,
"has_password": true,
"claimed": true,
"account_tier": "verified",
"date_of_birth_required": false,
"authenticator_types": [1, 2],
"last_active_at": "2026-08-30T21:04:02.771000+00:00",
"last_active_ip": "203.0.113.24",
"last_active_ip_reverse": "host24.example.com",
"last_active_location": "Stockholm, Sweden"
}

A profile badge with a suppressed field.

FieldTypeDescription
keystringThe badge's identity, custom:{id} for a custom badge
kindstringThe badge type
labelstringThe badge description in the caller's locale
asset?stringThe badge image hash, or null for a text badge or a custom badge
asset_url?stringThe image URL of a custom badge
aspect_ratio?numberThe image width divided by its height
caption?stringThe short badge text, such as #42
href?stringThe URL a click opens
small_asset?stringThe image hash for 20 pixels and smaller
count??integerNot used on a self-hosted instance
accessible_label??stringThe label for screen readers
details??badge details objectThe tooltip content
suppressedbooleanWhether the public profile hides the badge

The flags field is a 64-bit bitfield sent as a decimal string. It has every stored flag, including the ones the public flags leave out.

ValueNameDescription
1 << 0STAFFAccount is a staff member
1 << 2PARTNERAccount is a partner
1 << 3BUG_HUNTERAccount is a bug hunter
1 << 4FRIENDLY_BOTBot accepts friend requests
1 << 5FRIENDLY_BOT_MANUAL_APPROVALBot approves friend requests by hand
1 << 6SPAMMERAccount is flagged as a spammer
1 << 7PROFILE_HIDDENProfile details are hidden from other users
1 << 33HIGH_GLOBAL_RATE_LIMITAccount has a higher global rate limit
1 << 34DELETEDAccount is deleted
1 << 36SELF_DELETEDAccount holder deleted the account
1 << 38DISABLEDAccount is disabled
1 << 39HAS_SESSION_STARTEDAccount has started a session
1 << 47RATE_LIMIT_BYPASSAccount skips rate limits
1 << 48REPORT_BANNEDAccount cannot send reports
1 << 49VERIFIED_NOT_UNDERAGEAccount is verified as not underage
1 << 50ACCOUNT_LIMITEDAccount is limited
1 << 51HAS_DISMISSED_PREMIUM_ONBOARDINGAccount dismissed premium onboarding
1 << 53APP_STORE_REVIEWERAccount belongs to an app store reviewer
1 << 60AGE_VERIFIED_ADULTAccount verified its age as an adult
1 << 62LIMIT_EXEMPTAccount is never limited
ValueNameDescription
1 << 0DISCRIMINATORAccount has a premium discriminator
1 << 2BADGE_MASKEDPremium badge is masked
1 << 3BADGE_TIMESTAMP_HIDDENPremium badge timestamp is hidden
1 << 5PERKS_SANITIZEDPremium perks are sanitized
1 << 6PURCHASE_DISABLEDPremium purchase is blocked
1 << 7ENABLED_OVERRIDEPremium is turned on by override
1 << 8PERKS_DISABLEDPremium perks are paused
ValueNameDescription
0NONENo premium
1SUBSCRIPTIONPremium subscription
2LIFETIMELifetime premium

Values 1, 2, 19, 32 and 33 are not enforcement reasons. Only the others are accepted in an enforcement decision input.

ValueNameDescription
1USER_REQUESTEDAccount holder asked for deletion
2OTHEROther reason
3SPAMSpam
4CHEATING_OR_EXPLOITATIONCheating or exploitation
5COORDINATED_RAIDINGCoordinated raiding
6AUTOMATION_OR_SELFBOTDisruptive automation
7NONCONSENSUAL_SEXUAL_CONTENTNon-consensual sexual content
8SCAM_OR_SOCIAL_ENGINEERINGScam or social engineering
9CHILD_SEXUAL_CONTENTChild sexual content
10PRIVACY_VIOLATION_OR_DOXXINGPrivacy violation or doxxing
11HARASSMENT_OR_BULLYINGHarassment or bullying
12PAYMENT_FRAUDPayment fraud
13CHILD_SAFETY_VIOLATIONChild safety violation
14BILLING_DISPUTE_OR_ABUSEBilling dispute or abuse
15UNSOLICITED_EXPLICIT_CONTENTUnsolicited explicit content
16GRAPHIC_VIOLENCEGraphic violence
17BAN_EVASIONBan evasion
18TOKEN_OR_CREDENTIAL_SCAMToken or credential scam
19INACTIVITYInactivity
20HATE_SPEECH_OR_EXTREMIST_CONTENTHate speech or extremist content
21MALICIOUS_LINKS_OR_MALWAREMalicious links or malware
22IMPERSONATION_OR_FAKE_IDENTITYImpersonation or fake identity
23THREATS_OR_VIOLENT_SPEECHThreats or violent speech
24VIOLENT_EXTREMISMTerrorism or violent extremism
25SELF_HARM_PROMOTIONPromoting self-harm
26SEXUAL_CONTENT_PLACEMENTSexual content outside 18+ spaces
27ILLEGAL_GOODS_OR_ACTIVITYIllegal goods or activity
28HARMFUL_DECEPTIONHarmful deception
29REPORTING_ABUSEMisuse of reporting
30UNDERAGE_ACCOUNTAccount holder under the minimum age
31COPYRIGHTCopyright
32BELOW_MINIMUM_AGEAccount holder gave a date of birth below the minimum age
33UNCLAIMED_ACCOUNT_ABANDONEDAccount with no way to sign back in was left unused

The values Clear user profile fields accepts.

ValueDescription
avatarAvatar image
bannerBanner image
bioBio
pronounsPronouns
global_nameDisplay name

The values Clear user relationships and Remove user relationship accept.

ValueDescription
friendA friendship
incoming_requestA friend request the account received
outgoing_requestA friend request the account sent
blockedAn account this account blocked

A link the account holder opens to choose a password. Anyone with the link can set the password until it expires.

FieldTypeDescription
urlstringThe web app link, ending in /reset#token= and the token
expires_atISO8601 timestampWhen the link stops working, one hour after it is made

A one-time sign-in link for an admin account. Anyone with the link can sign in as that admin until it is used or expires.

FieldTypeDescription
urlstringThe web app link, ending in /login#sign_in_link= and the token
expires_atISO8601 timestampWhen the link stops working, 15 minutes after it is made

One sign-in session of an account. Ended sessions stay in the list with deleted_at set.

FieldTypeDescription
session_id_hashstringThe base64url hash of the session ID (8-256 characters)
created_atISO8601 timestampWhen the session started
approx_last_used_atISO8601 timestampAbout when the session was last used
client_ip1stringThe IP address the session started from
client_ip_reverse1?stringThe reverse DNS name of that address
client_os?stringThe operating system from the user agent
client_platform?stringThe platform from the user agent
client_location1?stringThe approximate location of that address
app_platform2?stringThe app platform, one of android, ios, linux or desktop
app_version2?stringThe app version
app_release_channel2?stringThe release channel, one of stable, beta or canary
app_build_number2?integerThe platform build number
app_beta_number2?integerThe beta number, only on beta builds
deleted_at?ISO8601 timestampWhen the session ended, or null while it is active

1 Needs user:view:ip. Without it client_ip is [redacted] and the other two are null

2 From the X-Fluxer-Client-Properties header of the last request the session made, and null when that header is missing or on ended sessions

One active session with the app version and build that its last X-Fluxer-Client-Properties header sent.

FieldTypeDescription
user_idsnowflakeThe account the session belongs to
session_id_hashstringThe base64url hash of the session ID (8-256 characters)
created_atISO8601 timestampWhen the session started
approx_last_used_atISO8601 timestampAbout when the session was last used
app_version?stringThe app version
app_build_number?integerThe platform build number
app_beta_number?integerThe beta number, only on beta builds

The account summary in Admin direct message channel and relationship objects.

FieldTypeDescription
idsnowflakeThe ID of the account
usernamestringThe username
discriminatorstringThe discriminator, zero-padded to four digits
global_name?stringThe display name
avatar?stringThe avatar hash

A direct message or group direct message channel the account is in.

FieldTypeDescription
channel_idsnowflakeThe ID of the channel
channel_type?integerChannel type
channel_nsfw?booleanWhether the channel is age-restricted
guild_nsfw_level?integerAlways null
recipient_idsarray[snowflake]The IDs of the recipients (at most 100)
recipientsarray[Admin resolved user object]The recipients whose accounts still exist (at most 100)
last_message_id?snowflakeThe ID of the latest message
is_openbooleanWhether the channel is open in the account's client
name?stringThe group name
icon?stringThe group icon hash
owner_id?snowflakeThe ID of the group owner

One relationship between the account and another account.

FieldTypeDescription
target_user_idsnowflakeThe ID of the other account
categorystringRelationship category
nickname?stringThe nickname the account gave the other account
since?ISO8601 timestampWhen the relationship started
target?Admin resolved user objectThe other account, or null when it no longer exists

One change to the account's email address or tag, by the account holder or an Admin.

FieldTypeDescription
event_idstringThe ID of the entry, which you send as page_token
fieldstringemail or fluxer_tag
old_value1?stringThe value before the change
new_value1?stringThe value after the change
reason?stringThe reason, admin_action for an Admin change
actor_user_id?snowflakeThe ID of the Admin, or null for the account holder's own change
event_atISO8601 timestampWhen the change happened

1 An email entry shows [redacted] without user:view:email

One message to shred.

FieldTypeDescription
channel_idsnowflakeThe ID of the channel
message_idsnowflakeThe ID of the message
GET/v1/admin/usersAudit reason

Finds accounts by one selector and returns Admin user objects. You need user:lookup. When you send more than one selector, the first one in this order wins: user_id, resolve, email, last_active_ip, acl, then q.

FieldTypeDescription
user_id?array[snowflake]Exact account IDs, repeated for more than one (at most 100)
resolve?1stringA tag, account ID or email address to match one account (1-1024 characters)
email?2stringAn exact email address (1-320 characters)
last_active_ip?3stringAn exact last active IP address (1-64 characters)
acl?stringAn ACL, to list the accounts that have it
q?stringA search query (1-1024 characters)
limit?4integerHow many accounts to return (1-200, default 50)
offset?4integerHow many results to skip (0-100000, default 0)

1 A value with @ needs user:view:email

2 Needs user:view:email

3 Needs user:view:ip

4 Only for last_active_ip, acl and q

FieldTypeDescription
usersarray[Admin user object]The matching accounts
totalintegerHow many accounts matched
StatusBodyCondition
200response bodyThe search finished, even with no matches
403error responseFEATURE_TEMPORARILY_DISABLED when q runs on an instance with no search backend

The rate limit is 200 requests per minute, on the admin:lookup bucket.

GET/v1/admin/users/@me

Returns the account you are signed in as, unredacted. You need admin:authenticate.

FieldTypeDescription
userAdmin user objectYour account
pending_registration_count?integerThe number of pending registrations, or null without registration:review
StatusBodyCondition
200response bodyYour account was returned

The rate limit is 200 requests per minute, on the admin:lookup bucket.

GET/v1/admin/users/{user_id}Audit reason

Returns one account. You need user:lookup.

FieldTypeDescription
usersarray[Admin user object]The account, or an empty array for an unknown ID
StatusBodyCondition
200response bodyThe lookup finished

The rate limit is 200 requests per minute, on the admin:lookup bucket.

POST/v1/admin/usersAudit reason

Creates an account with no password and returns a password reset link the account holder opens to choose one. You need *.

FieldTypeDescription
usernamestringThe username (1-32 characters)
email?1stringThe email address
admin?booleanWhether to give the account * (default false)

1 Required on an email instance and refused with USERNAME_SIGN_IN_ONLY on a username instance

FieldTypeDescription
userAdmin user objectThe new account
password_resetpassword reset link objectThe link the account holder opens to choose a password
StatusBodyCondition
200response bodyThe account was created
400error responseThe username or email address is taken or invalid

The rate limit is 100 requests per minute, on the admin:user:modify bucket.

PATCH/v1/admin/users/{user_id}/usernameAudit reason

Changes the username and returns the account. You need user:update:username.

FieldTypeDescription
usernamestringThe new username (1-32 characters)
discriminator?1stringA discriminator of one to four digits

1 Used only when the account may have a custom discriminator. Otherwise Fluxer picks a free one

FieldTypeDescription
userAdmin user objectThe updated account
StatusBodyCondition
200response bodyThe username was changed
400error responseTAG_ALREADY_TAKEN when the tag is taken or no discriminator is free

Fluxer sends User Update and Guild Member Update to each guild the account is in.

The rate limit is 100 requests per minute, on the admin:user:modify bucket.

PATCH/v1/admin/users/{user_id}/emailAudit reason

Changes the email address and returns the account. You need user:update:email. The new address is unverified, or verified when the instance doesn't send email. Nobody is emailed about the change.

FieldTypeDescription
emailstringThe new email address (1-254 characters)
FieldTypeDescription
userAdmin user objectThe updated account
StatusBodyCondition
200response bodyThe email address was changed
400error responseEMAIL_ALREADY_IN_USE when another account has the address

Fluxer sends User Update.

The rate limit is 100 requests per minute, on the admin:user:modify bucket.

PUT/v1/admin/users/{user_id}/email-verificationAudit reason

Marks the email address as verified, clears its bounce marker and returns the account. You need user:update:email.

FieldTypeDescription
userAdmin user objectThe updated account
StatusBodyCondition
200response bodyThe email address was marked verified

Fluxer sends User Update.

The rate limit is 100 requests per minute, on the admin:user:modify bucket.

POST/v1/admin/users/{user_id}/verification-emailAudit reason

Emails the account holder a new verification link. You need user:update:email. Nothing is sent when the address is already verified, has bounced or the instance doesn't send email.

StatusBodyCondition
204emptyThe request was accepted
400error responseINVALID_FORM_BODY with USER_DOES_NOT_HAVE_AN_EMAIL_ADDRESS when the account has no address
403error responseBOT_USER_AUTH_ENDPOINT_ACCESS_DENIED when the account is a bot
429error responseThe address already got three verification emails in 15 minutes

The rate limit is 100 requests per minute, on the admin:user:modify bucket.

POST/v1/admin/users/{user_id}/password-resetAudit reason

Emails the account holder a password reset link. You need user:update:email. When the instance doesn't send email, use Create password reset link.

StatusBodyCondition
204emptyThe request was accepted
400error responseEMAIL_DELIVERY_OFF when the instance doesn't send email
400error responseINVALID_FORM_BODY with USER_DOES_NOT_HAVE_AN_EMAIL_ADDRESS when the account has no address

The rate limit is 100 requests per minute, on the admin:user:modify bucket.

POST/v1/admin/users/{user_id}/password-reset-linkAudit reason

Returns a password reset link without emailing it, on an instance where members sign in with a username or one that doesn't send email. You need user:create:password_reset_link and every ACL the account has. Earlier reset links and the account's recovery kit stop working.

StatusBodyCondition
200password reset link objectThe link was created
400error responseUSERNAME_SIGN_IN_ONLY on an email instance that sends email
403error responseMISSING_ACL when the account has an ACL you lack, or BOT_USER_AUTH_ENDPOINT_ACCESS_DENIED for a bot

The rate limit is 100 requests per minute, on the admin:user:modify bucket.

POST/v1/admin/users/{user_id}/sign-in-linkAudit reason

Returns a sign-in link for an account that has *. Only rexctl on the server can call it. The link signs the admin in without a password, a second factor or an email.

StatusBodyCondition
200sign-in link objectThe link was created
403error responseACCESS_DENIED outside rexctl, MISSING_ACL when the account lacks *

The rate limit is 100 requests per minute, on the admin:user:modify bucket.

DELETE/v1/admin/users/{user_id}/recovery-kitAudit reason

Deletes the account's recovery kit, on an instance where members sign in with a username. You need user:delete:recovery_kit and every ACL the account has. The account holder can make a new kit in their settings.

StatusBodyCondition
204noneThe kit was deleted, or there was none
400error responseUSERNAME_SIGN_IN_ONLY on an email instance

The rate limit is 100 requests per minute, on the admin:user:modify bucket.

PATCH/v1/admin/users/{user_id}/date-of-birthAudit reason

Changes the date of birth and returns the account. You need user:update:dob. A deletion scheduled because the account was under the minimum age is canceled.

FieldTypeDescription
date_of_birthstringThe new date as YYYY-MM-DD
FieldTypeDescription
userAdmin user objectThe updated account
StatusBodyCondition
200response bodyThe date of birth was changed

Fluxer sends User Update.

The rate limit is 100 requests per minute, on the admin:user:modify bucket.

DELETE/v1/admin/users/{user_id}/profile-fieldsAudit reason

Clears profile fields and returns the account. You need user:update:profile. The enforcement basis saves the old values as evidence, records a profile reset decision and sends its notice.

FieldTypeDescription
fieldsarray[string]The profile fields to clear (1-10)
basisbasis objectWhy the fields are cleared
FieldTypeDescription
userAdmin user objectThe updated account
StatusBodyCondition
200response bodyThe fields were cleared
400error responseINVALID_FORM_BODY with a decision validation code

Fluxer sends User Update, and Guild Member Update when avatar or global_name changed.

The rate limit is 100 requests per minute, on the admin:user:modify bucket.

PUT/v1/admin/users/{user_id}/bot-statusAudit reason

Marks the account as a bot or not and returns the account. You need user:update:bot_status. Setting bot to false also clears system.

FieldTypeDescription
botbooleanWhether the account is a bot
FieldTypeDescription
userAdmin user objectThe updated account
StatusBodyCondition
200response bodyThe bot status was set
403error responseACCESS_DENIED when the account has Admin ACLs and bot is true

Fluxer sends User Update, and Guild Member Update when the status changed.

The rate limit is 100 requests per minute, on the admin:user:modify bucket.

PUT/v1/admin/users/{user_id}/system-statusAudit reason

Marks a bot as an official system account or not and returns the account. You need user:update:bot_status.

FieldTypeDescription
systembooleanWhether the account is a system account
FieldTypeDescription
userAdmin user objectThe updated account
StatusBodyCondition
200response bodyThe system status was set
400error responseINVALID_FORM_BODY when the account is not a bot

Fluxer sends User Update, and Guild Member Update when the status changed.

The rate limit is 100 requests per minute, on the admin:user:modify bucket.

PUT/v1/admin/users/{user_id}/aclsAudit reason

Replaces the account's Admin ACLs and returns the account. You need acl:set:user, and every ACL you grant unless you have *. The account can use the Admin API while its set has admin:authenticate or *, and a narrower set applies at once to its sessions and Admin API keys.

FieldTypeDescription
aclsarray[string]The new Admin ACLs
FieldTypeDescription
userAdmin user objectThe updated account
StatusBodyCondition
200response bodyThe ACLs were replaced
403error responseMISSING_ACL for an ACL you lack, ACCESS_DENIED when the account is your own

Fluxer sends User Update.

The rate limit is 100 requests per minute, on the admin:user:modify bucket.

PUT/v1/admin/users/{user_id}/traitsAudit reason

Replaces the account's traits and returns the account. You need user:update:traits. Traits are lowercase labels that limit rules can filter on.

FieldTypeDescription
traitsarray[string]The new traits, each 1-128 characters (at most 100)
FieldTypeDescription
userAdmin user objectThe updated account
StatusBodyCondition
200response bodyThe traits were replaced

Fluxer sends User Update.

The rate limit is 100 requests per minute, on the admin:user:modify bucket.

PATCH/v1/admin/users/{user_id}/badgesAudit reason

Replaces the custom badges given to the account and returns the account. You need user:update:badges.

FieldTypeDescription
badge_idsarray[snowflake]The user badges to give, replacing the current ones (at most 1000)
FieldTypeDescription
userAdmin user objectThe updated account
StatusBodyCondition
200response bodyThe badges were replaced
400error responseMAX_BADGES when the list adds a badge and holds more than max_per_user of the badge settings
404error responseUNKNOWN_BADGE when an ID isn't a user badge, or UNKNOWN_USER

A list that only removes badges always works, even when the account still has more than the limit after a limit was lowered.

The profile shows the change the next time someone loads it, and Fluxer sends no Gateway event.

The rate limit is 100 requests per minute, on the admin:user:modify bucket.

PATCH/v1/admin/users/{user_id}/flagsAudit reason

Adds and removes account flags and returns the account. You need user:update:flags. You can't add DISABLED, DELETED, SPAMMER or REPORT_BANNED, remove DELETED, or remove DISABLED from a suspended account. Use Suspend user or Schedule user deletion for those. Bulk jobs can make the same change on many accounts.

FieldTypeDescription
add_flags?array[string]The flag values to add, as decimal strings (at most 64)
remove_flags?array[string]The flag values to remove, as decimal strings (at most 64)
FieldTypeDescription
userAdmin user objectThe updated account
StatusBodyCondition
200response bodyThe flags were updated
400error responseFLAG_REQUIRES_ENFORCEMENT_ROUTE for a restriction flag
409error responseENFORCEMENT_DECISION_OWNS_STATE when a feature limit set the flag

Fluxer sends User Update, and Guild Member Update when a public flag changed.

The rate limit is 100 requests per minute, on the admin:user:modify bucket.

PATCH/v1/admin/users/{user_id}/premium-flagsAudit reason

Adds and removes premium flags and returns the account. You need user:update:flags. These flags don't grant or end premium. To block purchases, use Limit user features.

FieldTypeDescription
add_flags?array[integer]The flag values to add (at most 64)
remove_flags?array[integer]The flag values to remove (at most 64)
FieldTypeDescription
userAdmin user objectThe updated account
StatusBodyCondition
200response bodyThe premium flags were updated
400error responseFLAG_REQUIRES_ENFORCEMENT_ROUTE when adding PURCHASE_DISABLED
409error responseENFORCEMENT_DECISION_OWNS_STATE when a feature limit set the purchase block

Fluxer sends User Update.

The rate limit is 100 requests per minute, on the admin:user:modify bucket.

PUT/v1/admin/users/{user_id}/banAudit reason

Suspends the account for some hours or permanently, records the enforcement decision and returns the account. You need user:temp_ban. The account is signed out everywhere, and a new suspension replaces the current one. To lift it, end the decision.

FieldTypeDescription
duration_hoursintegerHow many hours to suspend for, or 0 for permanently (0-8760)
decisionenforcement decision input objectWhy the account is suspended
remove_evidence?1booleanWhether to delete the reported messages and the listed evidence once saved. Other report messages are kept
block_networks?2network block request objectThe account's addresses to block

1 Needs message:shred

2 Only for a permanent suspension. Needs ban:ip:add and user:view:ip

FieldTypeDescription
ips1array[string]The IP addresses to block (1-20)
days?integerHow many days the blocks last (1-365, default 90)

1 Each must be one List network block candidates returns

FieldTypeDescription
userAdmin user objectThe suspended account
skipped_ipsarray[object]The addresses not blocked, each with ip and a reason of exempt, special_purpose or already_blocked
StatusBodyCondition
200response bodyThe account was suspended
400error responseINVALID_FORM_BODY with a decision validation code
409error responseENFORCEMENT_ACCOUNT_CLOSED when the account is closed

The rate limit is 100 requests per minute, on the admin:user:modify bucket.

GET/v1/admin/users/{user_id}/network-block-candidates

Lists the addresses the account used in the last 30 days, newest first, which you can pass in block_networks. You need user:view:ip.

FieldTypeDescription
networksarray[object]One entry per address, with ip, last_seen_at, skip_reason and other_unrestricted_accounts

skip_reason is exempt or special_purpose for an address Fluxer never blocks. An address with other_unrestricted_accounts above zero is shared with an account in good standing and can't be blocked.

StatusBodyCondition
200response bodyThe addresses were listed

The rate limit is 200 requests per minute, on the admin:lookup bucket.

DELETE/v1/admin/users/{user_id}/banAudit reason

Lifts a suspension that no enforcement decision owns and returns the account. You need user:temp_ban. The account holder is emailed when the suspension was still in force. Sessions that were signed out stay signed out.

FieldTypeDescription
userAdmin user objectThe updated account
StatusBodyCondition
200response bodyThe suspension was lifted
409error responseENFORCEMENT_DECISION_OWNS_STATE when a decision owns the suspension

Fluxer sends User Update.

The rate limit is 100 requests per minute, on the admin:user:modify bucket.

POST/v1/admin/users/{user_id}/warningsAudit reason

Records a warning decision and sends its notice by email and system DM. You need user:update:flags.

FieldTypeDescription
decisionenforcement decision input objectWhy the account is warned
FieldTypeDescription
decision_idsnowflakeThe ID of the warning decision
StatusBodyCondition
200response bodyThe warning was recorded
400error responseINVALID_FORM_BODY with a decision validation code

The rate limit is 100 requests per minute, on the admin:user:modify bucket.

PUT/v1/admin/users/{user_id}/feature-limitsAudit reason

Records a decision that limits one feature, sets its account flag and returns the account. You need user:update:flags. Feature limits lists each limit's flag and reasons.

FieldTypeDescription
limitstringdirect_messages, reports or purchases
ends_at?1ISO8601 timestampWhen a reports limit ends
decisionenforcement decision input objectWhy the feature is limited

1 Only for reports, at most 365 days away (default 90 days)

FieldTypeDescription
userAdmin user objectThe updated account
StatusBodyCondition
200response bodyThe limit was recorded
400error responseINVALID_FORM_BODY with a decision validation code

Fluxer sends User Update.

The rate limit is 100 requests per minute, on the admin:user:modify bucket.

PUT/v1/admin/users/{user_id}/deletionAudit reason

Closes the account, signs it out everywhere, schedules its deletion and returns the account. You need user:delete. The account is kept for at least 14 days unless you set immediate, which queues the deletion right away and can't be undone.

BasisEffect
enforcementRecords a closure decision, sends its notice and blocks the email address, except for minimum age reasons
holder_requestSets deletion_reason_code to USER_REQUESTED, emails the account holder, and signing in cancels it
housekeepingSets deletion_reason_code to INACTIVITY, emails the account holder, and signing in cancels it
FieldTypeDescription
days_until_deletionintegerHow many days until deletion, at least 14 (1-365)
basisbasis objectWhy the account is closed
replace_pending_deletion_at?1ISO8601 timestampThe pending_deletion_at of the schedule you replace
remove_evidence?2booleanWhether to delete the reported messages and the listed evidence once saved. Other report messages are kept
block_networks?2network block request objectThe account's addresses to block
immediate?booleanWhether to delete the account now

1 Required when a deletion is already scheduled

2 Only with the enforcement basis, with the same ACLs as on Suspend user

FieldTypeDescription
userAdmin user objectThe closed account
skipped_ipsarray[object]The addresses not blocked, as on Suspend user
StatusBodyCondition
200response bodyThe deletion was scheduled
400error responseINVALID_FORM_BODY with a decision validation code
409error responseENFORCEMENT_DECISION_OWNS_STATE when a decision owns the account
409error responseCONFLICT when replace_pending_deletion_at doesn't match the scheduled deletion, or erasure has started

The rate limit is 100 requests per minute, on the admin:user:modify bucket.

DELETE/v1/admin/users/{user_id}/deletionAudit reason

Cancels a scheduled deletion that no enforcement decision owns, emails the account holder and returns the account. You need user:delete. The account can sign in again, but signed-out sessions stay signed out. To cancel a closure with a decision, end the decision.

FieldTypeDescription
expected_pending_deletion_atISO8601 timestampThe current pending_deletion_at
FieldTypeDescription
userAdmin user objectThe updated account
StatusBodyCondition
200response bodyThe deletion was canceled
400error responseNO_PENDING_DELETION when nothing is scheduled
409error responseENFORCEMENT_DECISION_OWNS_STATE when a decision owns the deletion
409error responseCONFLICT when a different deletion is scheduled or erasure has started

Fluxer sends User Update.

The rate limit is 100 requests per minute, on the admin:user:modify bucket.

GET/v1/admin/users/{user_id}/guildsAudit reason

Lists the guilds the account is in, by ascending guild ID. You need user:list:guilds. Use the last guild ID as the next after.

FieldTypeDescription
before?snowflakeReturn guilds before this guild ID
after?snowflakeReturn guilds after this guild ID
limit?integerHow many guilds to return (1-200, default 200)
with_counts?booleanWhether to include member and presence counts (default false)
FieldTypeDescription
guildsarray[Admin guild object]The guilds in this page
StatusBodyCondition
200response bodyThe guilds were returned

The rate limit is 200 requests per minute, on the admin:lookup bucket.

GET/v1/admin/users/{user_id}/sso-identitiesAudit reason

Lists the single sign-on subjects bound to the account. You need user:lookup.

FieldTypeDescription
sso_identitiesarray[Admin SSO identity object]The subjects bound to the account
StatusBodyCondition
200response bodyThe identities were returned

The rate limit is 200 requests per minute, on the admin:lookup bucket.

GET/v1/admin/sso-identitiesAudit reason

Finds the account a single sign-on subject is bound to. You need user:lookup.

FieldTypeDescription
provider_idstringThe provider ID (1-2048 characters)
subjectstringThe exact provider subject (1-1024 characters)
FieldTypeDescription
sso_identity?Admin SSO identity objectThe identity, or null when no account has the subject
StatusBodyCondition
200response bodyThe lookup finished

The rate limit is 200 requests per minute, on the admin:lookup bucket.

PUT/v1/admin/users/{user_id}/sso-identitiesAudit reason

Binds a subject from the current provider to the account and releases the subjects bound before. You need user:update:email. Use it when the provider sends a new subject for the same person.

FieldTypeDescription
subjectstringThe exact provider subject (1-1024 characters)
FieldTypeDescription
sso_identitiesarray[Admin SSO identity object]The subjects bound to the account now
StatusBodyCondition
200response bodyThe subject was bound
400error responseSSO_IDENTITY_LINKED_TO_ANOTHER_ACCOUNT when an account that isn't deleted has the subject

The rate limit is 100 requests per minute, on the admin:user:modify bucket.

DELETE/v1/admin/users/{user_id}/sso-identitiesAudit reason

Releases every subject bound to the account and signs it out on every device. You need user:update:email. On an email instance, the next single sign-on with a matching verified email binds the account again.

FieldTypeDescription
sso_identitiesarray[Admin SSO identity object]The subjects still bound, which is empty
StatusBodyCondition
200response bodyThe subjects were released

The rate limit is 100 requests per minute, on the admin:user:modify bucket.

POST/v1/admin/sso-identities/migrateAudit reason

Moves every subject from an earlier provider ID to the current one, keeping each on its account. You need instance:config:update. The provider ID is the issuer URL, or the authorization URL without an issuer. Run this once after you change either.

FieldTypeDescription
from_provider_idstringThe earlier provider ID (1-2048 characters)
FieldTypeDescription
to_provider_idstringThe current provider ID
moved_countintegerHow many subjects were moved
skipped_countintegerHow many subjects were left because another account has them or their account is gone
StatusBodyCondition
200response bodyThe move finished
400error responsefrom_provider_id is the current provider

The rate limit is 100 requests per minute, on the admin:user:modify bucket.

One single sign-on subject bound to an account.

FieldTypeDescription
provider_idstringThe provider's issuer URL, or its authorization URL without an issuer
subjectstringThe sub claim the provider sent
user_idsnowflakeThe ID of the account
claimed_atISO8601 timestampWhen the subject was bound
GET/v1/admin/users/{user_id}/dm-channelsAudit reason

Lists the direct message channels the account is in, without opening or marking any as read. You need user:list:dm_channels. Ask for group direct messages with type=group_dm, which returns all of them and ignores the paging fields.

FieldTypeDescription
type?stringdm or group_dm (default dm)
before?1snowflakeReturn channels with lower IDs
after?1snowflakeReturn channels with higher IDs
limit?integerHow many channels to return (1-200, default 50)

1 Send one or the other

FieldTypeDescription
channelsarray[Admin direct message channel object]The channels in this page
StatusBodyCondition
200response bodyThe channels were returned

The rate limit is 200 requests per minute, on the admin:lookup bucket.

GET/v1/admin/users/{user_id}/applicationsAudit reason

Lists the OAuth2 applications the account owns. You need application:list:by_owner.

FieldTypeDescription
applicationsarray[Admin application object]The applications the account owns
StatusBodyCondition
200response bodyThe applications were returned

The rate limit is 200 requests per minute, on the admin:lookup bucket.

GET/v1/admin/users/{user_id}/relationshipsAudit reason

Lists the account's friends, friend requests and blocks. You need user:list:relationships.

FieldTypeDescription
friendsarray[Admin relationship object]The account's friends
incoming_requestsarray[Admin relationship object]The friend requests the account received
outgoing_requestsarray[Admin relationship object]The friend requests the account sent
blockedarray[Admin relationship object]The accounts this account blocked
StatusBodyCondition
200response bodyThe relationships were returned

The rate limit is 200 requests per minute, on the admin:lookup bucket.

DELETE/v1/admin/users/{user_id}/relationshipsAudit reason

Removes all of the account's relationships in one category. You need user:remove:relationship.

FieldTypeDescription
categorystringThe relationship category to clear
FieldTypeDescription
removed_countintegerHow many relationships were removed
StatusBodyCondition
200response bodyThe relationships were removed

Both accounts get Relationship Remove for a removed friendship or request, and only this account for a removed block.

The rate limit is 100 requests per minute, on the admin:user:modify bucket.

DELETE/v1/admin/users/{user_id}/relationships/{target_user_id}Audit reason

Removes the account's relationship with target_user_id in one category. You need user:remove:relationship.

FieldTypeDescription
categorystringThe relationship category to remove
StatusBodyCondition
204emptyThe relationship was removed

Fluxer sends Relationship Remove as on Clear user relationships.

The rate limit is 100 requests per minute, on the admin:user:modify bucket.

GET/v1/admin/users/{user_id}/sessionsAudit reason

Lists the account's active and ended sessions, active first and then newest first. You need user:list:sessions, and user:view:ip for the address fields.

FieldTypeDescription
sessionsarray[Admin user session object]The account's sessions
StatusBodyCondition
200response bodyThe sessions were returned
503error responseSERVICE_UNAVAILABLE when every location lookup failed

The rate limit is 100 requests per minute, on the admin:user:modify bucket.

GET/v1/admin/app-sessionsAudit reason

Lists the active sessions whose last X-Fluxer-Client-Properties header sent the given platform and release channel. You need user:list:sessions. A page has up to 200 sessions and can have fewer while next_cursor is set, so keep reading until it is null.

FieldTypeDescription
platformstringOne of android, ios, linux or desktop
release_channelstringOne of stable, beta or canary
after?stringThe next_cursor from the previous page (1-128 characters)
FieldTypeDescription
sessionsarray[Admin app session object]The sessions on this page
next_cursor?stringThe value to send as after for the next page, or null on the last page
StatusBodyCondition
200response bodyThe page was returned, even with no sessions

The rate limit is 200 requests per minute, on the admin:lookup bucket.

DELETE/v1/admin/users/{user_id}/sessionsAudit reason

Signs the account out of every session. You need user:update:flags. Admin API keys, bot tokens and OAuth2 tokens keep working.

FieldTypeDescription
terminated_countintegerHow many sessions were ended
StatusBodyCondition
200response bodyThe sessions were ended

The rate limit is 100 requests per minute, on the admin:user:modify bucket.

GET/v1/admin/users/{user_id}/webauthn-credentialsAudit reason

Lists the account's passkeys and security keys as a JSON array. You need user:update:mfa.

StatusBodyCondition
200array[WebAuthn credential object]The credentials were returned

The rate limit is 100 requests per minute, on the admin:user:modify bucket.

DELETE/v1/admin/users/{user_id}/webauthn-credentials/{credential_id}Audit reason

Deletes one passkey or security key from the account. You need user:update:mfa. An unknown credential returns 404 UNKNOWN_USER.

FieldTypeDescription
user_idsnowflakeThe ID of the account
credential_idstringThe WebAuthn credential ID (1-512 characters)
StatusBodyCondition
204emptyThe credential was deleted

Fluxer sends WebAuthn Credentials Update, and User Update when the account's last passkey is removed.

The rate limit is 100 requests per minute, on the admin:user:modify bucket.

DELETE/v1/admin/users/{user_id}/mfaAudit reason

Removes the account's TOTP authenticator, second-factor types and backup codes. You need user:update:mfa. Passkeys stay registered and still sign the account in until you remove them with Delete user WebAuthn credential.

StatusBodyCondition
204emptyMFA was turned off

Fluxer sends User Update.

The rate limit is 100 requests per minute, on the admin:user:modify bucket.

DELETE/v1/admin/users/{user_id}/messagesAudit reason

Counts the account's messages and, unless it is a dry run, queues a shred job that deletes them. You need message:delete_all. The enforcement basis records a content removal decision and sends its notice. For child safety and violent extremism reasons, use Shred user messages.

FieldTypeDescription
dry_run?stringWhether to only count the messages (default true)
FieldTypeDescription
basis?1basis objectWhy the messages are removed

1 Required unless it is a dry run

FieldTypeDescription
successbooleanAlways true
dry_runbooleanWhether the request only counted
channel_countintegerAbout how many channels have the account's messages
message_countintegerHow many messages matched
job_id?stringThe ID of the queued shred job
decision_id?snowflakeThe content removal decision
StatusBodyCondition
200response bodyThe count finished and any job was queued
400error responseMODERATION_BASIS_REQUIRED without a basis, or a decision validation code

The rate limit is 100 requests per minute, on the admin:message:operation bucket.

POST/v1/admin/users/{user_id}/message-shreds/previewAudit reason

Lists exactly the messages a shred of these entries deletes, without deleting anything or recording a decision. You need message:shred. A message is listed only when the account sent it in the named channel. Missing messages, messages someone else sent and repeated entries are returned in skipped. Pass preview_token to Shred user messages to delete exactly these messages.

FieldTypeDescription
entriesarray[message shred entry object]The messages to check (1-1000)
FieldTypeDescription
requestedintegerHow many entries you sent
message_countintegerHow many messages a shred deletes
messagesarray[object]Each message a shred deletes, with channel_id, message_id, timestamp, content and attachment_count1
skippedarray[object]Each entry a shred leaves alone, with channel_id, message_id and a reason of not_found, other_author or duplicate
preview_tokenstringPass this with the shred

1 content holds the first 200 characters of the message

StatusBodyCondition
200response bodyThe preview is ready

The rate limit is 100 requests per minute, on the admin:message:operation bucket.

POST/v1/admin/users/{user_id}/message-shredsAudit reason

Queues a job that deletes the listed messages for good, with their reactions and attachments. You need message:shred. The job skips a message that is gone or isn't the account's, and you follow it with Get message shred job. Preview the entries first to see exactly what is deleted.

FieldTypeDescription
entriesarray[message shred entry object]The messages to delete (1-1000)
basis1basis objectWhy the messages are removed
preview_token?2stringThe preview_token from a preview of the same entries

1 The enforcement basis records a content removal decision, saves the first 50 deleted messages as evidence and sends the notice

2 With a token, only the previewed messages are deleted, and the shred is refused with MESSAGE_SHRED_PREVIEW_CHANGED when they changed since the preview

FieldTypeDescription
successbooleanAlways true
job_idstringThe ID of the shred job
requestedintegerHow many entries you sent
decision_id?snowflakeThe content removal decision
StatusBodyCondition
200response bodyThe job was queued
400error responseINVALID_FORM_BODY with MESSAGE_SHRED_PREVIEW_CHANGED or a decision validation code

The rate limit is 100 requests per minute, on the admin:message:operation bucket.

DELETE/v1/admin/users/{user_id}/message-deletionAudit reason

Cancels the message deletion the account holder scheduled for their own account and returns the account. You need user:cancel:bulk_message_deletion.

FieldTypeDescription
userAdmin user objectThe updated account
StatusBodyCondition
200response bodyThe deletion was canceled, or none was scheduled

The rate limit is 100 requests per minute, on the admin:user:modify bucket.

POST/v1/admin/users/{user_id}/archivesAudit reason

Starts building an archive of the account's data. You need archive:trigger:user.

FieldTypeDescription
include_attachments?booleanWhether to include uploaded files (default false)
StatusBodyCondition
200archive objectThe archive was queued

The rate limit is 200 requests per minute, on the admin:lookup bucket.

GET/v1/admin/users/{user_id}/change-logAudit reason

Lists the account's email and tag changes, newest first. You need user:view:contact_log, and user:view:email to see email values.

FieldTypeDescription
limit?integerHow many entries to return (1-200, default 50)
page_token?stringThe next_page_token from the previous page (1-64 characters)
FieldTypeDescription
entriesarray[Admin user change log object]The changes in this page
next_page_token?stringThe token for the next page, or null at the end
StatusBodyCondition
200response bodyThe changes were returned

The rate limit is 200 requests per minute, on the admin:lookup bucket.