Everything an AI agent can do with the Discord API.

A reference guide for building AI agents: every method, how to authenticate, and the permissions each one needs.

Endpoints34
API versionv10
Last updated23 June 2026
Orientation

How the Discord API works.

The Discord API is how an app or AI agent works with a Discord server: posting messages to a channel, reading message history, managing channels and roles, and updating the members of a server. Access uses a bot token or an OAuth2 token, and Discord's permission system decides, channel by channel, what each call can read or write. A bot also receives activity in real time over a persistent connection, so it learns about new messages and members without polling.

34Endpoints
8Capability groups
14Read
20Write
13Permissions
Authentication
Discord uses two token types in the Authorization header. A bot token, sent as 'Bot ', authenticates an application's bot and is the usual way an agent acts in a server. An OAuth2 bearer token, sent as 'Bearer ', acts for a user who authorized the app and is limited to the scopes they granted. An incoming webhook is a third route: its token in the URL alone authorizes posting to one channel, with no bot token needed.
Permissions
What a bot can do is set by Discord's permission system, a bitfield where each bit is one permission, like VIEW_CHANNEL, SEND_MESSAGES, MANAGE_MESSAGES, MANAGE_CHANNELS, MANAGE_ROLES, or MANAGE_GUILD. Permissions are granted through the bot's roles and per-channel overwrites, so the same bot can be allowed in one channel and blocked in another. Listing members or reading message content additionally needs a privileged intent enabled on the app, separate from channel permissions. OAuth2 calls instead depend on scopes like identify, guilds, and applications.commands.
Versioning
The API version is a whole number in the request path, like /api/v10. Version 10 is the current stable version and the one new integrations target; v9 remains available, while v8, v7, and v6 are deprecated and v6 is the legacy default when no version is given. v10 made message content a privileged intent and moved the audit-log reason to the X-Audit-Log-Reason header. Discord gives at least a year of deprecation notice before a version is removed.
Data model
Discord is organized around guilds (servers), which contain channels, which hold messages. A user in a guild is a member, and a member's access comes from roles, each carrying a permissions bitfield. Most write endpoints nest under a channel or guild id, like /channels/{id}/messages and /guilds/{id}/members/{id}. A bot receives changes in real time over a persistent Gateway connection rather than polling, and an incoming webhook can post into a single channel without a bot user.
Connect & authenticate

Connection & authentication methods.

How an app or AI agent connects to Discord determines what it can reach. There is a route for making calls, a route for receiving real-time events, and incoming webhooks for posting into a single channel, and each is governed by the token behind it and the permissions that token carries.

Ways to connect

REST API

The REST API answers at https://discord.com/api/v10, and a request authenticates with the Authorization header carrying either a bot token (Bot ) or an OAuth2 bearer token (Bearer ). The version number lives in the path, and v10 is the current stable version.

Best forConnecting an app or AI agent to Discord.
Governed byThe bot token or bearer token and the permissions or scopes it carries.
Docs ↗

Gateway (real-time events)

The Gateway is a persistent WebSocket connection that pushes events to a bot as they happen, like a message being posted or a member joining, so the bot does not poll. Which events arrive is set by the gateway intents the bot enables, and message content and guild members are privileged intents that must be granted.

Best forReceiving Discord events in real time at a bot.
Governed byThe bot token and the gateway intents it has enabled.
Docs ↗

Incoming webhook

An incoming webhook posts messages into one channel without a bot user. The webhook id and token in the URL are the only authorization, so a call needs no bot token and no permission once the webhook exists. Anyone holding the token can post to that channel.

Best forPosting messages into a single channel from an app or AI agent.
Governed byThe webhook token in the URL.
Docs ↗

MCP server (Model Context Protocol)

Discord does not publish an official Model Context Protocol server as of June 2026. Several community-built MCP servers wrap the Discord API for AI agents, but none is operated or endorsed by Discord, so each carries the security and maintenance posture of its own author.

Best forNot an official route; community MCP servers exist but are unofficial.
Governed byThe bot token configured in the community server.
Docs ↗
Authentication

Bot token

A bot token authenticates an application's bot user and is sent as 'Authorization: Bot '. It is the main way an agent calls the API on its own behalf. What the bot can do is decided by the permissions it holds in each guild and channel, granted through the bot's roles and permission overwrites.

TokenBot token (Authorization: Bot )
Best forAn agent acting as a bot in a server.
Docs ↗

OAuth2 bearer token

An OAuth2 bearer token acts on behalf of a user who authorized the app, and is sent as 'Authorization: Bearer '. It is limited to the scopes the user granted, like identify for the user's account, guilds for their server list, and email for their email address.

