Skip to content
Fluxer API

Admin discovery

Admin discovery is the review side of the public guild directory. An Admin decides the application a guild manager submits, reads and edits the approved listing, moves it between categories, and removes the guild from the directory. A guild has at most one application, and the public Discovery resource drives the same lifecycle from the guild’s side.

Every operation except Remove discovery listing requires discovery:review, which covers the four reads, Review discovery application, Move discovery listings to a category, and Update discovery listing. Remove discovery listing requires discovery:remove instead. Neither implies the other.

No operation here reads X-Audit-Log-Reason or records an Admin audit entry. An operation that stores a reason takes it in its request body.

A guild’s submitted application, together with the guild details Fluxer resolves at request time.

FieldTypeDescription
guild_idsnowflakeGuild that applied to discovery
guild_name1stringCurrent guild name
guild_icon1?stringCurrent guild icon hash, or null when the guild has none
guild_owner_id1snowflakeCurrent guild owner
guild_owner_username2?stringUsername of the owner
guild_owner_global_name2?stringDisplay name of the owner, or null when unset
guild_owner_discriminator2 3?stringDiscriminator of the owner
guild_member_count1 4integerThe member count on the guild record
guild_nsfw_level1?integerCurrent NSFW level of the guild
guild_features1 5array[string]Current guild features
descriptionstringListing description of 10 through 300 characters
category_type6integerDiscovery category the listing is filed under
primary_language7?stringSupported primary language code
custom_tags6 8array[string]Normalised custom tags of the listing
applied_atISO8601 timestampTime at which the guild applied

1 Resolved from the guild at request time. A guild that can no longer be resolved yields the literal name (unknown guild), a null icon, the owner ID 0, a member count of 0, a null NSFW level, an empty feature array, and null for all three owner name fields

2 Read from the owner account, so it is null when the guild resolved but the owner account did not

3 Rendered as four digits with leading zeroes

4 The count stored on the guild record, so it is approximate

5 An approved application has the discoverable feature here

6 A stored null reads as 0 for the category and as an empty array for the tags

7 A stored null reads as en-US, so this read does not produce null

8 Stored already trimmed, lowercased, and whitespace collapsed, so a tag does not round-trip in the casing it was submitted with

{
"guild_id": "1478812292088791040",
"guild_name": "Example Guild",
"guild_icon": "a1b2c3d4e5f60718293a4b5c6d7e8f90",
"guild_owner_id": "1478812292088791041",
"guild_owner_username": "example",
"guild_owner_global_name": "Example",
"guild_owner_discriminator": "0042",
"guild_member_count": 1204,
"guild_nsfw_level": 0,
"guild_features": ["COMMUNITY"],
"description": "A place to talk about building things.",
"category_type": 3,
"primary_language": "en-US",
"custom_tags": ["makers", "diy"],
"applied_at": "2026-08-19T14:03:55.000Z"
}

An approved listing. It has every field of the Admin pending application object with the same meaning, plus the field below.

FieldTypeDescription
approved_at1?ISO8601 timestampTime at which the application was approved

1 The review time of the application, so a guild approved automatically on submission has its submission time here

This is the discovery application object of the public Discovery resource. Every write on this page answers with it, so a client re-reads the listing after a write to render the enriched guild fields.

FieldTypeDescription
guild_idsnowflakeGuild the application belongs to
guild_nsfw_level?1?integerNSFW level of the guild
statusstringDiscovery application status
descriptionstringThe description shown on the listing
category_typeintegerDiscovery category the listing is filed under
primary_language?stringSupported primary language code
custom_tagsarray[string]Normalised custom tags of the listing
applied_atISO8601 timestampTime at which the guild applied
reviewed_at2?ISO8601 timestampTime at which the application was approved or rejected, or null while it is pending
review_reason3?stringReason recorded with the approval or rejection, or null
removed_at4?ISO8601 timestampTime at which an approved listing was removed, or null
removal_reason4?stringReason recorded with the removal, or null

1 No route on this page populates it. Read the level from the Admin pending application object or the guild object instead

2 An application approved automatically on submission has its submission time here

3 Null for an approval that supplied no reason and for an automatic approval. A rejection always has one

4 Both fields are set only by Remove discovery listing

