--- # SPDX-License-Identifier: AGPL-3.0-or-later title: Search indexes description: Administrative search index rebuilds, index names, and rebuild progress. --- import RouteHeader from '@/components/RouteHeader.astro'; These routes rebuild search indexes from current data and report progress. Rebuilds appear in [Jobs](/admin-api/jobs/) as `refreshSearchIndex`. Both routes require the [ACL](/admin-api/#acl-evaluation) `guild:lookup`. ## Search index names `index_name` is one of the following values. A value outside the set fails path validation. | Value | Scope | Description | | --- | --- | --- | | guilds | Instance-wide | Every guild, backing Admin guild search | | users | Instance-wide | Every account, backing Admin user search | | reports | Instance-wide | Every report, backing Admin report search | | audit_logs | Instance-wide | Every Admin audit entry, backing Admin audit search | | discovery1 | Instance-wide | Discovery metadata written onto the guild documents of approved listings | | channel_messages2 | One guild | Messages of every channel in one guild, requiring `guild_id` | | guild_members3 | One guild | Members of one guild, requiring `guild_id` | | favorite_memes4 | One user | Favourited [memes](/http-api/memes/) of one user, requiring `user_id` | 1 Refreshes the description, category, primary language and tags of approved discovery listings without removing guilds from search 2 Clears the guild's message index and queues `indexChannelMessages` jobs for its channels. Completion of the parent job does not mean those jobs have finished 3 Clears the guild's member index first and updates `members_indexed_at` on completion 4 Rebuilding this index is not supported. The request is accepted, but the job fails without reporting progress Every instance-wide name other than `discovery` deletes its documents before the first batch is written, so search over that index is incomplete for the whole run. A `discovery` rebuild instead updates the existing guild documents in place, so those documents stay searchable for the whole run. ## Search index refresh object A receipt for one queued rebuild. ### Structure | Field | Type | Description | | --- | --- | --- | | success | boolean | Always true | | job_id1 | string | The ID of the queued rebuild, used to read its progress | 1 The value is a [snowflake](/snowflakes/) rendered as a string. It addresses the progress record that [Get search index refresh](#get-search-index-refresh) reads. It differs from the `job_id` of the [Jobs](/admin-api/jobs/) ledger entry for the same rebuild, and appears there only inside that entry's `payload` ### Example ```json { "success": true, "job_id": "1501314428688998182" } ``` ## Search index refresh progress object Progress for one queued rebuild. The object shape is selected by `status`. ### Not found structure | Field | Type | Description | | --- | --- | --- | | status | string | Always `not_found` | ### Progress structure | Field | Type | Description | | --- | --- | --- | | status | string | One of `in_progress`, `completed`, or `failed` | | index_type | string | The [search index name](#search-index-names) being rebuilt | | total?1 | number | The number of documents expected, present while the rebuild reports progress and once it completes | | indexed?2 | number | The number of documents written so far | | started_at?3 | ISO8601 timestamp | The time the rebuild last reported progress | | completed_at? | ISO8601 timestamp | The time the rebuild finished, present only when `status` is `completed` | | failed_at? | ISO8601 timestamp | The time the rebuild failed, present only when `status` is `failed` | | error? | string | The failure text, present only when `status` is `failed` | 1 `total` is the same value as `indexed` while the rebuild runs and becomes the real total on completion. The `discovery` rebuild reports the approved listing count from its first batch onwards 2 Each document the rebuild writes counts as one. A `channel_messages` rebuild counts the channels it queued 3 Rewritten on every progress report, so its value moves forward while the rebuild runs A failed result includes `status`, `index_type`, `error` and `failed_at`, but neither `total` nor `indexed`. ### Example ```json { "status": "in_progress", "index_type": "guilds", "total": 3000, "indexed": 3000, "started_at": "2026-08-31T09:12:44.118Z" } ``` ## Refresh search index Queues a rebuild of the named index. Requires `guild:lookup`. Returns a [search index refresh](#search-index-refresh-object) object on success. ### Path parameters | Field | Type | Description | | --- | --- | --- | | index_name | string | The [search index name](#search-index-names) to rebuild | ### JSON body Every field is optional. Fluxer reads an absent or empty body as an empty object, so an instance-wide rebuild can send no body at all. A body that is not parseable JSON returns 400 `INVALID_FORM_BODY` with the validation code `INVALID_FORMAT` at the `body` path. | Field | Type | Description | | --- | --- | --- | | guild_id?1 | snowflake | The ID of the guild whose documents in the index are rebuilt | | user_id?2 | snowflake | The ID of the user whose documents in the index are rebuilt | 1 Required by `channel_messages` and `guild_members`. Every other index name ignores it 2 Required by `favorite_memes`. Every other index name ignores it Fluxer records both values on the audit entry whenever they are supplied, including on an index name that ignores them. ### Response | Status | Body | Condition | | --- | --- | --- | | 200 | [search index refresh](#search-index-refresh-object) object | The rebuild was queued | | 400 | [error response](/admin-api/#error-response) | `INVALID_FORM_BODY` because the scope ID the index name requires is missing, or the body is not parseable JSON | | 403 | [error response](/admin-api/#error-response) | `MISSING_PERMISSIONS` without `admin:authenticate`, or `MISSING_ACL` without `guild:lookup` | | 500 | [error response](/admin-api/#error-response) | The job could not be queued | A missing scope ID names `guild_id` or `user_id` in `errors`. Fluxer queues no job and records no audit entry for that failure. :::caution[The rebuild runs after the response] Search results over the named index can be incomplete until the rebuild finishes. ::: ### Side effects A guild-scoped rebuild for an unknown guild produces an empty index. A failed rebuild is not retried automatically. Fluxer records one Admin audit entry with the action `queue_refresh_index`, the target type `search_index`, and the target ID `0`. Its metadata has `index_type`, `job_id`, and whichever of `guild_id` and `user_id` the request supplied. Fluxer emits no Gateway Dispatch. ### Rate limit 200 requests per minute for each authenticated user, on the `admin:lookup` bucket. ## Get search index refresh Returns the [search index refresh progress](#search-index-refresh-progress-object) object for one queued rebuild. Requires `guild:lookup`. ### Path parameters | Field | Type | Description | | --- | --- | --- | | job_id1 | string | The identifier returned by [Refresh search index](#refresh-search-index) | 1 The value is bounded at 1 to 128 characters after Fluxer removes every form feed (U+000C) and right-to-left override (U+202E) character and trims whitespace from both ends. It need not be a snowflake ### Response | Status | Body | Condition | | --- | --- | --- | | 2001 | [search index refresh progress](#search-index-refresh-progress-object) object | A progress record was returned, including the not-found shape | | 403 | [error response](/admin-api/#error-response) | `MISSING_PERMISSIONS` without `admin:authenticate`, or `MISSING_ACL` without `guild:lookup` | 1 An unknown identifier answers 200 with `status` set to `not_found`, which is also the answer for an expired record and for a rebuild that failed before writing its first record :::note[Progress expires after one hour] Each write of the progress record renews a one-hour lifetime, so a completed or failed outcome stays readable for one hour after its final update. ::: ### Side effects The operation records no [Admin audit entry](/admin-api/#admin-audit-entry-object). ### Rate limit 200 requests per minute for each authenticated user, on the `admin:lookup` bucket.