TokenBearer token (Authorization: Bearer )
Best forActing for a user who logged in with Discord.
Docs ↗

bot scope + permissions bitfield

The bot OAuth2 scope adds a bot to a server the authorizing user picks. The install link carries a permissions value, a bitfield where each bit is one permission like SEND_MESSAGES or MANAGE_CHANNELS, that sets the bot's starting permissions in that server. The applications.commands scope, included with bot by default, lets the app register slash commands.

Tokenbot scope (install flow, not a call token)
Best forAdding an agent's bot to a server with a chosen set of permissions.
Docs ↗

Webhook token

An incoming webhook has its own id and token, and that token alone authorizes posting a message into the webhook's channel. It is not a bot token and carries no other access, so it can post but cannot read or manage anything.

TokenWebhook token (in the request URL)
Best forPosting into one channel without a bot.
Docs ↗
Capability map

What an AI agent can do in Discord.

The Discord API is split into areas an agent can act on, like channels, messages, guild members, and roles. Each method needs the right permission in the channel or guild, and some, like managing roles or members, reach far more than posting a message.

Endpoint reference

Every Discord API method.

Filter by method, access, or permission, or search any path. Select a row for version detail, rate limits, the related webhook event, and the source.

MethodEndpointWhat it doesAccessPermissionVersion

Channels

Read a channel's details, modify its settings, and delete a channel or close a direct message.3

Requires a bot token. The bot must be able to see the channel, which the VIEW_CHANNEL permission controls.

Acts onchannel
Permission (capability)VIEW_CHANNEL
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Requires MANAGE_CHANNELS for a guild channel; editing permission overwrites also needs MANAGE_ROLES.

Acts onchannel
Permission (capability)MANAGE_CHANNELS
VersionAvailable since the API’s base version
Webhook eventchannel_update
Rate limitStandard limits apply

Requires MANAGE_CHANNELS for a guild channel, or MANAGE_THREADS for a thread. Deleting a channel cannot be undone.

Acts onchannel
Permission (capability)MANAGE_CHANNELS
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Messages

List and read messages, post new ones, edit and delete them, bulk-delete, and add reactions.7

Needs both VIEW_CHANNEL and READ_MESSAGE_HISTORY. Reading the text of a message over the Gateway also needs the message content privileged intent, but the REST read here returns content directly.

Acts onmessage
Permission (capability)READ_MESSAGE_HISTORY
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Needs both VIEW_CHANNEL and READ_MESSAGE_HISTORY.

Acts onmessage
Permission (capability)READ_MESSAGE_HISTORY
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Requires SEND_MESSAGES, and SEND_MESSAGES_IN_THREADS to post in a thread. The bot must also have VIEW_CHANNEL.

Acts onmessage
Permission (capability)SEND_MESSAGES
VersionAvailable since the API’s base version
Webhook eventmessage_create
Rate limitStandard limits apply

A bot can edit its own messages with no extra permission; editing another author's message flags, or otherwise managing the message, needs MANAGE_MESSAGES. On v10, attachments not listed in the edit are removed.

Acts onmessage
Permission (capability)MANAGE_MESSAGES
VersionAvailable since the API’s base version
Webhook eventmessage_update
Rate limitStandard limits apply

A bot can delete its own message without MANAGE_MESSAGES; deleting anyone else's needs MANAGE_MESSAGES.

Acts onmessage
Permission (capability)MANAGE_MESSAGES
VersionAvailable since the API’s base version
Webhook eventmessage_delete
Rate limitStandard limits apply

Requires MANAGE_MESSAGES. Limited to 2 to 100 messages, and it will not delete messages older than two weeks.

Acts onmessage
Permission (capability)MANAGE_MESSAGES
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Always needs READ_MESSAGE_HISTORY, and additionally ADD_REACTIONS when no one has yet reacted with this emoji.

Acts onreaction
Permission (capability)ADD_REACTIONS
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Guilds (servers)

Read a guild's details, modify its settings, and list or create the channels inside it.4

Requires a bot token, and the bot must be a member of the guild. No specific permission is required.

Acts onguild
Permission (capability)None required
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Requires the MANAGE_GUILD permission.

Acts onguild
Permission (capability)MANAGE_GUILD
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Returns channels the bot can see. No specific permission is required beyond guild membership.

Acts onchannel
Permission (capability)None required
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Requires MANAGE_CHANNELS. Setting permission overwrites on the new channel also needs MANAGE_ROLES.

Acts onchannel
Permission (capability)MANAGE_CHANNELS
VersionAvailable since the API’s base version
Webhook eventchannel_create
Rate limitStandard limits apply

