Skip to content
Fluxer API

Admin messages

Admin message routes read, search, and permanently delete the messages of one channel. Another reports the progress of a shred job.

Shredding and bulk deletion for a whole account live under Admin users.

A flattened moderation view of one message. It has the author identity, the content and timestamp, the attachments, and the NSFW context of the channel and guild.

Every operation that returns Admin message objects also returns the matching public message objects in a parallel message_responses array, so a client that needs the full wire shape joins on id.

A message_responses entry has no thread field, and a thread started from a message lists no THREAD_STARTER_MESSAGE. Thread messages defines both.

FieldTypeDescription
idsnowflakeThe ID of the message
channel_idsnowflakeThe channel the message was sent in
channel_name1?stringThe channel name, or null for a channel that has no name
channel_nsfw1?booleanWhether the channel is marked NSFW
channel_content_warning_level?2?integerThe channel content warning level
channel_content_warning_text?2?stringThe channel content warning text (0-200 characters)
guild_id1?snowflakeThe guild containing the channel, or null for a private channel
guild_name1?stringThe guild name, or null for a private channel
guild_nsfw_level1?integerThe guild NSFW level, or null for a private channel
guild_nsfw?2?booleanWhether the guild is marked NSFW
guild_content_warning_level?2?integerThe guild content warning level
guild_content_warning_text?2?stringThe guild content warning text (0-200 characters)
author_idsnowflakeThe ID of the author
author_usernamestringThe author username (1-100 characters)
author_global_name?stringThe author display name, or null when unset
author_discriminatorstringThe author discriminator tag (1-10 characters)
author_avatar?stringThe author avatar hash, or null when unset
contentstringThe message content (0-4,000 characters)
timestampISO8601 timestampWhen the message was sent
attachmentsarray[Admin message attachment object]The attachments of the message (at most 10)

1 Every object in one response has the same values, taken from the channel named in the request path or query. All are null when the channel no longer exists

2 Always absent from the objects these operations return. The same member is set on the report message context object

For a thread, channel_nsfw is the value of its parent channel, as Thread object describes.

{
"id": "1502771119476146176",
"channel_id": "1471002884199612420",
"channel_name": "general",
"channel_nsfw": false,
"guild_id": "1471002884199612416",
"guild_name": "Tidepool",
"guild_nsfw_level": 0,
"author_id": "1490118377238528000",
"author_username": "kestrel",
"author_global_name": null,
"author_discriminator": "0117",
"author_avatar": "a1b2c3d4e5f60718293a4b5c6d7e8f90",
"content": "read the pinned message",
"timestamp": "2026-03-04T18:19:07.220Z",
"attachments": []
}

An attachment entry has the ordinary attachment metadata.

FieldTypeDescription
idsnowflakeThe ID of the attachment
filenamestringThe attachment filename (1-256 characters)
urlstringThe CDN URL of the attachment (1-2,048 characters)
nsfw?booleanWhether the attachment is marked NSFW, or null when it has no marking
content_type?stringThe recorded MIME type, or null when none was recorded
width?integerThe pixel width, or null when no dimensions were recorded
height?integerThe pixel height, or null when no dimensions were recorded
size?3?integerThe attachment size in bytes, or null when no size was recorded

3 Always emitted, so it is null and never absent when no size was recorded

The state of one message shred job. The state expires one hour after it was last written, and an expired job is reported by status alone.

FieldTypeDescription
statusnot_found | in_progress | completed | failedThe job state
requested1integerThe number of message references the job was queued with
total1integerThe number of those references the job resolved as shreddable
processed1integerThe number of messages the job has shredded so far
skipped1 2integerThe number of references the job did not shred
started_at?1 3ISO8601 timestampWhen the job started
completed_at?1ISO8601 timestampWhen the job completed
failed_at?1ISO8601 timestampWhen the job failed
error?1 4stringWhy the job failed (1-4,000 characters)

1 Absent when status is not_found, a shape that has status alone

