Discord organizes its surface around three primary scopes: guilds (servers), channels (including threads and DMs), and applications/webhooks. Snowflake IDs (called guild_id, channel_id, user_id, message_id, etc.) identify nearly every resource and power most calls. Treat Snowflakes as the single source of truth for cross-references: channels live on a guild (or are DMs), messages live in channels, members live in guilds, roles belong to guilds, and application commands and webhooks are owned by an application (optionally scoped to a guild).
How the domain is organized
- Guilds are the top-level community object. Most moderation, roles, scheduled events, emojis, stickers, channels, and members are scoped to a
guild_id. - Channels are the place for messages and threads. A thread is represented by a
channel_idjust like a channel; many thread operations reusechannel_idas the thread identifier. Some channel endpoints return different channel shapes depending on channel type (text, forum, private DM, thread). Inspect the response type to know which shape you received. - Members are always bound to a
guild_id+user_idpair. Role operations takeguild_id+role_id. Member management (ban, add role, update nick) needs the guild context. - Applications (bots/integrations) are identified by
application_id. Application commands are created either globally (create_application_command) or per-guild (create_guild_application_command). Webhooks carrywebhook_idand often awebhook_tokenwhen invoked without normal credentials. - Lobbies and entitlements are separate subsystems with their own
lobby_idor entitlement ids; they are not interchangeable with guild channels.
Entry points — what to call first
Start by obtaining the primary IDs you will need for follow-up operations. Common first calls:
get_my_userorget_my_application— learn your bot/application identity and primaryidvalues.list_my_guilds— get theguild_ids the bot is in (useful before guild-scoped actions).list_guild_channelsorget_guild— getchannel_ids and the guild structure; channel objects show channel type, parent id, and permissions.list_guild_membersorget_guild_member— locateuser_ids and member metadata needed for moderation or role changes.list_application_commands/list_guild_application_commands— inspect existing commands before creating or editing commands.get_webhook/get_webhook_by_token/list_channel_webhooks— discover webhooks and their tokens for posting without bot credentials.get_bot_gateway— if you need gateway/sharding details for real-time behavior (not required for HTTP-only tasks).
Obtaining those IDs early prevents dead ends: many operations require guild_id, channel_id, or application_id explicitly.
Common tasks and the call sequence to accomplish them
These workflows are the ones users ask for most often. Each sequence lists the essential operations and the IDs they require.
Send, edit, delete, or crosspost messages
- Send a message:
create_messagewithchannel_idand aMessageCreateRequestbody. The response contains themessage_idyou will use later. - Edit a message:
update_messagewithchannel_id+message_idandMessageEditRequestPartial. - Delete a message:
delete_messagewithchannel_id+message_id. - Crosspost (announcement channels):
crosspost_messagewithchannel_id+message_id. The call returns the published message. - Reactions: add with
add_my_message_reaction, remove your reaction withdelete_my_message_reaction, remove a specific user’s reaction withdelete_user_message_reaction, and clear all reactions withdelete_all_message_reactions.
Responding to interactions and follow-ups
- Immediately respond to an interaction using
create_interaction_responsewithinteraction_id,interaction_token, and an appropriate callback request body. The interaction token is short-lived—respond quickly. - For threaded follow-ups or editing interaction responses, use webhook operations tied to the interaction or the returned message objects.
Application commands (slash commands)
- Inspect existing commands via
list_application_commands(global) orlist_guild_application_commands(guild). Global commands useapplication_id; guild commands requireapplication_id+guild_id. - Create or update commands with
create_application_command/update_application_command(global) orcreate_guild_application_command/update_guild_application_command(guild). - Manage permissions for a guild-scoped command with
set_guild_application_command_permissionsand view them viaget_guild_application_command_permissions. - If you need to replace the entire set, use
bulk_set_application_commands(global) orbulk_set_guild_application_commands(guild). Note that global commands can take time to propagate.
Moderation: members, bans, prunes
- Ban a user:
ban_user_from_guildwithguild_id+user_id. Inspectlist_guild_bansorget_guild_banto confirm. - Unban:
unban_user_from_guildwithguild_id+user_id. - Bulk ban:
bulk_ban_users_from_guildfor multiple users in one call. - Preview or prune inactive members with
preview_prune_guildandprune_guild(both requireguild_id). - Audit logs:
list_guild_audit_log_entriesto inspect actions, filters supportuser_id,target_id, and action type.
Role and permission management
- Create:
create_guild_rolewithguild_id. - Update:
update_guild_role, delete withdelete_guild_role. - Assign or remove a role to/from a member:
add_guild_member_role/delete_guild_member_rolewithguild_id+user_id+role_id. - Reorder positions in bulk:
bulk_update_guild_roles.
Channels, threads, and pins
- Create a guild channel:
create_guild_channelwithguild_id. - Read a channel:
get_channelwithchannel_id(returns different channel shapes depending on type). - Create threads:
create_thread,create_thread_from_message, orcreate_thread_from_messagevariant depending on whether you start from a message. - Join/leave threads:
join_thread/leave_threaduse the threadchannel_id. - Pins:
create_pin,delete_pin, andlist_pins(note there is also a deprecated pins list to watch for).
Webhooks and raw posting
- Create a webhook in a channel:
create_webhookwithchannel_id. - Execute a webhook without standard credentials:
execute_webhook(requireswebhook_id+webhook_token). Optionalthread_idlets you post into a specific thread. - When you only have a token,
get_webhook_by_token,delete_webhook_by_token, andupdate_webhook_by_tokenare the relevant operations. - Webhook message lifecycle:
get_webhook_message,update_webhook_message,delete_webhook_message(all accept optionalthread_id).
Files, emojis, stickers, and attachments
- Upload attachments used by application activities or some message flows with
upload_application_attachment(returns attachment metadata you can reference). - Create emojis or application emojis using the
imagefield that accepts text or base64 payload shapes; sticker creation uses a multipart structure with afilepart. These endpoints accept multipart-like request shapes—provide the file content in the part exposed by the operation’s body schema. - When sending images or files with messages, check whether the operation expects an attachment id (from an upload) or an inline file part in the same call.
Lobbies, entitlements, and game features
- Lobbies are managed with
create_lobby,create_or_join_lobby,get_lobby,add_lobby_member,delete_lobby_member, andlist_lobby_messages. - Entitlements (in-app purchases) are created with
create_entitlement, queried withget_entitlements/get_entitlement, and consumed withconsume_entitlement.
Response unions and how to interpret them
Many endpoints return union types (for example channel responses, webhook responses, or scheduled event variants). The response body will include discriminator fields (like type, channel_type, or guild_scheduled_event_type) or specific object shapes to determine which variant you received. Always inspect the returned object to pick the right follow-up path (e.g., a GuildChannelResponse vs a PrivateChannelResponse).
Non-obvious gotchas and operational quirks
-
IDs everywhere: expect to pass
guild_id,channel_id,user_id,message_id, orapplication_idexplicitly. If you lack a required ID, fetch it first with the list/get operations mentioned above. -
Thread identity reuse: threads are
channel_ids. When an endpoint asks forchannel_idit may be the parent channel or an individual thread—read the operation and response shape to tell which. -
Short-lived interaction tokens:
interaction_tokenvalues expire quickly. Create interaction responses (create_interaction_response) as soon as possible after receiving the interaction. -
Global vs guild application commands: global commands (
application_idwithoutguild_id) can take substantial time to propagate; guild-scoped commands update instantly. Use guild commands for rapid iteration and testing. -
Webhook tokens bypass bot credentials: if you have a
webhook_tokenyou can post without the bot identity. Many webhook endpoints accept an optionalthread_id—use it to target specific threads. -
Multipart/attachment shapes are explicit in the operation body: parts are named (for example
fileorimage) and accept structured parts with$textor$base64fields or multipart sub-objects. Provide the content in the part specified by the API; the upload endpointupload_application_attachmentreturns attachment objects you can reference elsewhere. -
Bulk-deletes and age limits: bulk delete operations (and Discord in general) impose constraints on message age. Bulk-deleting very old messages is not permitted; if you need to remove older content, delete individually or check message timestamps before calling bulk delete.
-
Permission and scope requirements: many guild-level operations require the caller to have specific guild permissions (Manage Roles, Ban Members, Manage Channels, etc.) or the application to have the right OAuth scopes. If the operation fails with a permissions-related response, confirm the caller’s role and OAuth scopes.
-
Union responses for scheduled events, emojis, and stickers: these resources have subtype variants; follow-up calls that update or inspect them often require you to choose the correct patch/update shape matching the original subtype.
-
Pagination cursors are Snowflakes: listing endpoints that accept
before/afteruse Snowflake cursors. When iterating results across pages, use the last/first returned Snowflake values.
Practical tips for decision-making
- If a user asks to act in a guild, and you don’t have a
guild_id, calllist_my_guildsorget_guildfirst. - If the task is posting content in a conversation and you lack a
channel_id, calllist_guild_channelsor create a DM withcreate_dm(for one-off private messages) beforecreate_message. - If making or changing application commands, prefer guild-scoped calls during testing (
create_guild_application_command) and use bulk-set APIs when you want to replace all commands atomically. - For moderation actions (ban, mute, role changes), gather
user_idviaget_guild_memberorlist_guild_membersand confirm the member’s current roles via the member response before modifying roles.
Where callers commonly get stuck
- Missing IDs: many failures come from attempting to call a guild-scoped endpoint without a
guild_idor channel-scoped endpoint without achannel_id. If you hit this, fetch the list endpoints for the relevant scope. - Choosing the wrong command scope: creating global commands when you intended a quick test in one guild leads to long waits. Use guild commands for immediate changes.
- Webhook vs bot posting: if you need to post without bot credentials, ensure you have
webhook_id+webhook_tokenand useexecute_webhook/execute_slack_compatible_webhook/execute_github_compatible_webhookaccordingly.
Use these patterns as your operational map: fetch the ID you need, call the resource-scoped create/read/update/delete operation, and inspect returned objects for subtype discriminators. That approach covers the common requests users will give you (send/edit messages, moderate members, manage roles, create commands and webhooks, and handle attachments).