Message Resource
Messages are the core of Discord. They are the primary way users communicate with each other, and they can contain text, images, and other media. Embeddable content, such as polls, system messages, and calls are also represented as messages.
Message Object
A message sent in a channel within Discord.
Message Structure
Field | Type | Description |
---|---|---|
id | snowflake | The ID of the message |
channel_id | snowflake | The ID of the channel the message was sent in |
author 1 | partial user object | The author of the message |
content 2 | string | Contents of the message |
timestamp | ISO8601 timestamp | When this message was sent |
edited_timestamp | ?ISO8601 timestamp | when this message was last edited |
tts | boolean | Whether this message will be read out by TTS |
mention_everyone | boolean | Whether this message mentions everyone |
mentions | array[user object] | Users specifically mentioned in the message |
mention_roles | array[snowflake] | Roles specifically mentioned in this message |
mention_channels? 3 | array[partial channel object] | Channels specifically mentioned in this message |
attachments 2 | array[attachment object] | The attached files |
embeds 2 | array[embed object] | Content embedded in the message |
reactions? | array[reaction object] | Reactions on the message |
nonce? | integer | string | The message's nonce, used for message deduplication |
pinned | boolean | Whether this message is pinned |
webhook_id? | snowflake | The ID of the webhook that send the message |
type | integer | The type of message |
activity? | message activity object | The rich presence activity the author is inviting users to |
application? | integration application object | The application of the message's rich presence activity |
application_id? | snowflake | The ID of the application; only send for interaction responses |
flags? | integer | The message's flags |
message_reference? 4 | message reference object | The source of a crosspost, snapshot, channel follow add, pin, or reply message |
referenced_message? 5 4 | ?message object | The message associated with the message_reference |
message_snapshots? 4 | array[message snapshot object] | The partial message snapshot associated with the message_reference |
call? | message call object | The private channel call that prompted this message |
interaction? (deprecated) | message interaction object | The interaction the message is responding to |
interaction_metadata? | message interaction metadata object | The interaction the message originated from |
thread? | channel object | The thread that was started from this message, with the member key representing thread member data |
role_subscription_data? | message role subscription object | The role subscription purchase or renewal that prompted this message |
purchase_notification? | message purchase notification object | The guild purchase that prompted this message |
gift_info | message gift info object | Information on the gift that prompted this message |
components? 2 | array[message component object] | The message's components (e.g. buttons, select menus) |
sticker_items? | array[sticker item object] | The message's sticker items |
stickers? | array[sticker object] | Extra rich information for the message's sticker items; only available in some contexts |
poll? 2 | poll object | A poll! |
changelog_id? | snowflake | The ID of the changelog that prompted this message |
1 The author
object follows the structure of the user object, but may not be a valid user in the case where the message is generated by a webhook; you can recognize this by checking for the webhook_id
key on the message object. In these cases, the below notice about the additional member
keys does not apply as webhooks are not guild members.
2 Users must configure (or, in the case of bots, be approved for) the MESSAGE_CONTENT
intent to receive non-empty values for these fields in most situations.
3 Not all channel mentions in a message will appear in mention_channels
. Only textual channels that are visible to everyone in a lurkable guild will ever be included. Only crossposted messages (via Channel Following) currently include mention_channels
at all. If no mentions in the message meet these requirements, this field will not be sent.
4 See the message reference types for more information on which message references have which fields.
5 his field is only returned for messages with a type
of REPLY
, THREAD_STARTER_MESSAGE
, or CONTEXT_MENU_COMMAND
. If the message is one of these but the referenced_message
field is not present, the backend did not attempt to fetch the message, so its state is unknown. If the field exists but is null
, the referenced message was deleted.
Message Type
Value | Name | Description | Rendered Content | Deletable |
---|---|---|---|---|
0 | DEFAULT | A default message (see below) | "{content}" | true |
1 | RECIPIENT_ADD | A message sent when a user is added to a group DM or thread | "{author} added {mentions[0]} to the {group/thread}." | false |
2 | RECIPIENT_REMOVE | A message sent when a user is removed from a group DM or thread | "{author} removed {mentions[0]} from the {group/thread}." | false |
3 | CALL | A message sent when a user creates a call in a private channel | participated ? "{author} started a call{ended ? " that lasted {duration}" : " — Join the call"}." : "You missed a call from {author} that lasted {duration}." | false |
4 | CHANNEL_NAME_CHANGE | A message sent when a group DM or thread's name is changed | "{author} changed the {is_forum ? "post title" : "channel name"}: {content}" | false |
5 | CHANNEL_ICON_CHANGE | A message sent when a group DM's icon is changed | "{author} changed the channel icon." | false |
6 | CHANNEL_PINNED_MESSAGE | A message sent when a message is pinned in a channel | "{author} pinned a message to this channel." | true |
7 | USER_JOIN | A message sent when a user joins a guild | See user join message type, obtained via the formula timestamp_ms % 13 | true |
8 | PREMIUM_GUILD_SUBSCRIPTION | A message sent when a user subscribes to (boosts) a guild | "{author} just boosted the server{content ? " {content} times"}!" | true |
9 | PREMIUM_GUILD_SUBSCRIPTION_TIER_1 | A message sent when a user subscribes to (boosts) a guild to tier 1 | "{author} just boosted the server{content ? " {content} times"}! {guild} has achieved Level 1!" | true |
10 | PREMIUM_GUILD_SUBSCRIPTION_TIER_2 | A message sent when a user subscribes to (boosts) a guild to tier 2 | "{author} just boosted the server{content ? " {content} times"}! {guild} has achieved Level 2!" | true |
11 | PREMIUM_GUILD_SUBSCRIPTION_TIER_3 | A message sent when a user subscribes to (boosts) a guild to tier 3 | "{author} just boosted the server{content ? " {content} times"}! {guild} has achieved Level 3!" | true |
12 | CHANNEL_FOLLOW_ADD | A message sent when a news channel is followed | "{author} has added {content} to this channel. Its most important updates will show up here." | true |
14 | GUILD_DISCOVERY_DISQUALIFIED | A message sent when a guild is disqualified from discovery | "This server has been removed from Server Discovery because it no longer passes all the requirements. Check Server Settings for more details." | true |
15 | GUILD_DISCOVERY_REQUALIFIED | A message sent when a guild requalifies for discovery | "This server is eligible for Server Discovery again and has been automatically relisted!" | true |
16 | GUILD_DISCOVERY_GRACE_PERIOD_INITIAL_WARNING | A message sent when a guild has failed discovery requirements for a week | "This server has failed Discovery activity requirements for 1 week. If this server fails for 4 weeks in a row, it will be automatically removed from Discovery." | true |
17 | GUILD_DISCOVERY_GRACE_PERIOD_FINAL_WARNING | A message sent when a guild has failed discovery requirements for 3 weeks | "This server has failed Discovery activity requirements for 3 weeks in a row. If this server fails for 1 more week, it will be removed from Discovery." | true |
18 | THREAD_CREATED | A message sent when a thread is created | "{author} started a thread: {content}. See all threads." | true |
19 | REPLY | A message sent when a user replies to a message | "{content}" | true |
20 | CHAT_INPUT_COMMAND | A message sent when a user uses a slash command | "{content}" | true |
21 | THREAD_STARTER_MESSAGE | A message sent when a thread starter message is added to a thread | "{referenced_message?.content}" ?? "Sorry, we couldn't load the first message in this thread" | false |
22 | GUILD_INVITE_REMINDER | A message sent to remind users to invite friends to a guild | "Wondering who to invite?\nStart by inviting anyone who can help you build the server!" | true |
23 | CONTEXT_MENU_COMMAND | A message sent when a user uses a context menu command | "{content}" | true |
24 | AUTO_MODERATION_ACTION | A message sent when auto moderation takes an action | Special embed rendered from embeds[0] | true 1 |
25 | ROLE_SUBSCRIPTION_PURCHASE | A message sent when a user purchases or renews a role subscription | "{author} {is_renewal ? "renewed" : "joined"} {role_subscription.tier_name} and has been a subscriber of {guild} for {role_subscription.total_months_subscribed} month(?s)!" | true |
26 | INTERACTION_PREMIUM_UPSELL | A message sent when a user is upsold to a premium interaction | "{content}" | true |
27 | STAGE_START | A message sent when a stage channel starts | "{author} started {content}" | true |
28 | STAGE_END | A message sent when a stage channel ends | "{author} ended {content}" | true |
29 | STAGE_SPEAKER | A message sent when a user starts speaking in a stage channel | "{author} is now a speaker." | true |
30 | STAGE_RAISE_HAND | A message sent when a user raises their hand in a stage channel | "{author} requested to speak." | true |
31 | STAGE_TOPIC | A message sent when a stage channel's topic is changed | "{author} changed the Stage topic: {content}" | true |
32 | GUILD_APPLICATION_PREMIUM_SUBSCRIPTION | A message sent when a user purchases an application premium subscription | "{author} upgraded {application ?? "a deleted application"} to premium for this server!" | true |
35 | PREMIUM_REFERRAL | A message sent when a user gifts a premium (Nitro) referral | "{content}" | true |
36 | GUILD_INCIDENT_ALERT_MODE_ENABLED | A message sent when a user enabled lockdown for the guild | "{author} enabled security actions until {content}." | true |
37 | GUILD_INCIDENT_ALERT_MODE_DISABLED | A message sent when a user disables lockdown for the guild | "{author} disabled security actions." | true |
38 | GUILD_INCIDENT_REPORT_RAID | A message sent when a user reports a raid for the guild | "{author} reported a raid in {guild}." | true |
39 | GUILD_INCIDENT_REPORT_FALSE_ALARM | A message sent when a user reports a false alarm for the guild | "{author} reported a false alarm in {guild}." | true |
40 | GUILD_DEADCHAT_REVIVE_PROMPT | A message sent when no one sends a message in the current channel for 1 hour | "{content}" | true |
41 | CUSTOM_GIFT | A message sent when a user buys another user a gift | Special embed rendered from embeds[0].url and gift_info | true |
42 | GUILD_GAMING_STATS_PROMPT | "{content}" | true | |
44 | PURCHASE_NOTIFICATION | A message sent when a user purchases a guild product | "{author} has purchased {purchase_notification.guild_product_purchase.product_name}!" | true |
embeds[0] | ||||
46 | POLL_RESULT | A message sent when a poll is finalized | Special embed rendered from embeds[0] | true |
47 | CHANGELOG | A message sent by the Discord Updates account when a new changelog is posted | "{content}" | true |
48 | NITRO_NOTIFICATION | A message sent when a Nitro promotion is triggered | Special embed rendered from content | true |
49 | CHANNEL_LINKED_TO_LOBBY | A message sent when a voice channel is linked to a lobby | "{content}" | true |
50 | GIFTING_PROMPT | A local-only ephemeral message sent when a user is prompted to gift Nitro to a friend on their friendship anniversary | Special embed | true |
51 | IN_GAME_MESSAGE_NUX | A local-only message sent when a user receives an in-game message NUX | "{author} messaged you from {application.name}. In-game chat may not include rich messaging features such as images, polls, or apps. Learn More" | true |
52 | GUILD_JOIN_REQUEST_ACCEPT_NOTIFICATION 2 | A message sent when a user accepts a guild join request | "{join_request.user}'s application to {content} was approved! Welcome!" | true |
53 | GUILD_JOIN_REQUEST_REJECT_NOTIFICATION 2 | A message sent when a user rejects a guild join request | "{join_request.user}'s application to {content} was rejected." | true |
54 | GUILD_JOIN_REQUEST_WITHDRAWN_NOTIFICATION 2 | A message sent when a user withdraws a guild join request | "{join_request.user}'s application to {content} has been withdrawn." | true |
55 | HD_STREAMING_UPGRADED | A message sent when a user upgrades to HD streaming | "{author} activated HD Splash Potion" | true |
1 Can only be deleted by members with the MANAGE_MESSAGES
permission.
2 The join request can be retrieved using the ID of the channel the message was sent in.
User Join Message Type
Usually, the type of rendered message is determined via converting the message's timestamp
to a unix timestamp with millisecond precision, modulo 13.
Value | Rendered Content |
---|---|
0 | "{author} joined the party." |
1 | "{author} is here." |
2 | "Welcome, {author}. We hope you brought pizza." |
3 | "A wild {author} appeared." |
4 | "{author} just landed." |
5 | "{author} just slid into the server." |
6 | "{author} just showed up!" |
7 | "Welcome {author}. Say hi!" |
8 | "{author} hopped into the server." |
9 | "Everyone welcome {author}!" |
10 | "Glad you're here, {author}." |
11 | "Good to see you, {author}." |
12 | "Yay you made it, {author}!" |
However, if the guild has the CLAN
feature, the same is determined via dividing the message's timestamp
with millisecond precision by modulo 10.
See the below table for the system welcome messages specific to clans.
Value | Rendered Content |
---|---|
0 | "Everyone welcome {author} to the Guild!" |
1 | "A new member has spawned. Say hi to {author}." |
2 | "{author} just joined the Guild. We hope you brought pizza." |
3 | "Glad you're here, {author}, welcome to the Guild." |
4 | "New recruit! {author} joined the Guild." |
5 | "Round of applause for the newest Guild member, {author}. Just for being here." |
6 | "Rolling out the red carpet for {author}. Say hi!" |
7 | "Yahaha! {author} found us!" |
8 | "Get ready everyone -- a {author} has appeared!" |
9 | "Roses are red, violets are blue, {author} just joined the Guild with you." |
Message Flags
Value | Name | Description |
---|---|---|
1 << 0 | CROSSPOSTED | This message has been published to subscribed channels (via Channel Following) |
1 << 1 | IS_CROSSPOST | This message originated from a message in another channel (via Channel Following) |
1 << 2 | SUPPRESS_EMBEDS | Embeds will not be included when serializing this message |
1 << 3 | SOURCE_MESSAGE_DELETED | The source message for this crosspost has been deleted (via Channel Following) |
1 << 4 | URGENT | This message came from the urgent message system |
1 << 5 | HAS_THREAD | This message has an associated thread, with the same ID as the message |
1 << 6 | EPHEMERAL | This message is only visible to the user who invoked the interaction |
1 << 7 | LOADING | This message is an interaction response and the bot is "thinking" |
1 << 8 | FAILED_TO_MENTION_SOME_ROLES_IN_THREAD | Some roles were not mentioned and added to the thread |
1 << 9 | GUILD_FEED_HIDDEN | This message is hidden from the guild's feed |
1 << 10 | SHOULD_SHOW_LINK_NOT_DISCORD_WARNING | This message contains a link that impersonates Discord |
1 << 12 | SUPPRESS_NOTIFICATIONS | This message will not trigger push and desktop notifications |
1 << 13 | VOICE_MESSAGE | This message's audio attachment is rendered as a voice message |
1 << 14 | HAS_SNAPSHOT | This message has a forwarded message snapshot attached |
1 << 15 | IS_UIKIT_COMPONENTS | This message contains components from the UI kit |
1 << 16 | SENT_BY_SOCIAL_LAYER_INTEGRATION | This message was triggered by the social layer integration |
Example Message
{"id": "1076229630052270231","type": 0,"content": "guh","channel_id": "1029316811088478299","author": {"id": "545581357812678656","username": "alien","global_name": "Alien","avatar": "60387de43133809b083fb0f7458d2708","avatar_decoration_data": null,"discriminator": "0","public_flags": 4194432,"primary_guild": null},"attachments": [],"embeds": [],"mentions": [],"mention_roles": [],"pinned": false,"mention_everyone": false,"tts": false,"timestamp": "2023-02-17T19:52:19.184000+00:00","edited_timestamp": null,"flags": 0,"components": [],"reactions": [{"emoji": { "id": null, "name": "‼️" },"count": 2,"count_details": { "burst": 0, "normal": 82 },"burst_colors": ["#f0ca59", "#4c704f", "#e07f45", "#f0ae59", "#f0bc59", "#f0a059", "#e08e45", "#f0984a"],"me_burst": false,"me": false}]}
Example Crossposted Message
{"id": "1076589465084104805","type": 0,"content": "test","channel_id": "909072028911423498","author": {"bot": true,"id": "999498190359371866","username": "Testing Server #News","avatar": "47b30f67c7e2c15637936cd180dd681c","discriminator": "0000"},"attachments": [],"embeds": [],"mentions": [],"mention_roles": [],"pinned": false,"mention_everyone": false,"tts": false,"timestamp": "2023-02-18T19:42:10.541000+00:00","edited_timestamp": null,"flags": 2,"components": [],"webhook_id": "999498190359371866","message_reference": {"type": 0,"channel_id": "901900332408381450","guild_id": "901900332408381449","message_id": "1076589456297054320"}}
Message Activity Object
A rich presence invite in a message.
Message Activity Structure
Field | Type | Description |
---|---|---|
type | integer | The type of activity request |
session_id 1 | string | The session ID associated with this activity |
party_id? | string | The activity's party ID |
1 This field is send-only.
Message Call Object
A call in a private channel.
Message Call Structure
Field | Type | Description |
---|---|---|
participants | array[snowflake] | The channel recipients that participated in the call |
ended_timestamp 1 | ?ISO8601 timestamp | When the call ended, if it has |
1 This is a best-effort marker and may be unexpectedly null
in some cases.
Message Interaction Metadata Object
Metadata about the interaction, including the source of the interaction and the relevant guild and users.
Message Interaction Metadata Structure
Field | Type | Description |
---|---|---|
id | snowflake | The ID of the interaction |
type | integer | The type of interaction |
name? | string | The name of the application command executed (including subcommands and subcommand groups), present only on APPLICATION_COMMAND interactions |
command_type? | integer | The type of application command executed, present only on APPLICATION_COMMAND interactions |
ephemerality_reason? | integer | The reason this interaction is ephemeral |
user | partial user object | The user that initiated the interaction |
authorizing_integration_owners | map[integer, snowflake] | IDs for each installation context related to an interaction |
original_response_message_id? | snowflake | The ID of the original response message, present only on follow-up messages |
interacted_message_id? | snowflake | ID of the message that contained interactive component, present only on messages created from component interactions |
triggering_interaction_metadata? | message interaction metadata object | Metadata for the interaction that was used to open the modal, present only on MODAL_SUBMIT interactions |
target_user? | partial user object | The user that was targeted by the interaction, present only on USER_COMMAND interactions |
target_message_id? | snowflake | The ID of the message that was targeted by the interaction, present only on MESSAGE_COMMAND interactions |
Ephemerality Reason
Value | Name | Description |
---|---|---|
0 | NONE | Unknown reason |
1 | FEATURE_LIMITED | A required feature is temporarily limited |
2 | GUILD_FEATURE_LIMITED | A required feature is temporarily limited for this guild |
3 | USER_FEATURE_LIMITED | A required feature is temporarily limited for this user |
4 | SLOWMODE | The user is sending messages past their rate_limit_per_user |
5 | RATE_LIMIT | The user is being rate limited |
6 | CANNOT_MESSAGE_USER | The user does not have permission to message the target user |
7 | USER_VERIFICATION_LEVEL | The user does not meet the guild verification_level requirement |
8 | CANNOT_UNARCHIVE_THREAD | The user does not have permission to unarchive the thread |
9 | CANNOT_JOIN_THREAD | The user does not have permission to join the thread |
10 | MISSING_PERMISSIONS | The user does not have permission to send messages in the channel |
11 | CANNOT_SEND_ATTACHMENTS | The user does not have permission to send attachments in the channel |
12 | CANNOT_SEND_EMBEDS | The user does not have permission to send embeds in the channel |
13 | CANNOT_SEND_STICKERS | The user does not have permission to send stickers in the channel |
14 | AUTOMOD_BLOCKED | The message was blocked by AutoMod |
15 | HARMFUL_LINK | The message contains a link blocked by Discord |
16 | CANNOT_USE_COMMAND | The user does not have permission to use this command in this channel |
17 | BETA_GUILD_SIZE | The message is only visible to the user for this beta test |
18 | CANNOT_USE_EXTERNAL_APPS | The user does not have permission to use external applications in this channel |
Message Role Subscription Object
A role subscription purchase or renewal.
Message Role Subscription Structure
Field | Type | Description |
---|---|---|
role_subscription_listing_id | snowflake | The ID of the sku and listing that the user is subscribed to |
tier_name | string | The name of the tier that the user is subscribed to |
total_months_subscribed | integer | The cumulative number of months that the user has been subscribed for |
is_renewal | boolean | Whether this notification is for a renewal rather than a new purchase |
Message Purchase Notification Object
A guild product purchase notification.
Message Purchase Notification Structure
Field | Type | Description |
---|---|---|
type | integer | The type of purchase |
guild_product_purchase | ?guild product purchase | The guild product purchase that prompted this message |
Message Purchase Notification Type
Determines the type of purchase notification.
Value | Name | Description |
---|---|---|
0 | GUILD_PRODUCT | A guild product purchase |
Guild Product Purchase Structure
Field | Type | Description |
---|---|---|
listing_id | snowflake | The ID of the product listing that was purchased |
product_name | string | The name of the product that was purchased |
Message Gift Info Object
Information on a gift that prompted a message. The relevant gift link is provided in the first embed of the message.
Message Gift Info Structure
Field | Type | Description |
---|---|---|
emoji? 1 | partial emoji | The emoji associated with the gift |
sound? | message soundboard sound object | The sound associated with the gift |
1 The emoji name
and id
fields are user-provided and not guaranteed to be valid or accurate. The animated
field is never present.
Message Soundboard Sound Structure
Field | Type | Description |
---|---|---|
id | string | The ID of the soundboard sound |
Message Reference Object
A reference to an originating (replied to) message.
Message references are generic attribution on a message.
There are multiple message types that have a message_reference
object.
Message Reference Structure
Field | Type | Description |
---|---|---|
type? 1 | integer | The type of message reference (default DEFAULT ) |
message_id? | snowflake | The ID of the originating message |
channel_id 1 | snowflake | The ID of the originating channel |
guild_id? | snowflake | The ID of the originating channel's guild |
fail_if_not_exists? 2 | boolean | Whether to error if the referenced message doesn't exist instead of sending as a normal (non-reply) message (default true) |
forward_only? 2 3 | message forward only object | What to include in the forwarded message |
1 Optional when creating a reply, but will always be present when receiving this object. In future API versions this will become a required field.
2 This field is send-only.
3 Only applicable to FORWARD
type references.
Message Forward Only Structure
Field | Type | Description |
---|---|---|
embed_indices? | array[integer] | The indices of the embeds from the original message to include |
attachment_ids? | array[snowflake] | The IDs of the attachments from the original message to include |
Message Reference Type
Determines how associated data is populated.
Value | Name | Description | Coupled Message Field |
---|---|---|---|
0 | DEFAULT | A standard reference used by replies and system messages | referenced_message ? |
1 | FORWARD 1 | A reference used to point to a message at a point in time | message_snapshot |
1 This can only be used for basic messages, i.e., messages which do not have strong bindings to a non-global entity. Thus it only supports messages with DEFAULT
or REPLY
types, without any polls, calls, or components. This is subject to change in the future.
Message Snapshot Object
A snapshot of a partial message at a point in time.
Message Snapshot Structure
Field | Type | Description |
---|---|---|
message | snapshot message object | A snapshot of the message when the forward was created |
Snapshot Message Structure
Field | Type | Description |
---|---|---|
content 1 | string | Contents of the message |
timestamp | ISO8601 timestamp | When this message was sent |
edited_timestamp | ?ISO8601 timestamp | when this message was last edited |
mentions | array[user object] | Users specifically mentioned in the message |
mention_roles | array[snowflake] | Roles specifically mentioned in this message |
attachments 1 | array[attachment object] | The attached files |
embeds 1 | array[embed object] | Content embedded in the message |
type | integer | The type of message |
flags | integer | The message's flags |
components? 1 | array[message component object] | The message's components (e.g. buttons, select menus), not currently supported |
sticker_items? | array[sticker item object] | The message's sticker items |
stickers? | array[sticker object] | Extra rich information for the message's sticker items; only available in some contexts |
1 Users must configure (or, in the case of bots, be approved for) the MESSAGE_CONTENT
intent to receive non-empty values for these fields in most situations.
Example Message Snapshot
{"message": {"type": 0,"content": "guh","mentions": [],"mention_roles": [],"attachments": [],"embeds": [],"timestamp": "2023-02-17T19:52:19.184000+00:00","edited_timestamp": null,"flags": 0,"components": []}}
Message Types
There are multiple message types that have a message_reference
object. Since message references are generic attribution to a previous message, there will be more types of messages which have this information in the future.
Crosspost Messages
- These are messages that originated from another channel (
IS_CROSSPOST
flag). - These messages have all three fields, with data of the original message that was crossposted.
Forwarded Messages
- These are messages which capture a snapshot of a message, preventing spoofing or tampering (
HAS_SNAPSHOT
flag). - These messages have an array of
message_snapshots
field containing a copy of the original message. This copy follows the same structure as a message, but has only the minimal set of fields returned required for context/rendering. - A forwarded message can be identified by looking at it's
message_reference.type
field.- Message snapshots will be the message data associated with the forward. Currently only 1 snapshot is supported.
- Message snapshots are taken at moment the forward message is created, and are immutable; any mutations to the orignal message will not be propagated.
- Forwards are created by including a
message_reference
of aFORWARD
type when sending a message. When sending,type
,message_id
, andchannel_id
are required, and the requester must haveVIEW_CHANNEL
permissions. - You can opt to only include specific attachments and embed in the forward by including the
forward_only
field in themessage_reference
. - Stricter rate limits for this feature have been applied based on:
- Number of forwards sent
- Total attachment size
Channel Follow Add Messages
- These are automatic messages sent when a channel is followed into the current channel (type
12
). - These messages have the
channel_id
andguild_id
fields, with data of the followed announcement channel.
Pin Messages
- These are automatic messages sent when a message is pinned (type
6
). - These messages have
message_id
andchannel_id
, andguild_id
if it is in a guild, with data of the message that was pinned.
Reply Messages
- These are messages replying to a previous message (type
19
). - These messages have
message_id
andchannel_id
, andguild_id
if it is in a guild, with data of the message that was replied to. Thechannel_id
andguild_id
will be the same as the reply. - Replies are created by including a
message_reference
when sending a message. When sending, onlymessage_id
is required.
Thread Created Messages
- These are automatic messages sent when a public thread is created from an old message or without a message (type
18
). - These messages have the
channel_id
andguild_id
fields, with data of the created thread channel.
Thread Starter Messages
- These are the first message in public threads created from messages. They point back to the message in the parent channel from which the thread was started (type
21
). - These messages have
message_id
,channel_id
, andguild_id
. - These messages will never have
content
,embeds
, orattachments
, mainly just themessage_reference
andreferenced_message
fields.
Voice Messages
Voice messages are messages with the VOICE_MESSAGE
flag. They have the following properties:
- They cannot be edited.
- Only a single audio attachment is allowed. No other attachments, content, embeds, stickers, etc.
- The attachment has the additional fields
duration_secs
andwaveform
. TheContent-Type
of the attachment must begin withaudio/
to respect these fields.
The waveform
is intended to be a preview of the entire voice message, with 1 byte per datapoint encoded in base64.
Official clients sample the recording at most once per 100 milliseconds, but will downsample so that no more than 256 datapoints are in the waveform.
When uploading a voice message attachment directly, the provided content type must match an audio content type to support the additional fields.
Official clients upload a 1 channel, 48000 Hz, 32 kbps Opus stream in an OGG container. The encoding and waveform details are an implementation detail and may change without warning.
Clips
Clips are a special type of attachment that can be sent with a message. They are created by recording a stream and then clipping a portion of the recording.
Clip attachments have the CLIP
flag set, and have the additional fields clip_created_at
, clip_participants
, and optionally title
and application
.
An attachment can be sent as a clip by specifying the is_clip
, clip_created_at
, and clip_participant_ids
fields, and optionally the title
and application_id
fields.
For an attachment to be a valid clip, it must have a UUID appended to the end of the file in binary format. An example in hexadecimal format is 75 75 69 64 A1 C8 52 99 33 46 4D B8 88 F0 83 F5 7A 75 A5 EF
.
This can be done with the following pseudocode:
Reaction Object
Reaction Structure
Field | Type | Description |
---|---|---|
count | integer | Total amount of times this emoji has been used to react |
count_details | reaction count details object | Details about the number of times this emoji has been used to react |
me | boolean | Whether the current user reacted using this emoji |
me_burst | boolean | Whether the current user burst-reacted using this emoji |
emoji | partial emoji object | Reaction emoji information |
burst_colors | array[string] | The hex-encoded colors to render the burst reaction with |
Reaction Count Details Structure
Field | Type | Description |
---|---|---|
normal | integer | Amount of times this emoji has been used to react normally |
burst | integer | Amount of times this emoji has been used to burst-react |
Reaction Type
Value | Name | Description |
---|---|---|
0 | NORMAL | A normal reaction |
1 | BURST | A burst (super) reaction |
Embed Object
Embed Structure
Field | Type | Description |
---|---|---|
title? | string | The title of the embed (max 256) |
type? | string | The type of embed (always rich for sent embeds) |
description? | string | The description of the embed (max 4096) |
url? | string | The URL of the embed |
timestamp? | ISO8601 timestamp | Timestamp of embed content |
color? | integer | The color of the embed encoded as an integer representation of hexadecimal color code |
footer? | embed footer object | Embed footer information |
image? | embed image object | Embed image information |
thumbnail? | embed thumbnail object | Embed thumbnail information |
video? | embed video object | Embed video information |
provider? | embed provider object | Embed provider information |
author? | embed author object | Embed author information |
fields? | array[embed field object] | The fields of the embed (max 25) |
reference_id? | snowflake | The ID of the message this embed was generated from |
Embed Type
Most embed types are "loosely defined" and, for the most part, are not used by our clients for rendering. Embed attributes power what is rendered.
Type | Description |
---|---|
application_news (deprecated) | Application news embed |
article | Article embed |
auto_moderation_message 1 | AutoMod alert |
auto_moderation_notification 1 | AutoMod incident notification |
gift | Gift embed |
gifv | Animated GIF image rendered as a video embed |
image | Image embed |
link | Link embed |
post_preview 2 | Media channel post preview embed |
rich | Generic embed rendered from embed attributes |
video | Video embed |
1 These embed types are system-generated and cannot be sent by users. Their fields
array represents the object linked in the description as a list of key-value pairs.
2 This embed type is used to signal to the client to render a preview of the linked media channel post. This embed is created for URLs that link to a media channel post if the channel is a paywalled role subscription benefit. The URL is always in the format https://discord.com/channels/:guild_id/:parent_id/threads/:thread_id/:initial_message_id
.
Embed Thumbnail Structure
Field | Type | Description |
---|---|---|
url | string | Source URL of thumbnail (only supports http(s) and attachments) |
proxy_url? | string | A proxied URL of the thumbnail |
height? | integer | Height of thumbnail |
width? | integer | Width of thumbnail |
Embed Video Structure
Field | Type | Description |
---|---|---|
url | string | Source URL of video |
proxy_url? | string | A proxied URL of the video |
height? | integer | Height of video |
width? | integer | Width of video |
Embed Image Structure
Field | Type | Description |
---|---|---|
url | string | Source URL of image (only supports http(s) and attachments) |
proxy_url? | string | A proxied URL of the image |
height? | integer | Height of image |
width? | integer | Width of image |
Embed Provider Structure
Field | Type | Description |
---|---|---|
name? | string | The name of the provider |
url? | string | URL of the provider |
Embed Author Structure
Field | Type | Description |
---|---|---|
name | string | The name of the author (max 256) |
url? | string | URL of the author (only supports http(s)) |
icon_url? | string | Source URL of the author's icon (only supports http(s) and attachments) |
proxy_icon_url? | string | A proxied URL of the author's icon |
Embed Footer Structure
Field | Type | Description |
---|---|---|
text | string | The footer text (max 2048) |
icon_url? | string | Source URL of the footer icon (only supports http(s) and attachments) |
proxy_icon_url? | string | A proxied URL of the footer icon |
Embed Field Structure
Field | Type | Description |
---|---|---|
name | string | The name of the field (max 256) |
value | string | The value of the field (max 1024) |
inline? | boolean | whether this field should display inline |
Attachment Object
Attachment Structure
Field | Type | Description |
---|---|---|
id | snowflake | The attachment ID |
filename | string | The name of file attached (max 1024 characters) |
title? | string | The name of the file without the extension or title of the clip (max 1024 characters, automatically provided when the filename is normalized or randomly generated due to invalid characters) |
uploaded_filename? 3 | string | The name of the file pre-uploaded to Discord's GCP bucket |
description? | string | The description for the file (max 1024 characters) |
content_type? 2 | string | The attachment's media type |
size | integer | The size of file in bytes |
url 2 | string | Source URL of the file |
proxy_url 2 4 | string | A proxied url of the file |
height? 2 | ?integer | Height of image |
width? 2 | ?integer | Width of image |
placeholder_version? 2 | integer | The attachment placeholder protocol version (currently 1) |
placeholder? 2 | string | A low-resolution thumbhash of the image, to display before it is loaded |
ephemeral? 1 2 | boolean | Whether this attachment is ephemeral |
duration_secs? | float | Duration of the audio file (if voice message) |
waveform? | string | Base64 encoded bytearray representing a sampled waveform (if voice message) |
flags? 5 | integer | The attachment's flags |
is_clip? 5 6 7 | boolean | Whether the file being uploaded is a clipped recording of a stream |
is_thumbnail? 5 | boolean | Whether the file being uploaded is a thumbnail |
is_remix? 5 | boolean | Whether this attachment is a remixed version of another attachment |
is_spoiler? 5 | boolean | Whether this attachment is a spoiler |
clip_created_at? 6 | ISO8601 timestamp | When the clip was created |
clip_participant_ids? 6 7 | array[snowflake] | The IDs of the participants in the clip (max 100) |
clip_participants? 7 | array[partial user object] | The participants in the clip (max 100) |
application_id? 7 | snowflake | The ID of the application the clip was taken in |
application? 7 | partial application object | The application the clip was taken in |
1 Ephemeral attachments will automatically be removed after a set period of time. Ephemeral attachments on messages are guaranteed to be available as long as the message itself exists.
2 These fields are received only and cannot be set.
3 This field is send-only. See uploading to Google Cloud for more information.
4 The proxy URL only supports attachments with a defined width
and height
, such as images and videos. For all other attachments, the proxy returns a 415 unsupported media type error.
5 The flags
field is received only and cannot be set directly. To set flags, use the is_clip
, is_thumbnail
, and is_remix
send-only fields.
6 When sending a clip, is_clip
, clip_created_at
, and clip_participant_ids
are required. See message types for more information.
7 The clip_participant_ids
and application_id
fields are send-only. You will receive the clip_participants
and application
fields back when retrieving the message.
Attachment Flags
Value | Name | Description |
---|---|---|
1 << 0 | CLIP | This attachment is a clipped recording of a stream |
1 << 1 | THUMBNAIL | This attachment is a thumbnail |
1 << 2 | REMIX | This attachment has been remixed |
1 << 3 | SPOILER | This attachment is a spoiler |
1 << 4 | CONTAINS_EXPLICIT_MEDIA | This attachment contains explicit media |
1 << 5 | ANIMATED | This attachment is animated |
Allowed Mentions Object
The allowed mention field allows for more granular control over mentions without various hacks to the message content. This will always validate against message content to avoid phantom pings (e.g. to ping everyone, you must still have @everyone
in the message content), and check against user permissions.
Allowed Mention Types
Value | Description |
---|---|
roles | Controls role mentions |
users | Controls user mentions |
everyone | Controls @everyone and @here mentions |
Allowed Mentions Structure
Field | Type | Description |
---|---|---|
parse? | array[string] | The allowed mention types to parse from the content |
roles? | array[snowflake] | The role IDs to mention (max 100) |
users? | array[snowflake] | The user IDs to mention (max 100) |
replied_user? | boolean | For replies, whether to mention the author of the message being replied to (default false) |
Allowed Mentions Reference
Due to the complexity of possibilities, we have included a set of examples and behavior for the allowed mentions field.
If allowed_mentions
is not passed in (i.e. the key does not exist), the mentions will be parsed via the content. This corresponds with existing behavior.
In the example below we would ping @here (and also @role124 and @user123)
{"content": "@here Hi there from <@123>, cc <@&124>"}
To suppress all mentions in a message use:
{"content": "@everyone hi there, <@&123>","allowed_mentions": {"parse": []}}
This will suppress all mentions in the message (no @everyone or user mention).
The parse
field is mutually exclusive with the other fields. In the example below, we would ping users 123
and role 124
, but not @everyone. Note that passing a falsy value ([], null
) into the users
field does not trigger a validation error.
{"content": "@everyone <@123> <@&124>","allowed_mentions": {"parse": ["users", "roles"],"users": []}}
In the next example, we would ping @everyone, (and also users 123
and 124
if they suppressed
@everyone mentions), but we would not ping any roles.
{"content": "@everyone <@123> <@124> <@125> <@&200>","allowed_mentions": {"parse": ["everyone"],"users": ["123", "124"]}}
Due to possible ambiguities, not all configurations are valid. An invalid configuration is as follows
{"content": "@everyone <@123> <@124> <@125> <@&200>","allowed_mentions": {"parse": ["users"],"users": ["123", "124"]}}
Because parse: ["users"]
and users: ["123", "124"]
are both present, we would throw a validation error.
This is because the conditions cannot be fulfilled simultaneously (they are mutually exclusive).
Any entities with an ID included in the list of IDs can be mentioned. Note that the IDs of entities not present in the message's content will simply be ignored. e.g. The following example is valid, and would mention user 123, but not user 125 since there is no mention of user 125 in the content.
{"content": "<@123> Time for some memes.","allowed_mentions": {"users": ["123", "125"]}}
Poll Object
The poll object has a lot of levels and nested structures. It was also designed to support future extensibility, so some fields may appear to be more complex than necessary.
Poll Structure
Field | Type | Description |
---|---|---|
question 1 | poll media object | The question of the poll |
answers | array[poll answer object] | The answers available in the poll |
expiry 2 | ?IS08601 timestamp | When the poll ends |
allow_multiselect | boolean | Whether a user can select multiple answers |
layout_type | integer | The layout type of the poll |
results? | poll results object | The results of the poll |
1 Only text
is supported.
2 expiry
is marked as nullable to support non-expiring polls in the future, but all polls have an expiry currently.
Poll Create Structure
This is the request object used when creating a poll across the different endpoints.
It is similar but not exactly identical to the main poll object.
The main difference is that the request has duration
which eventually becomes expiry
.
Field | Type | Description |
---|---|---|
question 1 | poll media object | The question of the poll |
answers | array[poll answer object] | Each of the answers available in the poll (max 10) |
duration | integer | Number of hours the poll should be open for (max 32 days, default 1) |
allow_multiselect? | boolean | Whether a user can select multiple answers (default false) |
layout_type? | integer | The layout type of the poll (default DEFAULT ) |
1 Only text
is supported.
Poll Layout Type
Different layouts for polls will come in the future. For now though, this value will always be DEFAULT
.
Value | Name | Description |
---|---|---|
1 | DEFAULT | The default layout type |
Poll Media Structure
The poll media object is a common object that backs both the question and answers.
For now, question
only supports text
, while answers can have an optional emoji
.
Field | Type | Description |
---|---|---|
text? 1 | string | The text of the field (max 300 characters for question, 55 characters for answer) |
emoji? 2 | partial emoji | The emoji of the field |
1 text
should always be non-null
for both questions and answers, but do not depend on that in the future.
2 When creating a poll answer with an emoji, clients only needs to send either the id
(custom emoji) or name
(default emoji) as the only field.
Poll Answer Structure
The answer_id
is a number that labels each answer.
As an implementation detail, it currently starts at 1 for the first answer and goes up sequentially.
We recommend against depending on this sequence.
Currently, there is a maximum of 10 answers per poll.
Field | Type | Description |
---|---|---|
answer_id 1 | integer | The ID of the answer |
poll_media | poll media object | The data of the answer |
1 When sending, this field is optional.
Poll Results Structure
In a nutshell, this contains the number of votes for each answer.
The results
field may be not present in certain responses where, as an implementation detail, Discord does not fetch the poll results in the backend.
This should be treated as "unknown results", as opposed to "no results". You can keep using the results if you have previously received them through other means.
Due to the intricacies of counting at scale, while a poll is in progress the results may not be perfectly accurate.
They usually are accurate, and shouldn't deviate significantly—it's just difficult to make guarantees.
To compensate for this, after a poll is finished there is a background job which performs a final, accurate tally of votes.
This tally concludes once is_finalized
is true
. Polls that have ended will also always contain results.
If answer_counts
does not contain an entry for a particular answer, then there are no votes for that answer.
Field | Type | Description |
---|---|---|
is_finalized | boolean | Whether the votes have been precisely counted |
answer_counts | array[poll answer count object] | The counts for each answer |
Poll Answer Count Structure
Field | Type | Description |
---|---|---|
id | integer | The ID of the answer |
count | integer | The number of votes for this answer |
me_voted | boolean | Whether the current user voted for this answer |
Example Poll
{"question": {"text": "Aliens?"},"answers": [{"answer_id": 1,"poll_media": {"text": "Alien"}},{"answer_id": 2,"poll_media": {"text": "Alien 2","emoji": {"id": null,"name": "👽"}}},{"answer_id": 3,"poll_media": {"text": "Alien 3","emoji": {"id": "1120790948302033046","name": "meowlien"}}}],"expiry": "2024-05-02T10:00:02.039342+00:00","allow_multiselect": true,"layout_type": 1,"results": {"answer_counts": [{"id": 1,"count": 1,"me_voted": false}],"is_finalized": false}}
Poll Result Notifications
Poll result notifications are sent as standard messages in the channel with the POLL_RESULT
message type.
The author of the message is the user who created the poll, and the message has a reference pointing to the original poll message.
These messages have a special embed structure which contains information about the poll results.
The custom embed fields below are collapsed as a list of key-value pairs into the fields
array on the embed object.
Poll Result Embed Structure
Field | Type | Description |
---|---|---|
poll_question_text | string | The text of the poll question |
total_votes | integer | The total number of votes on the poll |
victor_answer_id? 1 | integer | The ID of the winning answer |
victor_answer_text? 1 | string | The text of the winning answer |
victor_answer_emoji_id? 1 | snowflake | The ID of the emoji of the winning answer |
victor_answer_emoji_name? 1 | string | The name of the emoji of the winning answer |
victor_answer_emoji_animated? | boolean | Whether the emoji of the winning answer is animated |
victor_answer_votes | integer | The number of votes on the winning answer |
1 If these fields are omitted, the poll did not have a decisive winner.
Example Poll Result Embed
{"type": "poll_result","fields": [{"name": "poll_question_text","value": "aliens?","inline": false},{"name": "victor_answer_votes","value": "100","inline": false},{"name": "total_votes","value": "101","inline": false},{"name": "victor_answer_id","value": "1","inline": false},{"name": "victor_answer_text","value": "ofc","inline": false},{"name": "victor_answer_emoji_id","value": "1243729917288386560","inline": false},{"name": "victor_answer_emoji_name","value": "cheeks","inline": false},{"name": "victor_answer_emoji_animated","value": "true","inline": false}]}
Conversation Summary Object
Conversation summaries are short, LLM-generated descriptions of a channel's activity.
Conversation Summary Structure
Field | Type | Description |
---|---|---|
id | snowflake | The ID of the summary |
topic | string | A short description of the topic of the conversation |
summ_short | string | A brief summary of the conversation |
message_ids | array[snowflake] | The IDs of the messages included in the summary |
people | array[snowflake] | The IDs of the users included in the summary |
unsafe | boolean | Whether the summary contains potentially unsafe content |
start_id | snowflake | The ID of the first message in the conversation |
end_id | snowflake | The ID of the last message in the conversation |
count | integer | The number of messages included in the summary |
source | integer | The source of the summary |
type | integer | The type of summary |
Summary Source
Value | Name | Description |
---|---|---|
0 | SOURCE_0 | The summary was generated by source 0 |
1 | SOURCE_1 | The summary was generated by source 1 |
2 | SOURCE_2 | The summary was generated by source 2 |
Summary Type
Value | Name | Description |
---|---|---|
0 | UNSET | The summary type is unset |
1 | SOURCE_1 | The summary was generated by source 1 |
2 | SOURCE_2 | The summary was generated by source 2 |
3 | UNKNOWN | Unknown |
Example Conversation Summary
{"topic": "Rare Footage of Alien Cat","summ_short": "Conversation about rare footage of an alien cat species.","message_ids": ["1314941815144845413", "1314944583397937213"],"people": ["852892297661906993", "841509053422632990"],"id": "1315651706670813286","unsafe": false,"start_id": "1314941815144845413","end_id": "1315650462522802196","count": 2,"source": 2,"type": 3}
Endpoints
Get Messages
GET
/channels/{channel.id}/messages
Returns an array of message objects in the channel. Requires the VIEW_CHANNEL
permission if operating on a guild channel. If the current user is missing the READ_MESSAGE_HISTORY
permission in the channel then this will return no messages (since they cannot read the message history).
Query String Params
Field | Type | Description |
---|---|---|
around? | snowflake | Get messages around this message ID |
before? | snowflake | Get messages before this message ID |
after? | snowflake | Get messages after this message ID |
limit | integer | Max number of messages to return (1-100, default 50) |
Search Messages
GET
/guilds/{guild.id}/messages/search OR /channels/{channel.id}/messages/search
Returns messages without the reactions
key that match a search query in the guild or channel. The messages that are direct results will have an extra hit
key set to true
. Requires the READ_MESSAGE_HISTORY
permission if operating on a guild channel.
Query String Params
Field | Type | Description |
---|---|---|
limit? | integer | Max number of messages to return (1-25, default 25) |
offset? | integer | Number to offset the returned messages by (max 9975, default 0) |
max_id? | snowflake | Get messages before this message ID |
min_id? | snowflake | Get messages after this message ID |
include_nsfw? | boolean | Whether to include results from NSFW channels (default false) |
content? | string | Filter messages by content |
channel_id? 1 | array[snowflake] | Filter messages by these channels |
author_type? | array[string] | Filter messages by author type |
author_id? | array[snowflake] | Filter messages by these authors |
mentions? | array[snowflake] | Filter messages that mention these users |
mention_everyone? | boolean | Filter messages that do or do not mention @everyone |
pinned? | boolean | Filter messages by whether they are or are not pinned |
has? | array[string] | Filter messages by whether or not they have specific things |
embed_type? | array[string] | Filter messages by embed type |
embed_provider? | array[string] | Filter messages by embed provider (e.g. tenor ) |
link_hostname? | array[string] | Filter messages by link hostname (e.g. google.com ) |
attachment_filename? | array[string] | Filter messages by attachment filename |
attachment_extension? | array[string] | Filter messages by attachment extension (e.g. txt ) |
command_id? | array[snowflake] | Filter messages by these application command IDs |
sort_by? | string | The sorting algorithm to use |
sort_order? | string | The direction to sort (asc or desc , default desc ) |
1 Not applicable when using the GET /channels/{channel.id}/messages/search
endpoint.
Author Type
All types can be negated by prefixing them with -
, which means results will not include messages that match the type.
Value | Description |
---|---|
user | Return messages sent by user accounts |
bot | Return messages sent by bot accounts |
webhook | Return messages sent by webhooks |
Has Type
All types can be negated by prefixing them with -
, which means results will not include messages that match the type.
Value | Description |
---|---|
image | Return messages that have an image |
sound | Return messages that have a sound attachment |
video | Return messages that have a video |
file | Return messages that have an attachment |
sticker | Return messages that have a sent sticker |
embed | Return messages that have an embed |
link | Return messages that have a link |
poll | Return messages that have a poll |
snapshot | Return messages that have a forwarded message |
Message Sort Type
Value | Description |
---|---|
timestamp | Sort by the message creation time (default) |
relevance | Sort by the relevance of the message to the search query |
Response Body
Field | Type | Description |
---|---|---|
messages | array[array[message object]] | A nested array of messages (with optional surrounding context) 1 that match the query |
threads? | array[channel object] | The threads that are the channels of the returned messages |
members? | array[thread member object] | A thread member object for each returned thread the current user has joined |
total_results | integer | The total number of results that match the query |
analytics_id | string | The analytics ID for the search query |
documents_indexed? | integer | The number of documents that have been indexed during the current index operation, if any |
doing_deep_historical_index? | boolean | The status of the guild/channel's deep historical indexing operation, if any |
1 Surrounding context messages are no longer returned.
Example Response
{"total_results": 1,"messages": [[{"id": "1076986676557131916","type": 0,"content": "domainreaction fear","channel_id": "885895521909227581","author": {"id": "545581357812678656","username": "alien","global_name": "Alien","avatar": "60387de43133809b083fb0f7458d2708","avatar_decoration_data": null,"discriminator": "0","public_flags": 4194432,"primary_guild": null},"attachments": [],"embeds": [],"mentions": [],"mention_roles": [],"pinned": false,"mention_everyone": false,"tts": false,"timestamp": "2023-02-19T22:00:33.136000+00:00","edited_timestamp": null,"flags": 0,"components": [],"hit": true}]],"analytics_id": "largealienalphanumericstring"}
Get Message
GET
/channels/{channel.id}/messages/{message.id}
Returns a specific message object in the channel. Requires the READ_MESSAGE_HISTORY
permission if operating on a guild channel.
Create Message
POST
/channels/{channel.id}/messages
Posts a message to a text-based channel. Returns a message object on success. Fires a Message Create Gateway event. See message formatting for more information on how to properly format messages.
To create a message as a reply to another message, you can include a message_reference
with a message_id
. The channel_id
and guild_id
in the message_reference
are optional, but will be validated if provided.
Files must be attached using a multipart/form-data
body (or pre-uploaded to Discord's GCP bucket) as described in Uploading Files.
Limitations
- When operating on a guild channel, the current user must have the
SEND_MESSAGES
permission. - When sending a message with
poll
, the current user must have theSEND_POLLS
permission. - When sending a message with
tts
(text-to-speech) set totrue
, the current user must have theSEND_TTS_MESSAGES
permission. - When creating a message as a reply to another message, the current user must have the
READ_MESSAGE_HISTORY
permission.- The referenced message must exist and cannot be a system message.
- The maximum request size when sending a message is 100 MiB.
- For the embed object, you can set every field except
type
(it will berich
regardless of if you try to set it),provider
,video
, and anyheight
,width
, orproxy_url
values for images.
JSON/Form Params
Field | Type | Description |
---|---|---|
content? | string | The message contents (up to 2000 characters) |
tts? | boolean | Whether this is a TTS message |
embeds? 2 | array[embed object] | Embedded rich content (max 6000 characters, max 10) |
embed? 2 (deprecated) | embed object | Embedded rich content (max 6000 characters), deprecated in favor of embeds |
nonce? 3 | integer | string | The message's nonce, used for message deduplication (will be present in the returned object and accompanying Message Create event) |
allowed_mentions? | allowed mention object | Allowed mentions for the message |
message_reference? | message reference object | The message being replied to or forwarded |
components? 2 | array[message component object] | The components to include with the message |
sticker_ids? | array[snowflake] | IDs of up to 3 stickers to send in the message |
activity? | message activity object | The rich presence activity to invite users to |
application_id? | snowflake | The application ID of the activity to create a rich presence invite for (defaults to the primary activity if unspecified) |
flags? | integer | The message's flags (only SUPPRESS_EMBEDS , SUPPRESS_NOTIFICATIONS , and VOICE_MESSAGE can be set) |
files[n]? 1 | file contents | Contents of the file being sent (max 10) |
payload_json? 1 | string | JSON-encoded body of non-file params |
attachments? 1 | array[partial attachment object] | Partial attachment objects with filename and description (max 10) |
poll? | poll create object | A poll! |
1 See Uploading Files for details.
2 Cannot be used by user accounts.
3 Sending multiple messages in the same channel with the same nonce in a short period of time will result in only the first message being sent.
Example Request Body (application/json)
{"content": "Hello, World!","tts": false,"embeds": [{"title": "Hello, Embed!","description": "This is an embedded message."}]}
Examples for file uploads are available in Uploading Files.
Create DM Message
POST
/users/{user.id}/messages
Posts a message to a text-based channel. Returns a message object on success. Fires a Message Create Gateway event.
This endpoint functions identically to the Create Message endpoint, but is used for DM channels in an OAuth2 context. Check there for more information.
Create Greet Message
POST
/channels/{channel.id}/greet
Posts a greet message to a channel. This endpoint requires the channel is a DM channel or you reply to a system message. Returns a message object on success. Fires a Message Create Gateway event.
JSON Params
Field | Type | Description |
---|---|---|
sticker_ids | array[snowflake] | IDs of up to 1 sticker to send in the message |
allowed_mentions? | allowed mention object | Allowed mentions for the message |
message_reference? | message reference object | The message being replied to |
Create Attachments
POST
/channels/{channel.id}/attachments
Creates attachment URLs to upload the intended attachments directly to Discord's GCP storage bucket. Returns an array of cloud attachment objects. Requires the same permissions as uploading an attachment inline with a message. See Uploading to Google Cloud for more information.
JSON Params
Field | Type | Description |
---|---|---|
files | array[upload attachment object] | The target files to create a URL for, containing the name and size |
Upload Attachment Structure
Field | Type | Description |
---|---|---|
id? | ?string | The ID of the attachment to reference in the response |
filename | string | The name of the file being uploaded |
file_size | integer | The size of the file being uploaded in bytes |
is_clip? 1 | boolean | Whether the file being uploaded is a clipped recording of a stream |
clip_created_at? 1 | ISO8601 timestamp | When the clip was created |
clip_participant_ids? 1 | array[snowflake] | The IDs of the participants in the clip (max 100) |
title? | string | The title of the clip |
application_id? | snowflake | The ID of the application the clip was taken in |
1 When uploading a clip, is_clip
, clip_created_at
, and clip_participant_ids
are required. See message types for more information.
Cloud Attachment Structure
Field | Type | Description |
---|---|---|
id | ?string | The ID of the attachment upload, if provided in the request |
upload_url | string | The URL to upload the file to |
upload_filename | string | The name of the uploaded file |
Example Response
{"attachments": [{"id": "23","upload_url": "https://discord-attachments-uploads-prd.storage.googleapis.com/87e49c99-43f8-4a33-baad-5a834c94424c/cat.png?upload_id=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX","upload_filename": "87e49c99-43f8-4a33-baad-5a834c94424c/cat.png"}]}
Delete Attachment
DELETE
/attachments/{cloud_attachment.upload_filename}
Deletes an attachment from Discord's GCP storage bucket. Returns a 204 empty response on success.
This endpoint should be used to delete an uploaded attachment that was not used. See Uploading to Google Cloud for more information.
Refresh Attachment URLs
POST
/attachments/refresh-urls
Refreshes the URLs of attachments that were uploaded to Discord's CDN. The provided URLs do not have to be valid or signed. Existing query string parameters are preserved.
JSON Params
Field | Type | Description |
---|---|---|
attachment_urls | array[string] | The URLs of the attachments to refresh (1-50) |
Response Body
Field | Type | Description |
---|---|---|
refreshed_urls | array[refreshed attachment object] | The refreshed URLs |
Refreshed Attachment Structure
Field | Type | Description |
---|---|---|
original | string | The provided URL |
refreshed | string | The refreshed URL |
Example Response
{"refreshed_urls": [{"original": "https://cdn.discordapp.com/attachments/1012345678900020080/1234567891233211234/my_image.png?ex=65d903de&is=65c68ede&hm=2481f30dd67f503f54d020ae3b5533b9987fae4e55f2b4e3926e08a3fa3ee24f&","refreshed": "https://cdn.discordapp.com/attachments/1012345678900020080/1234567891233211234/my_image.png?ex=66143372&is=6601be72&hm=5a90a0ac363d9de3619044102ffe963041517f0e2f78baecabfc2f544a14eace&"}]}
Acknowledge Message
POST
/channels/{channel.id}/messages/{message.id}/ack
Sets the channel's latest acknowledged message (marks a message as read) for the current user. Fires a Message Ack Gateway event.
The message ID parameter does not need to be a valid message ID, but it must be a valid snowflake. If the message ID is being set to a message sent prior to the latest acknowledged one, manual
should be true
or the resulting read state update should be ignored by clients (but is still saved), resulting in undefined behavior. In this case, mention_count
should also be set to the amount of mentions unacknowledged as it is not automatically calculated by Discord.
JSON Params
Field | Type | Description |
---|---|---|
token? | ?string | The last received ack token, or null |
manual? | boolean | Whether the acknowleged message ID is manually set |
mention_count? 1 | integer | The new unread indicator for the channel |
1 Requires manual
to be true
.
Response Body
Field | Type | Description |
---|---|---|
token | ?string | The new ack token |
Crosspost Message
POST
/channels/{channel.id}/messages/{message.id}/crosspost
Crossposts a message in a News Channel to following channels. Requires the SEND_MESSAGES
permission if the current user sent the message, or additionally the MANAGE_MESSAGES
permission for all other messages. Returns a message object on success. Fires a Message Update (and possibly multiple Message Create) Gateway event.
Hide Message from Guild Feed
POST
/channels/{channel.id}/messages/{message.id}/hide-guild-feed
Hides a message from the feed of the guild the channel belongs to. Returns a 204 empty response on success.
Get Reactions
GET
/channels/{channel.id}/messages/{message.id}/reactions/{emoji}
Get a list of users that reacted with this emoji. Returns an array of partial user objects.
The emoji
must be URL Encoded or the request will fail. To use custom emoji, you must encode it in the format name:id
with the emoji name and emoji ID.
Query String Params
Field | Type | Description |
---|---|---|
after? | snowflake | Get users after this user ID |
limit? | integer | Max number of users to return (1-100, default 25) |
type? | integer | The type of reaction to get users for (default REGULAR ) |
Create Reaction
PUT
/channels/{channel.id}/messages/{message.id}/reactions/{emoji}/@me
Creates a reaction for the message. Requires the READ_MESSAGE_HISTORY
permission if operating on a guild channel. Additionally, if nobody else has reacted to the message using this emoji, this endpoint requires the ADD_REACTIONS
permission. Returns a 204 empty response on success. Fires a Message Reaction Add Gateway event.
The emoji
must be URL Encoded or the request will fail. To use custom emoji, you must encode it in the format name:id
with the emoji name and emoji ID.
Query String Params
Field | Type | Description |
---|---|---|
type? | integer | The type of reaction to create (default REGULAR ) |
Delete Own Reaction
DELETE
/channels/{channel.id}/messages/{message.id}/reactions/{emoji}/{reaction_type}/@me
Deletes a reaction the current user has made for the message. Returns a 204 empty response on success. Fires a Message Reaction Remove Gateway event.
The emoji
must be URL Encoded or the request will fail. To use custom emoji, you must encode it in the format name:id
with the emoji name and emoji ID.
Delete Reaction
DELETE
/channels/{channel.id}/messages/{message.id}/reactions/{emoji}/{reaction_type}/{user.id}
Deletes another user's reaction. Requires the MANAGE_MESSAGES
permission. Returns a 204 empty response on success. Fires a Message Reaction Remove Gateway event.
The emoji
must be URL Encoded or the request will fail. To use custom emoji, you must encode it in the format name:id
with the emoji name and emoji ID.
Delete Reaction Emoji
DELETE
/channels/{channel.id}/messages/{message.id}/reactions/{emoji}
Deletes all the reactions for a given emoji on a message. Returns a 204 empty response on success. Requires the MANAGE_MESSAGES
permission. Fires a Message Reaction Remove Emoji Gateway event.
The emoji
must be URL Encoded or the request will fail. To use custom emoji, you must encode it in the format name:id
with the emoji name and emoji ID.
Delete All Reactions
DELETE
/channels/{channel.id}/messages/{message.id}/reactions
Deletes all reactions on a message. Returns a 204 empty response on success. Requires the MANAGE_MESSAGES
permission. Fires a Message Reaction Remove All Gateway event.
Edit Message
PATCH
/channels/{channel.id}/messages/{message.id}
Edits a previously sent message. All fields can be edited by the original message author. Other users can only edit flags
and only if they have the MANAGE_MESSAGES
permission in the corresponding channel. When specifying flags, ensure to include all previously set flags/bits in addition to ones that you are modifying.
When the content
field is edited, the mentions
array in the message object will be reconstructed from scratch based on the new content. The allowed_mentions
field of the edit request controls how this happens. If there is no explicit allowed_mentions
in the edit request, the content will be parsed with default allowances, that is, without regard to whether or not an allowed_mentions
was present in the request that originally created the message.
Returns a message object. Fires a Message Update Gateway event.
Refer to Uploading Files for details on attachments and multipart/form-data
requests.
Any provided files will be appended to the message. To remove or replace files you will have to supply the attachments
field which specifies the files to retain on the message after edit.
JSON/Form Params
Field | Type | Description |
---|---|---|
content? | ?string | The message contents (up to 2000 characters) |
embeds? 2 | ?array[embed object] | Embedded rich content (max 6000 characters) |
embed? 2 (deprecated) | ?embed object | Embedded rich content (max 6000 characters), deprecated in favor of embeds |
allowed_mentions? | ?allowed mention object | Allowed mentions for the message |
components? 2 | ?array[message component object] | The components to include with the message |
flags? | ?integer | The message's flags (only SUPPRESS_EMBEDS can be set) |
files[n] 1 | ?file contents | Contents of the file being sent |
payload_json 1 | ?string | JSON-encoded body of non-file params |
attachments 1 | ?array[partial attachment object] | Partial attachment objects with filename and description , including attached files to keep |
1 See Uploading Files for details.
Edit DM Message
PATCH
/users/{user.id}/messages/{message.id}
Edits a previously sent message. Messages can be edited by the original message author. Returns a message object. Fires a Message Update Gateway event.
JSON/Form Params
Field | Type | Description |
---|---|---|
content? | ?string | The message contents (up to 2000 characters) |
Delete Message
DELETE
/channels/{channel.id}/messages/{message.id}
Deletes a message. Requires the MANAGE_MESSAGES
permission if operating on a guild channel and trying to delete a message that was not sent by the current user. Returns a 204 empty response on success. Fires a Message Delete Gateway event.
Delete DM Message
POST
/users/@me/messages/{message.id}/delete
Deletes a message. Messages can be deleted by the original message author. Returns a 204 empty response on success. Fires a Message Delete Gateway event.
Bulk Delete Messages
POST
/channels/{channel.id}/messages/bulk-delete
Deletes multiple messages from a guild channel in a single request. Requires the MANAGE_MESSAGES
permission. Returns a 204 empty response on success. Fires a Message Delete Bulk Gateway event.
Any message IDs given that do not exist or are invalid will count towards the minimum and maximum message count (currently 2 and 100 respectively).
JSON Params
Field | Type | Description |
---|---|---|
messages | array[snowflake] | The message IDs to delete (2-100) |
Get Pinned Messages
GET
/channels/{channel.id}/pins
Returns all pinned messages in the channel as an array of message objects without the reactions
key.
Pin Message
PUT
/channels/{channel.id}/pins/{message.id}
Pins a message in a channel. Requires the MANAGE_MESSAGES
permission if operating on a guild channel. Returns a 204 empty response on success.
Unpin Message
DELETE
/channels/{channel.id}/pins/{message.id}
Unpins a message in a channel. Requires the MANAGE_MESSAGES
permission if operating on a guild channel. Returns a 204 empty response on success.
Acknowledge Pinned Messages
POST
/channels/{channel.id}/pins/ack
Acknowledges the currently pinned messages in a channel. Returns a 204 empty response on success. Fires a Channel Pins Ack Gateway event.
Get Channel Media Preview
GET
/channels/{channel.id}/media-post-preview
Returns information on the media of a post (thread) in a media channel. The media channel must be a paywalled role subscription benefit. If the user is not in the guild, the guild must be discoverable.
Response Body
Field | Type | Description |
---|---|---|
media | media preview object | The preview of the media in the thread's first message |
Media Preview Structure
Field | Type | Description |
---|---|---|
guild_id | snowflake | The ID of the guild the media is in |
guild_name | string | The name of the guild the media is in |
guild_icon | string | The icon hash of the guild the media is in |
channel_id | snowflake | The ID of the thread that represents the media |
parent_channel_id | snowflake | The ID of the media channel the thread is in |
message_id | snowflake | The ID of the thread's first message (same as the thread ID) |
author_id | snowflake | The ID of the author of the thread's first message |
title | string | The name of the thread |
description | string | The first 64 characters of the first message's content |
has_media_attachment 1 | boolean | Whether the first message has a media attachment |
thumbnail? | attachment object | The thumbnail of the thread's first message, if any |
1 If a media attachment is present, a fake thumbnail will be rendered in the preview as a CTA to subscribe to the role that unlocks the media channel.
Example Response
{"media": {"guild_id": "1046920999469330512","channel_id": "1120793989809967114","parent_channel_id": "1120793939562217483","message_id": "1120793989809967114","title": "feet picers","description": "https://tenor.com/view/naomi-bunny-melon-gif-22514980","guild_name": "Hood Network","guild_icon": "a_78187748cb59baec2bf6a1f8766ff9fc","author_id": "728342296696979526","thumbnail": {"url": "https://media.tenor.com/ttfzDdgGOqgAAAAM/naomi-bunny.png","proxy_url": "https://images-ext-2.discordapp.net/external/RGh8LSJbaADcUFgzFsvpODM6E2nz3xKVg_Mrg9UE58k/https/media.tenor.com/ttfzDdgGOqgAAAAe/naomi-bunny.png","width": 388,"height": 640},"has_media_attachment": true}}
Unfurl Embed
POST
/unfurler/unfurl
Returns debug information about an embed.
JSON Params
Field | Type | Description |
---|---|---|
url | string | The URL to unfurl |
Response Body
Field | Type | Description |
---|---|---|
response? | embed response object | The response from the website |
error? | string | The error that occurred while parsing the website |
context_errors | array[string] | The contextual errors that occurred while parsing the website |
embeds? | array[embed object] | The found embeds for the URL |
Embed Response Structure
Field | Type | Description |
---|---|---|
headers | map[string, string] | The relevant headers returned by the website |
body | string | The body of the website, if used to generate the embed |
Unfurl Embeds
POST
/unfurler/embed-urls
Returns embed data from a list of URLs.
JSON Params
Field | Type | Description |
---|---|---|
urls | array[string] | The URLs to unfurl (max 4) |
Response Body
Field | Type | Description |
---|---|---|
embeds | array[embed object] | The found embeds for the URLs |
Get Answer Voters
GET
/channels/{channel.id}/polls/{message.id}/answers/{answer.id}
Get a list of users that voted for this specific answer.
Query String Params
Field | Type | Description |
---|---|---|
after? | snowflake | Get users after this user ID |
limit? | integer | Max number of users to return (1-100, default 25) |
Response Body
Field | Type | Description |
---|---|---|
users | array[partial user object] | Users who voted for this answer |
End Poll
POST
/channels/{channel.id}/polls/{message.id}/expire
Immediately ends the poll. You cannot end polls from other users.
Returns a message object. Fires a Message Update Gateway event.
Create Poll Vote
PUT
/channels/{channel.id}/polls/{message.id}/answers/@me
Submits a poll vote for the current user. Returns a 204 empty response on success. Fires multiple Message Poll Vote Add and optionally Message Poll Vote Remove Gateway events.
JSON Params
Field | Type | Description |
---|---|---|
answer_ids | array[integer] | Selected answers, empty to clear votes |
Get Conversation Summaries
GET
/channels/{channel.id}/summaries
Get a list of up to 50 latest conversation summaries for a text channel in reverse chronological order. Requires the READ_MESSAGE_HISTORY
permission.
Response Body
Field | Type | Description |
---|---|---|
summaries | array[conversation summary object] | The conversation summaries for the channel (max 50) |
Delete Conversation Summary
DELETE
/channels/{channel.id}/summaries/{summary.id}
Deletes a conversation summary. Requires the MANAGE_MESSAGES
permission. Returns a 204 empty response on success. Fires a Conversation Summary Update Gateway event.