Guild members

List members, read a single member, modify a member, and add or remove a member's roles.5

Requires the guild members privileged intent to be enabled on the application. This intent is the permission this list depends on, not a channel permission.

Acts onguild member
Permission (capability)GUILD_MEMBERS intent
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

No specific permission is required for a single member by id.

Acts onguild member
Permission (capability)None required
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

The permission depends on the field changed: MANAGE_NICKNAMES for nickname, MANAGE_ROLES for roles, and MUTE_MEMBERS, DEAFEN_MEMBERS, MOVE_MEMBERS, or MODERATE_MEMBERS for voice and timeout fields.

Acts onguild member
Permission (capability)MANAGE_ROLES
VersionAvailable since the API’s base version
Webhook eventguild_member_update
Rate limitStandard limits apply

Requires MANAGE_ROLES, and the bot's own highest role must sit above the role being granted.

Acts onguild member
Permission (capability)MANAGE_ROLES
VersionAvailable since the API’s base version
Webhook eventguild_member_update
Rate limitStandard limits apply

Requires MANAGE_ROLES, and the bot's own highest role must sit above the role being removed.

Acts onguild member
Permission (capability)MANAGE_ROLES
VersionAvailable since the API’s base version
Webhook eventguild_member_update
Rate limitStandard limits apply

Roles

List the roles in a guild and create a new role.2

No specific permission is required to read the role list.

Acts onrole
Permission (capability)None required
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Requires MANAGE_ROLES. A role's own permissions are a bitfield, so creating one can hand out further access.

Acts onrole
Permission (capability)MANAGE_ROLES
VersionAvailable since the API’s base version
Webhook eventguild_role_create
Rate limitStandard limits apply

Users

Read the current user, read a user by id, modify the current user, list the user's guilds, and open a direct message.5

With a bot token this returns the bot. With an OAuth2 bearer token it needs the identify scope, and the email field requires the email scope.

Acts onuser
Permission (capability)identify
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Requires a bot token. No OAuth2 scope is required for public profile fields.

Acts onuser
Permission (capability)None required
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Acts on the authenticated account itself, so no extra scope is required.

Acts onuser
Permission (capability)None required
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

With a bot token this lists the bot's guilds. With an OAuth2 bearer token it needs the guilds scope.

Acts onguild
Permission (capability)guilds
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

No specific scope is required to open the DM, but the bot still needs to share a guild with the user to message them.

Acts onchannel
Permission (capability)None required
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Webhooks

List a channel's or guild's webhooks, create a webhook, read one, and execute a webhook to post a message.4

Requires the MANAGE_WEBHOOKS permission.

Acts onwebhook
Permission (capability)MANAGE_WEBHOOKS
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Requires the MANAGE_WEBHOOKS permission.

Acts onwebhook
Permission (capability)MANAGE_WEBHOOKS
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Requires MANAGE_WEBHOOKS, unless the application itself owns the webhook.

Acts onwebhook
Permission (capability)MANAGE_WEBHOOKS
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Does not require a bot token or any permission; the webhook token in the URL is the authorization. Anyone holding that token can post to the channel.

Acts onwebhook
Permission (capability)None required
VersionAvailable since the API’s base version
Webhook eventmessage_create
Rate limitStandard limits apply

Application commands

List and create the global or guild slash commands an application registers, and bulk-overwrite the set.4

Managing an application's commands is tied to the applications.commands OAuth2 scope under which the app was authorized.

Acts onapplication command
Permission (capability)applications.commands
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Requires the applications.commands scope. Global commands can take up to an hour to roll out to all guilds.

Acts onapplication command
Permission (capability)applications.commands
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Requires the applications.commands scope. Guild commands appear in that guild immediately, unlike global ones.

Acts onapplication command
Permission (capability)applications.commands
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply

Requires the applications.commands scope. This overwrites the entire command set for the guild, removing any not included.

Acts onapplication command
Permission (capability)applications.commands
VersionAvailable since the API’s base version
Webhook eventNone
Rate limitStandard limits apply
No endpoints match those filters.
Webhooks

Webhook events.

Discord delivers real-time activity to a bot over a persistent Gateway connection, like a message being posted or a member joining, rather than the bot polling for changes. Which events arrive depends on the gateway intents the bot has enabled, and two of them, message content and guild members, are privileged.