{
"guild_id": "1478812292088791040",
"status": "approved",
"description": "A place to talk about building things.",
"category_type": 3,
"primary_language": "en-US",
"custom_tags": ["makers", "diy"],
"applied_at": "2026-08-19T14:03:55.000Z",
"reviewed_at": "2026-08-20T09:11:02.000Z",
"review_reason": null,
"removed_at": null,
"removal_reason": null
}

The application records the Admin that approved, rejected, or removed it. No response on this page exposes that value.

Each release ships a fixed category set, and no Admin operation changes it. See discovery categories for the set.

Every category_type and category_id here is an integer of 0 through 8. A value outside that range fails path, query, or body validation.

GET/v1/admin/discovery/applications

Returns every pending application as an array of Admin pending application objects. Requires discovery:review.

Applications arrive in storage order, keyed by application time and then by guild ID. That direction is not specified, so a client that needs a stable order sorts the array itself. The response is a bare array, and the operation accepts no cursor and no limit.

A guild approved automatically on submission never appears here. An application whose stored record can no longer be read is dropped from the array. The request still succeeds.

StatusBodyCondition
200array[Admin pending application object]Pending applications were returned

30 requests per 10 seconds for each authenticated user, on the discovery:admin:list bucket.

PATCH/v1/admin/discovery/applications/{guild_id}

Approves or rejects a pending application and returns the updated discovery application object. Requires discovery:review.

FieldTypeDescription
guild_idsnowflakeGuild that applied to discovery

status is the decision, and the constraint on reason depends on which one it is.

FieldTypeDescription
status1approved | rejectedDecision to apply
reason2 3stringReason stored on the application as review_reason (at most 500 characters)

1 A value outside the two listed fails body validation. Neither removed nor pending is accepted

2 Optional when status is approved, and omitting it stores null. An empty string fails body validation with 400 INVALID_FORM_BODY

3 Required and at least one character when status is rejected, so a rejection without a reason fails body validation

StatusBodyCondition
200discovery application objectDecision was applied
404error responseThe guild holds no application, returned as DISCOVERY_APPLICATION_NOT_FOUND
409error responseThe application is not pending, returned as DISCOVERY_APPLICATION_ALREADY_REVIEWED

An approval moves the application to approved and records the review time, the reviewing Admin, and the supplied reason. It adds the discoverable feature to the guild and indexes the listing, so the guild appears in Search discovery guilds. Guild Update fires to every session that can observe the guild. Indexing is skipped on an instance with no search backend configured, and the approval still succeeds.

Fluxer moves a rejected application to rejected and records the review time, the reviewing Admin, and the required reason. It leaves every guild field as it is and emits no Gateway Dispatch.

An approval whose guild can no longer be resolved still succeeds. Fluxer skips the feature grant and the Dispatch.

20 requests per 10 seconds for each authenticated user, on the discovery:admin:action bucket.

GET/v1/admin/discovery/categories

Returns the fixed discovery category set as an array of discovery category objects, in ascending ID order. Requires discovery:review.

It reports the same set on every instance running the same release and has no listing counts. Names are the release’s display names and are not localised.

StatusBodyCondition
200array[discovery category object]Categories were returned

30 requests per 10 seconds for each authenticated user, on the discovery:admin:list bucket.

GET/v1/admin/discovery/categories/{category_id}/listings

Returns an offset page of the approved listings filed under one category, most members first, as an array of Admin discovery listing objects. Requires discovery:review.

FieldTypeDescription
category_idintegerDiscovery category of 0 through 8
FieldTypeDescription
limit?integerListings to return (1-100, default 50)
offset?1integerListings to skip (0-10000, default 0)

1 Applied after the category filter and the member sort, so raise it to page a category

A rebuild of the discovery search index does not change what it answers. It reports no total, so a page shorter than limit is the only end-of-category signal. A listing whose guild could not be resolved sorts as if it had no members and lands at the end.

StatusBodyCondition
200array[Admin discovery listing object]The page was returned

30 requests per 10 seconds for each authenticated user, on the discovery:admin:list bucket.

GET/v1/admin/discovery/listings

Returns every approved listing as an array of Admin discovery listing objects. Requires discovery:review.

Listings arrive in the same unspecified storage order as List discovery applications. The response is a bare array, and the operation accepts no cursor and no limit. A pending, rejected, or removed application is never returned.

StatusBodyCondition
200array[Admin discovery listing object]Approved listings were returned

