Discord's HTTP API models servers (guilds), channels (guild channels, DMs, group DMs, threads), users/members, applications (bots and OAuth2 apps), webhooks, and a handful of auxiliary resources (roles, scheduled events, entitlements, lobbies, stickers, emojis, soundboard). Most useful workflows pivot around a small set of IDs: guild_id, channel_id, message_id, user_id, application_id, webhook_id (+ webhook_token), role_id, and guild_scheduled_event_id. Understanding which ID is required where, and where to obtain it, is the key to accomplishing user requests efficiently.
How the domain is organized
Guilds are the top-level server resource for community-related operations: channels, members, roles, scheduled events, emojis, stickers, and guild-level webhooks live under a guild_id. Channels are the focal point for messaging: guild channels, private (DM) channels, group DMs, and threads share many channel-scoped endpoints and are returned as union types that indicate their concrete kind.
Applications (bots/OAuth apps) are a separate scope. Application-scoped resources include application commands, application emojis, entitlements, and role-connections; these require the application_id. Webhooks are a hybrid resource: a webhook record (by webhook_id) plus a webhook_token can be used to post without the application's bot token. Interaction responses also use interaction_id and interaction_token and are accessed through webhook-style endpoints anchored to an application.
Lobbies and matchmaking-like resources use lobby_id and have their own member/message endpoints; they are orthogonal to guild channels but follow the same pattern (list, create, edit, delete).
Entry points — where to call first to get the IDs you need
Begin by fetching the resource that naturally contains the ID you need rather than guessing names or constructing IDs. Typical first calls:
-
If the user references a server name or wants to operate in a server: call
list_my_guildsorget_guildto obtainguild_idand optional counts. Uselist_guild_channelsto map channel names →channel_idinside that guild. -
If the user wants to DM someone: call
create_dmwith the recipient(s) to produce a DM channel (returns a channel object withid). Use thatchannel_idforcreate_message/update_message/reactions. -
If the user asks to post as a webhook or follow up to an interaction: obtain the
webhook_id/webhook_tokenfromcreate_webhook(channel-scoped) or from stored webhook credentials.get_webhook_by_tokencan validate and return the webhook object fromwebhook_id+webhook_token. -
For bot/application actions (commands, entitlements, metadata): call
get_applicationorget_my_applicationto confirmapplication_id, thenlist_application_commands/list_guild_application_commandsas needed. -
To act on a specific message: call
list_messagesorget_message(requireschannel_idfirst). Many message-based workflows require bothchannel_idandmessage_id. -
To manage members and roles: call
list_guild_members(orsearch_guild_members) to locate auser_idandget_guild/list_guild_rolesto find arole_id.
If the user supplies a human name (server name, channel name, username#discriminator), resolve that by the appropriate list/get endpoint rather than assuming an ID format.
Common tasks and the operation pattern to accomplish them
Each task below lists the minimal sequence of operations that produce the IDs required for the next call; responses referenced are the typical returns you can rely on.
Send a message to a guild channel:
- Obtain
guild_id(if not given) withlist_my_guildsorget_guild. - Get channels with
list_guild_channels, pick the channel bynameortype, takechannel_id. - Call
create_messagewithchannel_id. The response isMessageResponse(containsid,author,content, etc.).
Send a DM to a user:
- Call
create_dmwith the recipient user ID(s); response is a DM channel object withid. - Call
create_messagewith thatchannel_id.
Edit or delete a message:
- Use
get_message(orlist_messages) to getmessage_idand verify ownership/permissions. - Call
update_messageordelete_messagewithchannel_id+message_id.
React to a message and inspect reactions:
- Add your reaction with
add_my_message_reaction(requiresemoji_namefor unicode or custom emoji format — see Gotchas). - List voters with
list_message_reactions_by_emoji(returnsUserResponse[]). - Remove reactions with
delete_my_message_reactionordelete_all_message_reactions.
Create and use a webhook:
- Create in a channel with
create_webhook(returns the webhook object; stored tokens are often returned there). - Post with
execute_webhook(usewebhook_idandwebhook_token). You can includethread_idas a query param to post into a thread in that channel. - Update or delete webhook messages with
update_webhook_message/delete_webhook_message(requirewebhook_id,webhook_token, andmessage_id).
Create and manage application (slash) commands:
- Use
list_application_commands(global) orlist_guild_application_commands(guild-scoped) to see existing commands forapplication_id. - Create with
create_application_commandorcreate_guild_application_command(choose global vs guild based on scope). - For per-guild permissions, use
get_guild_application_command_permissions/set_guild_application_command_permissions.
Manage guild members and roles:
- Find the member with
list_guild_membersorsearch_guild_members. - Create a role with
create_guild_role; add it to a user withadd_guild_member_roleor update multiple roles viaupdate_guild_member. - Ban/unban with
ban_user_from_guildandunban_user_from_guild(both requireguild_id+user_id).
Threads and private archives:
- Create threads with
create_threadorcreate_thread_from_message(requireschannel_id, and optionallymessage_idfor message-threading). - Join/leave threads with
join_thread/leave_thread; add/remove thread members withadd_thread_member/delete_thread_member. - Use
list_thread_members/get_thread_memberto inspect membership. Threads are returned by the same channel endpoints and appear in union channel responses.
Application entitlements and SKU flow:
- Entitlements are application-scoped: call
create_entitlementandget_entitlementswithapplication_id. Filtering byuser_id,sku_ids,guild_id, andonly_activenarrows results.
Lobbies and related flows:
- Create or join with
create_or_join_lobby(returnsLobbyResponse); usecreate_lobby_messageandlist_lobby_messagesfor lobby chat; manage members withadd_lobby_member,bulk_update_lobby_members, anddelete_lobby_member.
Response patterns and unions you must handle
Many endpoints return union types because the same endpoint can return several concrete resource shapes depending on context (for example, get_channel may return a GuildChannelResponse, PrivateChannelResponse, PrivateGroupChannelResponse, or ThreadResponse). Do not assume a fixed shape: inspect the returned object's discriminating fields (type, presence of guild_id, owner_id, permissions, member sub-object, etc.) to decide the next step.
Some list endpoints return null rather than an empty array. Treat null as “no results.” Several bulk endpoints return arrays of result objects or null entries where items failed or didn’t exist.
Several update/create endpoints return slightly different concrete types depending on inputs (for example, scheduled events and auto-moderation rules can return one of several variant response objects). Rely on discriminant fields in the response rather than a single expected type.
Non‑obvious behaviors and gotchas
-
Webhook tokens vs application/bot tokens: webhook operations that accept
webhook_id+webhook_tokenallow posting, editing, and deleting webhook messages without the bot token. Interaction follow-ups use the same webhook-style endpoints anchored toapplication_idandinteraction_token. Webhook-based endpoints also accept an optionalthread_idquery parameter to post into threads. -
emoji_nameformat for reactions: unicode emoji should be provided as the literal emoji; custom guild emojis use thename:idformat (the path parameter accepts either form). The bridge encodes values, but you must pass the emoji in the correct textual form. -
Interaction responses vs webhooks:
create_interaction_responseusesinteraction_id+interaction_token. To edit or delete the original interaction message, use the webhook-style endpoints withwebhook_id= yourapplication_idandwebhook_token= theinteraction_token. -
Expansion flags reduce extra calls: many endpoints offer query flags such as
with_member,with_counts,with_user_count, andwith_localizations. Use these to obtain joined or expanded data in a single call instead of making separate list/get calls. -
Global vs guild-scoped commands: creating a global application command (
create_application_command) affects all guilds but can take time to propagate; guild-scoped commands (create_guild_application_command) are immediate and suitable for testing. Managing per-guild permissions requires theapplication_idandguild_id. -
Some create/update endpoints are marked with no response body (
unknown) in this specification. Don’t assume a returned resource is always present; if you need the created resource’s ID, follow the create call with the appropriate get/list endpoint to retrieve it. -
Lists and pagination: list endpoints commonly accept
limit,before, andafter. If a user requests more results than a single list call returns, call the list endpoint again withbefore/afteror other filters; many list endpoints provide deterministic ordering useful for paging. -
Rate limiting and 429 responses: many routes are rate limited per-route and per-bucket. If a request returns a rate-limited response, the response body and headers indicate retry information. (The bridge surfaces the status and body; use the information returned to decide the next call.)
Practical tips for common user asks
-
When a user asks to "post in channel X in server Y", resolve
guild_idwithlist_my_guildsorget_guild, then find thechannel_idvialist_guild_channelsbefore callingcreate_message. -
When asked to "message user Z", create or fetch a DM channel with
create_dmand use the returnedchannel_id. -
When the request involves moderation (ban, role change, prune): find the
user_idbylist_guild_membersorsearch_guild_members, confirm therole_idwithlist_guild_roles, then callban_user_from_guild,add_guild_member_role, orprune_guildas appropriate. -
For slash command lifecycle: fetch
application_idviaget_my_application, list existing commands, then create/update viacreate_application_command/update_application_commandor their guild equivalents. Use bulk set endpoints when replacing all commands. -
For interaction follow-ups and edits: use
create_interaction_responsefor the initial callback. To edit or delete the original interaction response, use the webhook-style endpoints withwebhook_id=application_idandwebhook_token=interaction_token.
Focus on obtaining the specific IDs the next operation requires, and prefer endpoints that return expanded objects (via with_... flags) to reduce additional lookups. When a response is a union or optional, inspect discriminating fields rather than assuming a structure. This will keep workflows straightforward and predictable across the many resource variations the Discord API exposes.