EventWhat it signalsTriggered by
MESSAGE_CREATEFires when a message is posted in a channel the bot can see. Reading the message text needs the message content privileged intent, unless the bot is mentioned or it is a direct message./channels/{channel.id}/messages
/webhooks/{webhook.id}/{webhook.token}
MESSAGE_UPDATEFires when a message is edited./channels/{channel.id}/messages/{message.id}
MESSAGE_DELETEFires when a message is deleted from a channel./channels/{channel.id}/messages/{message.id}
CHANNEL_CREATEFires when a new guild channel is created./guilds/{guild.id}/channels
CHANNEL_UPDATEFires when a channel's settings change./channels/{channel.id}
GUILD_MEMBER_UPDATEFires when a guild member changes, like a nickname or role change. Receiving it needs the guild members privileged intent./guilds/{guild.id}/members/{user.id}
/guilds/{guild.id}/members/{user.id}/roles/{role.id}
/guilds/{guild.id}/members/{user.id}/roles/{role.id}
GUILD_MEMBER_ADDFires when a user joins a guild. Receiving it needs the guild members privileged intent.In-app only
GUILD_ROLE_CREATEFires when a new role is created in a guild./guilds/{guild.id}/roles
INTERACTION_CREATEFires when a user runs an interaction, such as a slash command the app has registered.In-app only
No events match that search.
Rate limits & pagination

Rate limits, pagination & request size.

Discord limits how fast an app or AI agent can call, through a global ceiling on requests per second and separate per-route limits that the response headers report as the agent goes.

Request rate

Discord applies a global limit of 50 requests per second across the whole API for a bot, on top of separate per-route limits. Per-route limits are grouped into buckets, and endpoints that act on a top-level resource, like a single channel, guild, or webhook, are counted independently per resource id, so the same call on two different channels does not share one quota. Each response carries the current state in headers: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-RateLimit-Reset-After, and X-RateLimit-Bucket, with X-RateLimit-Global and X-RateLimit-Scope added on a 429. Going over returns HTTP 429 with a retry_after value in the body. Separately, an IP that sends too many invalid requests, the 401, 403, and 429 responses, is temporarily blocked at the edge after 10,000 in 10 minutes.

Pagination

Message and member lists page by id rather than by page number. Get Channel Messages takes a limit of 1 to 100 (default 50) with before, after, or around an id; List Guild Members takes a limit up to 1000 with after the highest user id from the previous page. There is no total count, so a caller keeps requesting until a short page signals the end.

Request size

A single request body is capped at 8 MB for the default upload, and higher for boosted servers. Bulk Delete Messages takes 2 to 100 message ids at once and will not touch messages older than two weeks. A message's text content is limited to 2000 characters, or 4000 with an active Nitro-style boost.

Errors

Status codes & error handling.

The status codes an agent should handle, and what to do about each.

StatusCodeMeaningWhat to do
400BAD REQUESTThe request was improperly formatted, or the server could not understand it. A common case is JSON error code 50035, an invalid form body, where the errors object names the fields that failed validation.Read the errors object in the body, correct the named fields, and resend.
401UNAUTHORIZEDThe Authorization header was missing or invalid. JSON error code 40001 is returned when no valid token is provided.Send a valid bot token (Bot ) or bearer token (Bearer ) in the Authorization header.
403FORBIDDENThe token is valid but does not have permission for the resource. JSON error code 50001 is missing access, and 50013 is missing the permission needed for the action.Grant the bot the required permission, like SEND_MESSAGES or MANAGE_CHANNELS, in the channel or guild, then retry.
404NOT FOUNDThe resource does not exist. JSON error codes like 10003 unknown channel, 10004 unknown guild, 10008 unknown message, and 10013 unknown user point to which id was not found.Confirm the id in the path is correct and that the bot can see the resource.
405METHOD NOT ALLOWEDThe HTTP method used is not valid for the location specified.Use the method the endpoint documents, such as POST to create and PATCH to edit.
429TOO MANY REQUESTSA rate limit was hit. The JSON body carries retry_after in seconds and a global flag saying whether the global 50-per-second limit or a per-route limit was reached.Wait the retry_after seconds before retrying, and read the X-RateLimit headers to pace future calls.
502GATEWAY UNAVAILABLEThere was not a gateway available to process the request. This is a transient server-side condition.Retry the request after a short, increasing wait.
Versioning & freshness

Version history.

Discord versions its API by a whole number in the request path, and version 10 is the current stable version that new integrations target.

Version history

What changed, and when

Latest versionv10
v10Current version
Current stable version

Version 10 is the current stable version of the Discord API, targeted by new integrations and set in the request path as /api/v10. It made message content a privileged intent, so a bot must enable that intent to receive the text of most messages over the Gateway. It also moved the audit-log reason from the request body to the X-Audit-Log-Reason header, switched message routes to embeds instead of embed, and stopped serving v10 and later on the old discordapp.com domain. It was announced on 14 February 2022.