30 requests per 10 seconds for each authenticated user, on the discovery:admin:list bucket.

PATCH/v1/admin/discovery/listings

Files every named guild under one discovery category and reports how many moved. Requires discovery:review.

FieldTypeDescription
guild_ids1array[snowflake]Guilds to move, 1 through 100 entries
category_typeintegerDiscovery category of 0 through 8 to file every named guild under

1 Duplicate entries are collapsed before the move, so a guild named twice is attempted once and counted once

FieldTypeDescription
updatedintegerNumber of distinct guilds that were moved
failed_guild_ids1array[snowflake]Distinct guilds that were not moved

1 A guild lands here when it holds no application, when its application is rejected or removed, or when the write failed. The response does not say which, so retry the guild through Update discovery listing to read the error

StatusBodyCondition
200response bodyThe batch ran, whether or not every guild moved

Repeating the request is safe. A pending application moves on the same terms as an approved one, so this operation can refile a guild that is still awaiting review.

A move replaces the application’s category_type and preserves its description, language, tags, status, and timestamps. A moved listing that is already approved appears under the new category in the next public search. No guild field changes and no Gateway Dispatch is emitted.

20 requests per 10 seconds for each authenticated user, on the discovery:admin:action bucket.

PATCH/v1/admin/discovery/listings/{guild_id}

Updates the stored listing of one guild and returns the updated discovery application object. Requires discovery:review.

FieldTypeDescription
guild_id1snowflakeGuild whose application is edited

1 Despite the route path, a pending application is accepted as well as an approved listing, which lets an Admin correct the wording before approving it

Every member is optional. An omitted member preserves the stored value, and an empty object is accepted and changes nothing.

FieldTypeDescription
description?1stringListing description of 10 through 300 characters
category_type?integerDiscovery category of 0 through 8
primary_language?2stringSupported primary language code
custom_tags?3 4array[string]Up to 10 custom tags

1 A supplied value is scanned against the instance content blocklists before the stored application is read, so a match returns 403 CONTENT_BLOCKED even when the guild holds no application. The scan covers banned phrases and banned URLs and domains found in the text

2 A code outside the supported set fails body validation. A language is always stored, so the listing cannot be returned to having none

3 A supplied array replaces the stored tags outright, so an empty array clears every tag

4 Each entry is 2 through 30 characters both as submitted and after normalisation. An entry that fails that bound or the character rule fails body validation against its own index, and duplicate normalised values collapse to the first occurrence

StatusBodyCondition
200discovery application objectListing was updated, or the submitted values already matched the stored ones
403error responseThe description matches a content blocklist, returned as CONTENT_BLOCKED
404error responseThe guild holds no application, returned as DISCOVERY_APPLICATION_NOT_FOUND
409error responseThe stored application is rejected or removed, returned as DISCOVERY_APPLICATION_ALREADY_REVIEWED

The supplied members update the application while preserving its status, submission time, review time, review reason, and removal fields. Editing an approved listing does not return it to review. The new copy is visible in the next public search. Editing a pending application changes nothing a public reader can see.

No guild field changes, so no Guild Update fires.

20 requests per 10 seconds for each authenticated user, on the discovery:admin:action bucket.

DELETE/v1/admin/discovery/listings/{guild_id}

Removes an approved listing from discovery, strips the guild’s discoverable feature, and returns the updated discovery application object. Requires discovery:remove.

FieldTypeDescription
guild_idsnowflakeThe guild whose listing is removed

The operation takes a required body even though it is a DELETE, so a request without one fails body validation.

FieldTypeDescription
reasonstringReason stored on the application as removal_reason, 1 through 500 characters
StatusBodyCondition
200discovery application objectListing was removed
4001error responseThe application is not approved, returned as DISCOVERY_NOT_DISCOVERABLE
404error responseThe guild holds no application, returned as DISCOVERY_APPLICATION_NOT_FOUND

1 A pending application is refused this way, so rejecting it through Review discovery application is the only way to close it

The application moves to removed and records the removal time, the removing Admin, and the required reason. The discoverable feature is removed from the guild, the guild stops appearing in Search discovery guilds, and Guild Update fires to every session that can observe the guild.

A removal whose guild can no longer be resolved still succeeds. Fluxer skips the feature strip and the Dispatch.

20 requests per 10 seconds for each authenticated user, on the discovery:admin:action bucket.