Admin reports
A report is one complaint filed against a message, an account, or a guild, together with the evidence captured when it was filed. These routes list and search reports, return that evidence, resolve a report with a comment shown to the reporter, hold a report past its retention period, and delete a report before it.
Report submission belongs to the public Reports resource, which defines the report categories and the report reasons a report is filed under.
Reporter contact fields require report:view:reporter_pii on top of report:view. Without it reporter_email, reporter_full_legal_name, and reporter_country_of_residence are null on every report, so a redacted field looks like a field the reporter never supplied.
Admin report object
Section titled “Admin report object”A report is written once, when the reporter files it. Update report moves it from PENDING to RESOLVED with an optional comment. Schedule user deletion for one of the abuse reasons listed there also resolves the pending reports against the deleted account, with no public comment, and sends each reporter the generic notice Update report describes. A report in the child_safety, underage_user, or self_harm category is never resolved this way and stays PENDING. A report is deleted at the end of its retention period, or earlier through Delete report.
List reports returns this object without message context. Get report returns the Admin report detail object, which extends it.
Structure
Section titled “Structure”| Field | Type | Description |
|---|---|---|
| report_id | snowflake | The ID of the report |
| reporter_id1 | ?snowflake | The account that filed the report |
| reporter_tag1 2 18 | ?string | The reporter username and four-digit discriminator joined by # |
| reporter_username1 2 | ?string | The username of the reporter |
| reporter_global_name1 2 | ?string | The display name of the reporter, or null when unset |
| reporter_discriminator1 2 | ?string | The zero-padded four-digit reporter discriminator |
| reporter_email3 | ?string | The email address of the reporter |
| reporter_full_legal_name3 | ?string | The legal name supplied with a Digital Services Act notice |
| reporter_country_of_residence3 | ?string | The country of residence supplied with a Digital Services Act notice |
| reported_at | ISO8601 timestamp | When the report was submitted |
| status | integer | The report status |
| report_type | integer | The report type |
| category | ?string | The report category, derived from reason when the report has one |
| reason?7 10 | ?string | The report reason the report was filed under |
| reason_label?7 11 | ?string | The English label of the reason |
| reason_highest_priority?7 12 | ?boolean | Whether the reason is one moderators see first |
| flow?7 10 | ?report flow answers object | The answers the reporter gave, described in English |
| reporter_good_faith_confirmed?7 13 | ?boolean | Whether the reporter confirmed the notice in good faith |
| additional_info | ?string | The free-text detail the reporter supplied |
| reported_user_id14 | ?snowflake | The reported account, or null for a guild report |
| reported_user_tag2 18 | ?string | The reported username and four-digit discriminator joined by # |
| reported_user_username2 | ?string | The username of the reported account |
| reported_user_global_name2 | ?string | The display name of the reported account, or null when unset |
| reported_user_discriminator2 | ?string | The zero-padded four-digit reported account discriminator |
| reported_user_avatar_hash4 | ?string | The avatar hash of the reported account, or null when unset |
| reported_user_bot?2 7 17 | ?boolean | Whether the reported account is a bot |
| reported_webhook_id?7 14 | ?snowflake | The webhook that sent the reported message |
| reported_webhook_name?4 7 14 | ?string | The name the reported message was sent under |
| reported_webhook_avatar_hash?4 7 14 | ?string | The avatar hash the reported message was sent with, or null when unset |
| reported_webhook_default_name?4 7 14 15 | ?string | The name set on the webhook itself |
| reported_webhook_default_avatar_hash?4 7 14 15 | ?string | The avatar hash set on the webhook itself, or null when unset |
| reported_webhook_type?4 7 14 15 | ?integer | The webhook type |
| reported_webhook_application_id?4 7 14 15 | ?snowflake | The application whose bot account created the webhook, or null when a user account created it |
| reported_webhook_channel_id?4 7 14 15 | ?snowflake | The channel the webhook belonged to |
| reported_webhook_guild_id?4 7 14 15 | ?snowflake | The guild the webhook belonged to |
| reported_webhook_created_at?7 14 | ?ISO8601 timestamp | When the webhook was created, derived from its ID |
| reported_webhook_creator_id?4 7 14 15 | ?snowflake | The account that created the webhook |
| reported_webhook_creator_tag?4 7 14 15 16 18 | ?string | The creator username and four-digit discriminator joined by # |
| reported_webhook_creator_username?4 7 14 15 16 | ?string | The username of the creator |
| reported_webhook_creator_global_name?4 7 14 15 16 | ?string | The display name of the creator, or null when unset |
| reported_webhook_creator_discriminator?4 7 14 15 16 | ?string | The zero-padded four-digit creator discriminator |
| reported_webhook_creator_avatar_hash?4 7 14 15 16 | ?string | The avatar hash of the creator, or null when unset |
| reported_guild_id | ?snowflake | The reported guild, or null when the report names none |
| reported_guild_name4 | ?string | The name of the reported guild |
| reported_guild_icon_hash4 | ?string | The icon hash of the reported guild, or null when unset |
| reported_message_id | ?snowflake | The reported message, or null for a user or guild report |
| reported_channel_id | ?snowflake | The channel the reported content was sent in |
| reported_channel_name4 | ?string | The channel name, or null for a direct message channel |
| reported_channel_nsfw5 | ?boolean | The effective NSFW state of the reported channel |
| reported_guild_invite_code4 | ?string | The invite code the reported guild was reached by |
| reported_guild_nsfw_level6 | ?integer | The guild NSFW level |
| reported_guild_nsfw?4 7 | ?boolean | Whether the reported guild was marked NSFW |
| reported_guild_content_warning_level?4 7 | ?integer | The guild content warning level |
| reported_guild_content_warning_text?4 7 | ?string | The guild content warning text (at most 200 characters) |
| reported_channel_nsfw_override?4 7 | ?boolean | The NSFW override set on the reported channel itself |
| reported_channel_content_warning_level?4 7 | ?integer | The content warning level set on the channel itself |
| reported_channel_content_warning_text?4 7 | ?string | The content warning text set on the channel itself (at most 200 characters) |
| reported_channel_effective_nsfw?7 8 | ?boolean | Whether the channel was NSFW once the guild setting was applied |
| reported_channel_effective_content_warning_level?7 8 | ?integer | The channel content warning level once the guild setting was applied |
| reported_channel_effective_content_warning_text?7 8 | ?string | The channel content warning text once the guild setting was applied |
| resolved_at9 | ?ISO8601 timestamp | When the report was resolved |
| resolved_by_admin_id9 | ?snowflake | The Admin account that resolved the report |
| public_comment9 | ?string | The comment shown to the reporter (at most 512 characters) |
1 Null for an anonymous Digital Services Act notice, which is filed without a Fluxer account, so every reporter identity field is null exactly when reporter_id is null
2 Resolved from the account when the response is produced, and null when the account can no longer be read
3 Null unless the caller holds report:view:reporter_pii, and null when the reporter supplied no value. For a report filed from an account, reporter_email is the current address of that account, and null when the account no longer exists or has no address. For a Digital Services Act notice it is the verified address the notice was filed with
4 Captured when the report was filed and never updated afterwards
5 The captured effective state when the report recorded one, otherwise the current NSFW state of the reported channel
6 Derived from the captured guild NSFW flag, where true is level 3 and false is level 0. Otherwise it is read from the reported guild, the filing guild, or the channel’s guild
7 Always emitted, so an absent member and a null member mean the same thing
8 Computed when the report was filed by applying the guild setting over the channel setting
9 Null while the report is PENDING and set when it moves to RESOLVED
10 Null on a report filed without a report flow, which includes every report filed before report flows existed
11 Null when reason is null, and the raw reason key when this API does not know the reason
12 Null when reason is null or unknown to this API
13 True on a Digital Services Act notice filed through a report flow, and null on every other report
14 A message a webhook sent has no author account, so its report has a null reported_user_id and null reported user fields, and records the webhook instead. Every webhook field is null on any other report, and a message a bot account sent is reported as that account
15 Read from the webhook when the report was filed, and null when the webhook had already been deleted by then
16 Captured from the account that created the webhook. Null when that account had been deleted by the time the report was filed, while reported_webhook_creator_id still names it. The creator is context for moderators and is not the reported account, so reported_user_id stays null
17 Null when the report names no reported account, which includes a report about a message a webhook sent
18 On an instance with the none tag style the tag of an account that is not a bot is the bare username, with no #0000
For a report in a thread, reported_channel_nsfw, the three reported_channel_effective_ fields, and channel_nsfw of each context entry resolve through the parent channel, as Thread object describes.
Example
Section titled “Example”{ "report_id": "1502771904419102720", "reporter_id": "1483920011884392448", "reporter_tag": "wren#0042", "reporter_email": null, "reported_at": "2026-03-04T18:22:10.441Z", "status": 0, "report_type": 0, "category": "harassment", "reason": "harassment", "reason_label": "Harassment or bullying", "reason_highest_priority": false, "flow": { "revision_hash": "6b1f0c9e2a7d4413", "surface": "in_app", "locale": "de", "steps": [ {"screen_id": "root_message", "screen_title": "Report message", "option_id": "abuse", "option_label": "Abusive or harmful content", "items": []}, {"screen_id": "abuse", "screen_title": "What does it involve?", "option_id": "harassment", "option_label": "Bullying, harassment or stalking", "items": []}, {"screen_id": "harassment", "screen_title": "How is someone being targeted?", "option_id": "harassment_direct", "option_label": "Repeatedly targeting someone with insults or abuse", "items": []} ] }, "reporter_good_faith_confirmed": null, "additional_info": null, "reported_user_id": "1490118377238528000", "reported_user_bot": false, "reported_guild_id": "1471002884199612416", "reported_message_id": "1502771119476146176", "reported_channel_id": "1471002884199612420", "reported_channel_nsfw": false, "reported_guild_nsfw_level": 0, "resolved_at": null, "resolved_by_admin_id": null, "public_comment": null}Report status
Section titled “Report status”| Value | Name | Description |
|---|---|---|
| 0 | PENDING | Report is waiting to be reviewed |
| 1 | RESOLVED | Report has been reviewed and resolved |
Report type
Section titled “Report type”| Value | Name | Description |
|---|---|---|
| 0 | MESSAGE | A message was reported |
| 1 | USER | A user was reported |
| 2 | GUILD | A guild was reported |
Admin report detail object
Section titled “Admin report detail object”The detail object extends the Admin report object with the evidence too large to return in a list page. Get report emits these members, and List reports omits them.
Structure
Section titled “Structure”| Field | Type | Description |
|---|---|---|
| mutual_dm_channel_id1 | ?snowflake | The direct message channel shared by the reporter and the reported account |
| message_context2 | array[report message context object] | The messages captured around the reported content |
| message_responses3 | array[message object] | The current state of the same messages, read live |
| reported_profile_snapshot?4 | ?report profile snapshot object | The reported profile as it was when the report was filed |
| legal_hold_until?5 | ?ISO8601 timestamp | When the legal hold on the report ends |
| legal_hold_reason?5 | ?string | Why the report is held |
1 Set only for a USER report that has both a reporter and a reported account, and null when the two share no direct message channel
2 Empty for a report that captured no message context, which is every user report and every guild report. An entry for which neither the capture nor the report records a channel is left out
3 Resolved when the response is produced, so an edited message differs from its captured entry
4 Always emitted. Null for a report filed before profile snapshots were stored, for a report about a message a webhook sent, and when the stored snapshot cannot be read
5 Always emitted. Null when the report has no hold. Set report legal hold places and clears the hold, and Report retention describes its effect
Report message context object
Section titled “Report message context object”A context entry preserves a message as it was when the report was filed. Later edits or deletions do not change it, and attachment evidence survives deletion of the original.
A message report captures the reported message together with at most 25 messages before it and at most 25 after it, for at most 51 entries. A Digital Services Act notice about a direct message, a group DM, or a guild channel that @everyone cannot view and read the history of captures the reported message alone. A message whose author account no longer existed at capture time is kept under the DeletedUser identity with discriminator 0000 and its original author ID. A message a webhook sent is captured under the name and avatar it was sent with.
Structure
Section titled “Structure”| Field | Type | Description |
|---|---|---|
| id | snowflake | The ID of the message |
| channel_id1 | snowflake | The channel the captured messages were read from |
| channel_nsfw2 | ?boolean | The current NSFW state of that channel |
| channel_content_warning_level?3 4 | ?integer | The channel content warning level |
| channel_content_warning_text?3 4 | ?string | The channel content warning text |
| guild_id5 | ?snowflake | The guild the report is scoped to, or null when the report names none |
| guild_nsfw_level2 | ?integer | The current guild NSFW level |
| guild_nsfw?3 4 | ?boolean | Whether the guild is marked NSFW |
| guild_content_warning_level?3 4 | ?integer | The guild content warning level |
| guild_content_warning_text?3 4 | ?string | The guild content warning text |
| content | string | The captured message content, empty when the message had none |
| timestamp6 | ISO8601 timestamp | When the message was sent |
| attachments7 | array[report message attachment object] | The captured attachment copies |
| author_id8 | snowflake | The author of the message |
| author_username8 | string | The captured author username |
| author_global_name4 | ?string | The display name of the author |
| author_discriminator8 | string | The captured zero-padded four-digit author discriminator |
| author_avatar8 | ?string | The captured author avatar hash, or null when unset |
| webhook_id?3 9 | ?snowflake | The webhook that sent the message |
| author_bot?3 10 | ?boolean | Whether the author account is a bot |
| missing_attachments?3 11 | array[report missing attachment object] | Attachments that could not be copied into the report |
1 The channel of the captured entry, otherwise the reported channel. An entry for which neither records a channel is left out of message_context
2 Read from the current channel or guild, and null when the record can no longer be read
3 Always emitted, so an absent member and a null member mean the same thing
4 Always null, because the capture stores no value for it
5 The reported guild, or the guild the report was filed from, so every entry of one report has the same value
6 Derived from the message ID
7 Fluxer drops an evidence copy that records no file name, resolves to no channel, or receives no download URL, so this array can be shorter than the original
8 For a message a webhook sent, the webhook ID, the name and avatar hash the message was sent with, and the discriminator 0000, as the message object shows the author of a webhook message
9 Null for a message an account sent
10 Read from the author account when the response is produced. Null for a message a webhook sent and for an author account that no longer resolves
11 Empty when every attachment was copied, and on a report filed before missing attachments were recorded. An attachment is listed here when its copy failed or, for a file embedded in the message, when the file was no longer stored
Report message attachment object
Section titled “Report message attachment object”Structure
Section titled “Structure”| Field | Type | Description |
|---|---|---|
| id | snowflake | The ID of the attachment |
| filename | string | The captured file name |
| url12 | string | The download URL for the evidence copy |
| nsfw | ?boolean | Whether the attachment was marked NSFW |
| content_type | ?string | The captured MIME type, or null when unknown |
| width | ?integer | The pixel width, or null for a non-image attachment |
| height | ?integer | The pixel height, or null for a non-image attachment |
| size?3 | ?integer | The size in bytes, or null when unknown |
12 The URL expires after five minutes. Fetch the report again for fresh attachment links
Report missing attachment object
Section titled “Report missing attachment object”An attachment of a captured message that Fluxer could not copy into the report. It has the captured metadata and no download URL.
Structure
Section titled “Structure”| Field | Type | Description |
|---|---|---|
| id | snowflake | The ID of the attachment |
| filename | string | The captured file name |
| nsfw | ?boolean | Whether the attachment was marked NSFW |
| content_type | ?string | The captured MIME type, or null when unknown |
| width | ?integer | The pixel width, or null for a non-image attachment |
| height | ?integer | The pixel height, or null for a non-image attachment |
| size13 | ?integer | The size in bytes, or null when unknown |
13 0 for a file embedded in the message that was no longer stored when the report was filed
Report profile snapshot object
Section titled “Report profile snapshot object”The reported profile as it was when the report was filed. A user report keeps the account, a guild report keeps the guild, and a message report keeps the author account. Each image is a copy Fluxer made when the report was filed, so a later profile change or deletion does not affect it.
Structure
Section titled “Structure”| Field | Type | Description |
|---|---|---|
| captured_at | ISO8601 timestamp | When the snapshot was taken |
| user1 | ?snapshot user object | The reported account |
| member2 | ?snapshot member object | The guild profile of the reported account |
| guild3 | ?snapshot guild object | The reported guild |
1 Null on a guild report
2 Set when the report names a guild the account was a member of, which is a user report with guild_id or a message report in a guild channel
3 Set on a guild report only
Snapshot user object
Section titled “Snapshot user object”Structure
Section titled “Structure”| Field | Type | Description |
|---|---|---|
| id | snowflake | The ID of the account |
| username4 | ?string | The username |
| discriminator4 | ?string | The zero-padded four-digit discriminator |
| global_name4 | ?string | The display name, or null when unset |
| bio4 | ?string | The profile bio, or null when unset |
| pronouns4 | ?string | The pronouns, or null when unset |
| avatar4 | ?snapshot asset object | The avatar, or null when unset |
| banner4 | ?snapshot asset object | The profile banner, or null when unset |
4 Null for an account whose deletion had started when the report was filed, which is kept by ID alone with no member profile
Snapshot member object
Section titled “Snapshot member object”Structure
Section titled “Structure”| Field | Type | Description |
|---|---|---|
| guild_id | snowflake | The guild the profile belongs to |
| nick | ?string | The guild nickname, or null when unset |
| bio | ?string | The guild profile bio, or null when unset |
| pronouns | ?string | The guild profile pronouns, or null when unset |
| joined_at | ?ISO8601 timestamp | When the account joined the guild |
| avatar | ?snapshot asset object | The guild avatar, or null when unset |
| banner | ?snapshot asset object | The guild profile banner, or null when unset |
Snapshot guild object
Section titled “Snapshot guild object”Structure
Section titled “Structure”| Field | Type | Description |
|---|---|---|
| id | snowflake | The ID of the guild |
| name | ?string | The guild name |
| vanity_url_code | ?string | The vanity invite code, or null when unset |
| icon | ?snapshot asset object | The icon, or null when unset |
| banner | ?snapshot asset object | The banner, or null when unset |
| splash | ?snapshot asset object | The invite splash, or null when unset |
Snapshot asset object
Section titled “Snapshot asset object”Structure
Section titled “Structure”| Field | Type | Description |
|---|---|---|
| hash | string | The asset hash when the report was filed |
| url5 | ?string | The download URL for the copy |
5 Expires after five minutes. Null when the image could not be copied into the report, or when no download URL could be made
Example
Section titled “Example”{ "captured_at": "2026-03-04T18:22:10.502Z", "user": { "id": "1490118377238528000", "username": "marlow", "discriminator": "0117", "global_name": "Marlow", "bio": "Ask me about trains", "pronouns": null, "avatar": {"hash": "4be1c7a09d2e3f56", "url": "https://reports.example.com/reports/1502771904419102720/profile/user_avatar/4be1c7a09d2e3f56?X-Amz-Expires=300"}, "banner": null }, "member": { "guild_id": "1471002884199612416", "nick": "Conductor", "bio": null, "pronouns": null, "joined_at": "2026-01-12T09:41:00.000Z", "avatar": null, "banner": null }, "guild": null}Report flow answers object
Section titled “Report flow answers object”The answers a reporter gave in a report flow, described in English whatever locale the reporter saw. Fluxer builds the description from the stored IDs when it produces the response, so the labels follow the current catalogue.
Structure
Section titled “Structure”| Field | Type | Description |
|---|---|---|
| revision_hash | string | The revision hash the reporter’s client sent |
| surface | string | The report flow surface, in_app or dsa |
| locale | ?string | The locale the reporter saw the flow in |
| steps | array[report flow answer step object] | The answered screens in walk order |
Report flow answer step object
Section titled “Report flow answer step object”Structure
Section titled “Structure”| Field | Type | Description |
|---|---|---|
| screen_id | string | The ID of the screen |
| screen_title1 | string | The English title of the screen |
| option_id2 | ?string | The ID of the chosen option |
| option_label1 2 | ?string | The English label of the chosen option |
| items3 | array[report flow answer item object] | The ticked checklist items |
1 The raw ID when the current catalogue no longer has the screen or option
2 Null on a checklist screen and an info screen
3 In checklist order, not the order the reporter ticked them, and empty on a choice screen and an info screen
Report flow answer item object
Section titled “Report flow answer item object”Structure
Section titled “Structure”| Field | Type | Description |
|---|---|---|
| id | string | The ID of the item |
| label | string | The English label of the item, or its raw ID when the current catalogue no longer has it |
Report reason object
Section titled “Report reason object”One entry of the report reason catalogue, as List report reasons returns it.
Structure
Section titled “Structure”| Field | Type | Description |
|---|---|---|
| key | string | The reason key stored on a report |
| label | string | The English label |
| highest_priority | boolean | Whether moderators see reports with this reason first |
| legacy_category_message | string | The category a message report stores |
| legacy_category_user | string | The category a user report stores |
| legacy_category_guild | string | The category a guild report stores |
Example
Section titled “Example”{ "key": "csam", "label": "Child sexual abuse material", "highest_priority": true, "legacy_category_message": "child_safety", "legacy_category_user": "child_safety", "legacy_category_guild": "child_safety"}Report resolution object
Section titled “Report resolution object”A report resolution is the reduced view Update report returns. It has the fields the update writes and nothing else.
Structure
Section titled “Structure”| Field | Type | Description |
|---|---|---|
| report_id | snowflake | The ID of the report |
| status | integer | The report status, always RESOLVED on a successful update |
| resolved_at | ?ISO8601 timestamp | When the report was resolved |
| public_comment | ?string | The comment shown to the reporter, or null when none was supplied |
Example
Section titled “Example”{ "report_id": "1502771904419102720", "status": 1, "resolved_at": "2026-03-05T11:04:53.902Z", "public_comment": "Thanks for the report. We actioned the account."}Report legal hold object
Section titled “Report legal hold object”Structure
Section titled “Structure”| Field | Type | Description |
|---|---|---|
| report_id | snowflake | The ID of the report |
| legal_hold_until | ?ISO8601 timestamp | When the hold ends, or null when the report has no hold |
| legal_hold_reason | ?string | Why the report is held, or null when the report has no hold |
Example
Section titled “Example”{ "report_id": "1502771904419102720", "legal_hold_until": "2027-06-30T00:00:00.000Z", "legal_hold_reason": "Preservation request from a court"}Report retention
Section titled “Report retention”Fluxer deletes a report when its retention period ends, whether it is pending or resolved, together with its stored evidence: the attachment copies, the profile snapshot images, and its search index entry. The reporter’s duplicate-report reservation for it goes too, so the reporter can report the same message, account or guild again.
The retention period is 365 days from when the report was filed, or the number of days in FLUXER_REPORT_RETENTION_DAYS. With FLUXER_RESOLVED_REPORT_RETENTION_DAYS set, a resolved report is deleted that many days after resolved_at when that comes first. A report with a legal hold that ends later is kept until the next run after the hold ends. An evidence copy that a retained report also uses is kept for that report.
The deletion runs once a day in worker. Each run logs one Processed report retention line with the counts it found and deleted and the two periods it used. A report that fails to delete keeps its record and is retried on the next run. Delete report deletes one report straight away by the same rules.
List reports
Section titled “List reports”GET/v1/admin/reportsReturns a page of Admin report objects without message context. Requires report:view.
The operation has two branches. Both read the report search index, and both return total, offset, and limit beside the page. A request that supplies status and no other filter takes the status branch, which lists the reports with that status newest first by reported_at and ignores sort_by and sort_order. Every other request takes the search branch, which applies the supplied filters and sort.
The search branch applies no status filter when status is omitted, so a request with no query string returns reports of every status.
An instance with no search backend returns 403 FEATURE_TEMPORARILY_DISABLED on both branches.
Query parameters
Section titled “Query parameters”| Field | Type | Description |
|---|---|---|
| q?1 | string | Free-text query matched against the searchable report fields (1-1024 characters) |
| status? | pending | resolved | Restrict results to one report status |
| report_type? | message | user | guild | Restrict results to one report type |
| category? | string | Restrict results to one submitted category (1-128 characters) |
| reason? | string | Restrict results to one report reason key (1-64 characters) |
| reporter_id? | snowflake | Restrict results to one reporter |
| reported_user_id? | snowflake | Restrict results to one reported account |
| reported_webhook_id? | snowflake | Restrict results to messages one webhook sent |
| reported_guild_id? | snowflake | Restrict results to one reported guild |
| reported_channel_id? | snowflake | Restrict results to one reported channel |
| guild_context_id? | snowflake | Restrict results to reports filed from within one guild |
| resolved_by_admin_id? | snowflake | Restrict results to one resolving Admin account |
| sort_by?2 | created_at | reported_at | resolved_at | Sort field (default reported_at) |
| sort_order? | asc | desc | Sort direction, where asc is oldest first (default desc) |
| limit? | integer | Maximum reports to return (1-200, default 50) |
| offset?3 | integer | Reports to skip (0-10000, default 0) |
1 Matched against category, additional_info, reported_guild_name, and reported_channel_name only. Omitting it matches every report satisfying the remaining filters
2 created_at orders by the time encoded in the report ID, and reported_at by the submission time stored on the report
3 The next page is requested with a larger offset
Response body
Section titled “Response body”| Field | Type | Description |
|---|---|---|
| reports1 | array[Admin report object] | Reports in this page, without message context |
| total2 | integer | Index hits matching the filters |
| offset | integer | The offset this page was read from |
| limit | integer | The limit this page was read with |
1 An index hit whose report record no longer exists is dropped and the request still succeeds, so a full page can hold fewer entries than limit. Fluxer logs the dropped IDs, and a Refresh search index of reports removes them from the index
2 The index count, which still includes hits whose report record no longer exists
Response
Section titled “Response”| Status | Body | Condition |
|---|---|---|
| 200 | response body | Report page was returned |
| 403 | error response | No search backend is configured for the instance and the request returns FEATURE_TEMPORARILY_DISABLED |
Side effects
Section titled “Side effects”The operation records one Admin audit entry with action search_reports, target type report, and target ID 0 on both branches. The metadata keys are limit, offset, result_count for the reports in this page, and total. The search branch adds sort_by and sort_order. A supplied q adds has_query with the value true, and the query text is not recorded. The supplied filters add status, report_type, category, reason, reported_user_id, reported_webhook_id, reported_guild_id, and reported_channel_id under their own names, reporter_id as reporter_user_id, guild_context_id as context_guild_id, and resolved_by_admin_id as resolved_by_admin_user_id. A 403 records nothing.
Rate limit
Section titled “Rate limit”200 requests per minute for each authenticated user, on the admin:lookup bucket.
List report reasons
Section titled “List report reasons”GET/v1/admin/report-reasonsReturns every report reason a report flow can file a report under, with the category each one stores for each report type. Requires report:view.
The labels are English. The list is the catalogue this API was built with, so an admin client can label and filter a reason without a copy of its own.
Response body
Section titled “Response body”| Field | Type | Description |
|---|---|---|
| reasons | array[report reason object] | Every reason, in catalogue order |
Response
Section titled “Response”| Status | Body | Condition |
|---|---|---|
| 200 | response body | The catalogue was returned |
Side effects
Section titled “Side effects”The operation records one Admin audit entry with action list_report_reasons, target type report, target ID 0, and the metadata key result_count.
Rate limit
Section titled “Rate limit”200 requests per minute for each authenticated user, on the admin:lookup bucket.
Get report
Section titled “Get report”GET/v1/admin/reports/{report_id}Returns one Admin report detail object, which adds the captured message context and the live state of those messages. Requires report:view.
The operation answers even when the report search index is unavailable. Reporter contact fields are redacted here exactly as they are in List reports.
Path parameters
Section titled “Path parameters”| Field | Type | Description |
|---|---|---|
| report_id | snowflake | The ID of the report |
Response
Section titled “Response”| Status | Body | Condition |
|---|---|---|
| 200 | Admin report detail object | Report was returned |
| 404 | error response | Report does not exist and the request returns UNKNOWN_REPORT |
Side effects
Section titled “Side effects”The operation records one Admin audit entry with action get_report, target type report, the report ID as target ID, and metadata keys report_type and status with the integer values of the report. The attachment download URLs are not recorded. A 404 records nothing.
Rate limit
Section titled “Rate limit”200 requests per minute for each authenticated user, on the admin:lookup bucket.
Update report
Section titled “Update report”PATCH/v1/admin/reports/{report_id}Resolves one report and returns a report resolution object. Requires report:resolve.
status is required and resolved is the only value it accepts, so this route changes no other field.
Path parameters
Section titled “Path parameters”| Field | Type | Description |
|---|---|---|
| report_id | snowflake | The ID of the report |
JSON body
Section titled “JSON body”| Field | Type | Description |
|---|---|---|
| status | resolved | The status to move the report to |
| public_comment?1 | string | The comment shown to the reporter (0-512 characters) |
| notify_reporter?2 | boolean | Whether the notice to the reporter includes public_comment (default true) |
| resolution?3 | string | How the report was resolved, one of actioned, no_violation, or duplicate |
1 Stored as null when it is omitted or empty. Otherwise it is stored, and the resolution notice shows it to the reporter unless notify_reporter is false
2 The reporter is notified either way. False sends the generic notice without the comment, and the comment is still stored on the report
3 Optional, so older admin clients that send none still work. It is not stored on the report, not returned by any report route, and not shown to the reporter. It is recorded in the audit entry
The admin panel always sends resolution. Its resolve form has a required Resolution select with three choices: Action taken (actioned), No violation (no_violation), and Duplicate (duplicate). The browser refuses to submit the form without a choice, and the panel checks again on the server: a submission with no choice, or with any other value, is refused with the error “Choose a resolution” and the report stays pending. After a resolve, the panel confirms the choice in its message, such as “Report resolved: No violation”. The report page itself does not show the choice, because no report route returns it. Staff find it in the resolution metadata of the resolve_report entry in the audit log.
Response
Section titled “Response”| Status | Body | Condition |
|---|---|---|
| 200 | report resolution object | Report was resolved |
| 400 | error response | The report is already resolved and the request returns REPORT_ALREADY_RESOLVED |
| 404 | error response | Report does not exist and the request returns UNKNOWN_REPORT |
Side effects
Section titled “Side effects”The report moves to RESOLVED and records resolved_at, resolved_by_admin_id, and the public comment.
Fluxer records one Admin audit entry with target type report, target ID equal to the report ID, and action resolve_report. The metadata is report_id, report_type, notify_reporter, reporter_dm_sent, reporter_email_sent, and reporter_dsa_email_sent, plus resolution when the request sets one. When Fluxer does not attempt a notice, reporter_notice_skipped names the reason: reporter_account_deleted, reporter_report_banned, reporter_lookup_failed, or no_reporter_email.
Fluxer notifies the reporter of every resolution. A reporter with an account receives a system direct message, and an email when the account has an address. A Digital Services Act notice has no reporter account, so its verified address receives a decision email with the report ID, the comment when one is shared, and how to appeal. Nothing is sent when the reporter account is deleted or barred from reporting.
A reporter who does not already have the system channel open receives Channel Create, and every session of the reporter receives Message Create. Fluxer logs a delivery failure, and the request still succeeds.
Rate limit
Section titled “Rate limit”200 requests per minute for each authenticated user, on the admin:lookup bucket.
Set report legal hold
Section titled “Set report legal hold”POST/v1/admin/reports/{report_id}/legal-holdPlaces or clears a legal hold on one report and returns a report legal hold object. Requires report:resolve.
A held report is kept past the end of its retention period until the hold ends, and Delete report refuses it. A hold can be placed on a pending or a resolved report, and a new hold replaces the previous one.
Path parameters
Section titled “Path parameters”| Field | Type | Description |
|---|---|---|
| report_id | snowflake | The ID of the report |
JSON body
Section titled “JSON body”| Field | Type | Description |
|---|---|---|
| legal_hold_until1 | ?ISO8601 timestamp | When the hold ends, or null to clear the hold |
| legal_hold_reason?2 | ?string | Why the report is kept (1-512 characters) |
1 Must be in the future. A time in the past, or a value that is not an ISO 8601 timestamp, returns 400 INVALID_FORM_BODY on legal_hold_until
2 Required to place a hold, and a missing or null reason returns 400 INVALID_FORM_BODY on legal_hold_reason. Ignored when the hold is cleared, which also clears the reason
Response
Section titled “Response”| Status | Body | Condition |
|---|---|---|
| 200 | report legal hold object | The hold was placed or cleared |
| 400 | error response | The end time or the reason is invalid and the request returns INVALID_FORM_BODY |
| 404 | error response | Report does not exist and the request returns UNKNOWN_REPORT |
Side effects
Section titled “Side effects”Fluxer records one Admin audit entry with target type report and the report ID as target ID. Placing a hold records action set_report_legal_hold with the metadata keys report_id, report_type, legal_hold_until, and legal_hold_reason. Clearing a hold records action clear_report_legal_hold with report_id and report_type. Either adds previous_legal_hold_until when the report already had a hold end time stored, including one that has passed. A rejected request records nothing.
Rate limit
Section titled “Rate limit”200 requests per minute for each authenticated user, on the admin:lookup bucket.
Delete report
Section titled “Delete report”DELETE/v1/admin/reports/{report_id}Deletes one report straight away. Requires report:delete, which report:resolve does not include.
This is the deletion report retention runs, without waiting for the retention period. It removes the report record with its captured message context and profile snapshot, its stored evidence copies, its search index entry, and the reporter’s duplicate-report reservation for it. An evidence copy that another report also uses is kept for that report. A pending or a resolved report can be deleted, and the reporter is not told.
Path parameters
Section titled “Path parameters”| Field | Type | Description |
|---|---|---|
| report_id | snowflake | The ID of the report |
Response
Section titled “Response”| Status | Body | Condition |
|---|---|---|
| 204 | empty | The report was deleted |
| 404 | error response | Report does not exist and the request returns UNKNOWN_REPORT |
| 409 | error response | The report has a legal hold that ends later and the request returns REPORT_UNDER_LEGAL_HOLD |
Side effects
Section titled “Side effects”Fluxer records one Admin audit entry with action delete_report, target type report, and the report ID as target ID. The metadata keys are report_id, report_type, status, objects_deleted for the evidence copies removed, and shared_objects_kept for the copies kept because another report uses them. A refused request records nothing.
Rate limit
Section titled “Rate limit”200 requests per minute for each authenticated user, on the admin:lookup bucket.