What changed
  • Message content became a privileged intent, enforced for verified bots on v10
  • Audit-log reason moved to the X-Audit-Log-Reason header
  • Message routes accept embeds instead of the singular embed
  • Attachments not listed when editing a message are removed
  • v10 and later are no longer served on the discordapp.com domain
v9
Previous stable version (still available)

Version 9 remains available for existing integrations. It predates the v10 change that made message content privileged, and Discord keeps it usable while encouraging new work on v10.

What changed
  • Remains an available version alongside v10
  • Does not require the message content privileged intent that v10 introduced
v6
Legacy default version (deprecated)

Version 6 is deprecated but remains the default version Discord uses when a request does not specify one in the path. Relying on the default is discouraged; integrations should pin v10 explicitly. Versions 8, 7, and 6 are all deprecated, and 5, 4, and 3 are discontinued.

What changed
  • Deprecated, but still the fallback default when no version is in the path
  • Pinning v10 in the path is recommended over relying on this default

An integration pins a version in the path and moves up when a newer one is ready.

Discord API changelog ↗
Questions

Discord API, answered.

Bot token or OAuth2 bearer token, which do I use?+
A bot token is the usual choice for an agent that acts on its own in a server: it authenticates the application's bot and is sent as 'Authorization: Bot '. An OAuth2 bearer token is for acting on behalf of a user who logged in with Discord, sent as 'Authorization: Bearer ', and is limited to the scopes that user granted, like identify or guilds. Many integrations use both: the bot scope to add the bot, and OAuth2 to identify users.
How do Discord permissions work for a bot?+
Permissions are a bitfield, where each bit is one permission such as VIEW_CHANNEL, SEND_MESSAGES, or MANAGE_CHANNELS. A bot gets permissions from its roles in a guild and from per-channel overwrites, so its access can differ channel by channel. When a bot is added, the install link's permissions value sets its starting permissions. A 403 with JSON error 50013 means the bot is missing the permission an action needs.
Why can't my bot read message content?+
Message content is a privileged intent. Since v10, a bot does not receive the text of most messages over the Gateway unless the message content intent is enabled on the application, though it still sees messages that mention it and direct messages. Reading a message through the REST API, like Get Channel Messages, returns content directly when the bot has VIEW_CHANNEL and READ_MESSAGE_HISTORY. Listing guild members similarly needs the guild members privileged intent.
What are the rate limits?+
A bot can make up to 50 requests per second globally across the whole API, and individual routes have their own per-bucket limits on top. Routes that act on a single channel, guild, or webhook are counted separately per resource id. The response headers, X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset-After, report where a route stands, and going over returns HTTP 429 with a retry_after value to wait. Sending too many invalid requests, 10,000 in 10 minutes, gets the IP temporarily blocked.
How do I receive events instead of polling?+
A bot connects to the Gateway, a persistent WebSocket, and Discord pushes events as they happen, like MESSAGE_CREATE when a message is posted or GUILD_MEMBER_ADD when someone joins. The bot declares which events it wants through gateway intents; message content and guild members are privileged intents that must be enabled on the application. This is the real-time channel, distinct from incoming webhooks, which only post messages out.
What's the difference between a bot and an incoming webhook?+
A bot is a full account that can read and write across the channels and guilds where it has permission, authenticated by a bot token. An incoming webhook is much narrower: it posts messages into one channel, authorized only by its own token in the URL, and cannot read messages or do anything else. A webhook is the simplest way to push notifications into a channel, while a bot is needed for anything interactive or read-based.
Which API version should I target?+
Version 10 is the current stable version, set in the request path as /api/v10, and it is what new integrations should use. Version 9 is still available, while v8, v7, and v6 are deprecated, and v6 is the default Discord falls back to when no version is in the path. Discord gives at least a year of notice before removing a version, so pinning v10 explicitly avoids surprises.
Related

More communication API guides for agents

What is Bollard AI?

Control what every AI agent can do in Discord.

Bollard AI sits between a team's AI agents and Discord. Grant each agent exactly the access it needs, read or write, channel by channel, and every call is checked and logged.

  • Set read, write, or full access per agent, never a shared bot token.
  • Denied by default, so an agent reaches only what has been explicitly allowed.
  • Every call recorded in plain English: who, what, where, and the decision.
Discord
Community Agent
Post to channels ActionOffReadFull use
Read message history ResourceOffReadFull use
Manage roles ActionOffReadFull use
Per-agent access, set in Bollard AI, not in Discord