Skip to content
Fluxer API

Search

Message search finds indexed messages that match a text query and filters. One request can search a channel, a guild, your direct messages or several of these.

A message matches the text query only when it has every word of it. How words and typos match depends on the instance's search backend (Elasticsearch or Meilisearch), but filters always match exactly.

One page of matching messages.

FieldTypeDescription
messages1array[message object]The matching messages on the page
channelsarray[channel object]The channels the returned messages belong to
total2integerThe number of messages matching the query
hits_per_pageintegerThe page size that was applied
pageintegerThe page number that was applied
cursor?array[string]Not used for paging
threads?3array[thread object]The threads that contain a returned message
members?3array[thread member object]Your thread member object for each of those threads you joined

1 Messages have no referenced_message field

2 In a channel context without READ_MESSAGE_HISTORY, this is the number of messages in messages

3 Present only when a returned message is in a thread and the request is not a single channel search

Fluxer returns this object with status 200 when a channel in the search isn't indexed yet or its index is out of date. Fluxer starts indexing it, and you can retry the same request later to get results. Check for indexing to tell this object apart from a result. In the all_guilds, all and open_dms_and_all_guilds scopes, this happens when any guild channel you can read needs indexing, even one you left out of channel_ids.

FieldTypeDescription
indexingbooleanAlways true
ValueDescription
currentThe guild in context_guild_id, or the channel in context_channel_id when no guild is given
open_dmsYour open direct message and group direct message channels
all_dmsEvery direct message and group direct message channel you are a recipient of
all_guildsEvery guild you are a member of
allAll guilds plus all_dms
open_dms_and_all_guildsAll guilds plus open_dms

A bot can only use current, and any other value returns 400 INVALID_FORM_BODY with the field code BOT_SEARCH_SCOPE_UNAVAILABLE on scope.

To search members, communities or threads, see Guild member search, Discovery and Search threads.

ValueDescription
userAn ordinary user account
botA bot account
webhookA webhook
ValueDescription
imageHas an attachment with an image/ media type
soundHas an attachment with an audio/ media type
videoHas an attachment with a video/ media type
fileHas at least one attachment
stickerHas at least one sticker
embedHas at least one preview or rich embed
linkHas an HTTP or HTTPS URL in its text
pollAccepted but matches nothing
snapshotIs a forward
ValueDescription
imageAn image preview embed
videoA video preview embed
soundAccepted but matches nothing. Use the sound content type
articleAn article or webpage preview embed
ValueDescription
timestampCreation time
relevance1The search backend's own order

1 sort_order doesn't apply, and on Elasticsearch this is the same as timestamp with desc

ValueDescription
ascOldest first
descNewest first
POST/v1/search/messagesBot

Searches indexed messages in the resolved scope. Returns a message search result object, or a search indexing object when an index isn't ready.

A guild search only includes channels where you have VIEW_CHANNEL and READ_MESSAGE_HISTORY. To search a single guild channel through context_channel_id, you need VIEW_CHANNEL, and without READ_MESSAGE_HISTORY you only get messages after the guild's history cutoff.

Threads are only searched for bots and for sessions with the channel_threads client capability. The same applies to a thread, forum or media channel in channel_ids.

Every field is optional, but the default current scope needs context_guild_id or context_channel_id. Without either, it returns 400 with the field code CONTEXT_CHANNEL_OR_GUILD_ID_REQUIRED.

FieldTypeDescription
scope?stringSearch scope (default current)
context_channel_id?snowflakeThe ID of the channel to search
context_guild_id?snowflakeThe ID of the guild to search
channel_ids?1array[snowflake]The channel IDs to narrow the scope to (at most 500)
channel_id?1array[snowflake]An alias of channel_ids (at most 500)
hits_per_page?integerThe number of messages on each page (1-25, default 25)
page?integerThe page number (1-400, default 1)
cursor?array[string]Leave this out. Outside a channel context, a non-empty value returns the first page
min_id?2snowflakeThe lowest message ID to match, exclusive
max_id?2snowflakeThe highest message ID to match, exclusive
content?3stringThe free-text query (1-1024 characters)
contents?3array[string]Alternative free-text queries (at most 100, 1-1024 characters each)
exact_phrases?4array[string]Phrases that must all match (at most 10, 1-1024 characters each)
exclude_channel_id?array[snowflake]Channel IDs to exclude (at most 500)
author_id?array[snowflake]Author user IDs, any of which can match (at most 100)
exclude_author_id?array[snowflake]Author user IDs to exclude (at most 100)
author_type?array[string]Author types, any of which can match (at most 20)
exclude_author_type?array[string]Author types to exclude (at most 20)
mentions?array[snowflake]User IDs that must all be mentioned (at most 100)
exclude_mentions?array[snowflake]User IDs, any of which excludes a message (at most 100)
mention_everyone?booleanWhether a matching message has an everyone mention
pinned?booleanWhether a matching message is pinned
has?array[string]Content types that must all be present (at most 20)
exclude_has?array[string]Content types that can't be present (at most 20)
embed_type?array[string]Embed types that must all be present (at most 20)
exclude_embed_type?array[string]Embed types to exclude (at most 20)
embed_provider?5array[string]Embed provider names that must all be present (at most 50, 1-256 characters each)
exclude_embed_provider?5array[string]Embed provider names to exclude (at most 50, 1-256 characters each)
link_hostname?5array[string]Hostnames that must all be present (at most 100, 1-255 characters each)
exclude_link_hostname?5array[string]Hostnames to exclude (at most 100, 1-255 characters each)
attachment_filename?5array[string]Filenames that must all be present (at most 100, 1-1024 characters each)
exclude_attachment_filename?5array[string]Filenames to exclude (at most 100, 1-1024 characters each)
attachment_extension?6array[string]Extensions that must all be present (at most 50, 1-32 characters each)
exclude_attachment_extension?6array[string]Extensions to exclude (at most 50, 1-32 characters each)
sort_by?stringSearch sort field (default timestamp)
sort_order?stringSearch sort order (default desc)
include_nsfw?7booleanWhether age-restricted channels can give results (default false)

1 A channel context ignores them

2 On Meilisearch, the comparison uses the second the ID was created in

3 Matches message text and embed text. On Elasticsearch, contents replaces content when both are supplied

4 Terms must appear adjacent and in order

5 Compared exactly and case-sensitively

6 Write extensions in lowercase without the dot. Only the part after the last dot of a filename counts, and only when it has 1-10 characters

7 Ignored unless you are 18 or older. Bots always count as 18 or older

Every channel in channel_ids must be in the scope. A channel from another guild returns 400 with the field code ALL_CHANNELS_MUST_BELONG_TO_GUILD, and any other channel outside the scope returns 403 MISSING_PERMISSIONS.

StatusBodyCondition
200message search result object | search indexing objectThe search completed, or an index isn't ready
400error responseINVALID_FORM_BODY for a bad scope, a channel from another guild or no context
403error responseFEATURE_TEMPORARILY_DISABLED when the instance has no search backend
403error responseNSFW_CONTENT_AGE_RESTRICTED when the context is age restricted and you are not old enough
403error responseCONTENT_BLOCKED when a search string matches the instance blocklist

The rate limit is 20 requests per 10 seconds, on the search:messages bucket.