2 Counts a reference that repeats an earlier entry, one whose IDs are not valid snowflakes, one whose message no longer exists, and one no longer authored by the target user

3 Present whenever the counters are

4 Present only when status is failed

GET/v1/admin/channels/{channel_id}/messagesAudit reason

Returns one page of Admin message objects for one channel. Requires message:lookup.

The read ignores message history permissions, channel membership, and the age cutoff applied to ordinary members, so it returns every message the channel still holds.

FieldTypeDescription
channel_idsnowflakeThe ID of the channel
FieldTypeDescription
limit?integerMaximum messages to return (1-100, default 50)
before?1snowflakeReturn messages with a lower ID than this cursor
after?1 2snowflakeReturn messages with a higher ID than this cursor

1 Supplying neither selects the newest messages in the channel. Supplying both selects the newest messages below before and discards any at or below after

2 Supplying after also flips the order of the returned array

FieldTypeDescription
messages1array[Admin message object]Messages in this page (at most 100)
message_responses?2array[message object]The same messages in the public wire shape, same order (at most 100)
has_more3booleanWhether the page was filled to limit

1 Ordered oldest first, except when after was supplied, in which case it is ordered newest first

2 Written by every response this operation produces

3 True when the page holds exactly limit entries, so a page that ends on the last message reports true and the next request returns an empty page

StatusBodyCondition
200response bodyMessage page was returned

The response has no cursor member. Page further by sending the ID of the oldest returned message as before, or the ID of the newest returned message as after.

A channel that does not exist returns an empty messages array with has_more false, so this operation never answers 404.

One Admin audit entry is recorded with the action list_channel_messages, the target type channel, and the channel ID as the target. Its metadata keys are limit, result_count for the messages in this page, and has_more. A supplied before or after cursor is added under the same key.

100 requests per minute for each authenticated user, on the shared admin:message:operation bucket.

GET/v1/admin/channels/{channel_id}/messages/{message_id}Audit reason

Returns the requested message together with the messages surrounding it, as one array of Admin message objects, oldest first. Requires message:lookup.

FieldTypeDescription
channel_idsnowflakeThe ID of the channel
message_idsnowflakeThe ID of the message
FieldTypeDescription
context_limit?1integerSize of the whole returned window, counting the requested message (1-100, default 50)

1 At most context_limit divided by two, rounded down, are newer than the requested message and the rest are older, so the default returns at most 25 newer and 24 older

FieldTypeDescription
messages1array[Admin message object]The requested message and its surrounding window (at most 100)
message_responses?array[message object]The same messages in the public wire shape, same order (at most 100)
message_id2?snowflakeThe requested message ID

1 The requested message is one entry of this array, and it is absent when it no longer exists

2 Echoes the path parameter and is never null here

StatusBodyCondition
200response bodyWindow was returned

An unknown message returns 200 with the window surrounding the position the missing ID would have occupied, so this operation never returns UNKNOWN_MESSAGE. An unknown channel returns 200 with an empty messages array.

One Admin audit entry is recorded with the action get_message, the target type message, and the message ID as the target. Its metadata keys are channel_id, context_limit, result_count for the messages returned, and found, which is true when the requested message is in messages and false otherwise.

100 requests per minute for each authenticated user, on the shared admin:message:operation bucket.

DELETE/v1/admin/channels/{channel_id}/messages/{message_id}Audit reason

Permanently deletes one message and purges the attachments it owned. Requires message:delete.

FieldTypeDescription
channel_idsnowflakeThe ID of the channel
message_idsnowflakeThe ID of the message
FieldTypeDescription
successbooleanAlways true
StatusBodyCondition
200response bodyRequest completed and the audit entry was written

An unknown channel or message returns 200 with success true and still records an audit entry.

The message and its attachments are permanently removed, including from search results and the CDN.

Message Delete is sent to the guild when the channel belongs to one, and to each recipient when the channel is private. No other Dispatch is emitted, and deleting a pinned message here emits no Channel Pins Update.

A deleted message in a thread no longer counts towards message_count of the thread object. Fluxer emits no Thread Update for the change.

One Admin audit entry is recorded with the action delete_message and the target type message, targeting the message ID. Its metadata is channel_id and message_id. The entry is written whether or not a message was found.

100 requests per minute for each authenticated user, on the shared admin:message:operation bucket.

GET/v1/admin/messagesAudit reason

Searches the message index of one channel, or resolves one message in that channel by message ID or by attachment identity. Requires message:lookup.

A request with message_id or attachment_id returns the lookup response body. Any other request returns the search response body.

FieldTypeDescription
channel_idsnowflakeThe channel every returned message was sent in
q?1stringFree-text query matched against message content (1-200 characters)
message_id?2snowflakeResolve the message with this ID together with its surrounding window
attachment_id?2 3snowflakeResolve the message with this attachment together with its surrounding window
filename?3stringThe exact filename of the attachment named by attachment_id (1-255 characters)
context_limit?2integerSize of the window returned by a lookup, counting the resolved message (1-100, default 50)
limit?1integerMaximum messages to return when searching (1-100, default 25)

1 Applies to the search mode only. Omitting q searches for the empty string

2 message_id takes precedence over every other member, and attachment_id over q. A lookup ignores limit and a search ignores context_limit

3 Supply both together. Sending attachment_id without filename returns 400 INVALID_FORM_BODY against filename

Returned when neither message_id nor attachment_id was supplied.

FieldTypeDescription
messages4array[Admin message object]Matching messages (at most 100)
message_responses?array[message object]The same messages in the public wire shape, same order (at most 100)
total5integerThe number of matches that still exist

4 Holds at most limit entries. There is no cursor and no offset member, so this operation returns the first page of matches only

5 Counts every surviving match, so it can exceed the length of messages

Returned when message_id or attachment_id was supplied. It is the same body Get message returns.

FieldTypeDescription
messagesarray[Admin message object]The resolved message and its surrounding window, oldest first (at most 100)
message_responses?array[message object]The same messages in the public wire shape, same order (at most 100)
message_id6?snowflakeThe ID of the resolved message

6 Null only for an attachment lookup that matched no attachment, in which case messages is empty too. A message_id lookup echoes the supplied ID even when no such message exists

StatusBodyCondition
200search or lookup response bodySearch or lookup completed

The result is empty for an unknown channel, for a message that does not exist, and for an attachment whose filename does not match. This operation never answers 404.

With no message search service configured the search mode returns an empty messages array and total zero. The lookup modes are unaffected.

One Admin audit entry is recorded with the action search_messages. Its metadata key mode is message for a message_id lookup, attachment for an attachment lookup, and search otherwise, and result_count is the number of messages returned.

  • A message_id lookup has the target type message and the message ID as the target. It adds channel_id, context_limit, and found, which is true when the message is in messages.
  • An attachment lookup has the target type channel and the channel ID as the target. It adds attachment_id, context_limit, and found, which is true when the attachment resolved. A resolved attachment also adds message_id.
  • A search has the target type channel and the channel ID as the target. It adds limit and total, and has_query as true when q is supplied.

The query text and the filename are not recorded. A 400 records nothing.

100 requests per minute for each authenticated user, on the shared admin:message:operation bucket.

GET/v1/admin/messages/shreds/{job_id}Audit reason

Returns one message shred status object. Requires message:shred.

Shred jobs are created by Shred user messages and by the non-dry-run form of Delete all user messages. Both return the identifier this operation reads.

FieldTypeDescription
job_id1snowflakeThe message shred job ID, taken from the queueing response

1 A snowflake issued when the job was queued, so a value that is not a decimal integer fails path validation instead of reporting not_found

StatusBodyCondition
200message shred status objectJob state was returned, including not_found for an unknown or expired job

One Admin audit entry is recorded with the action get_message_shred_status, the target type message_shred, and the target ID 0. Its metadata keys are job_id and status, which is the returned job state.

100 requests per minute for each authenticated user, on the shared admin:message:operation bucket.