Per-route rate limits
Per-route rate limits exist for many individual endpoints, and may include the HTTP method (GET, POST, PUT, or DELETE). In some cases, per-route limits are shared across a set of similar endpoints, indicated in the X-RateLimit-Bucket header. Use this header as a unique identifier for a rate limit to group shared limits as you encounter them.
During calculation, per-route rate limits often account for top-level resources within the path using an identifier — for example, guild_id when calling /guilds/{guild.id}/channels. Top-level resources are currently limited to:
- Channels (
channel_id) - Guilds (
guild_id) - Webhooks (
webhook_idorwebhook_id + webhook_token)
/channels/1234, you could still call /channels/9876 without a problem.
Global rate limits
Global rate limits apply to the total number of requests a bot or user makes, independent of any per-route limits. All bots can make up to 50 requests per second. If no authorization header is provided, the limit is applied to the IP address. Interaction endpoints are not bound to the bot’s global rate limit.Header format
For most API requests, Discord returns optional HTTP response headers containing the rate limit information encountered during your request.| Header | Description |
|---|---|
X-RateLimit-Limit | The number of requests that can be made |
X-RateLimit-Remaining | The number of remaining requests that can be made |
X-RateLimit-Reset | Epoch time (seconds since 00:00:00 UTC on January 1, 1970) at which the rate limit resets |
X-RateLimit-Reset-After | Total time (in seconds) until the current rate limit bucket resets. Can have decimals for millisecond precision. |
X-RateLimit-Bucket | A unique string denoting the rate limit being encountered (non-inclusive of top-level resources in the path) |
X-RateLimit-Global | Returned only on HTTP 429 responses if the rate limit encountered is the global rate limit (not per-route) |
X-RateLimit-Scope | Returned only on HTTP 429 responses. Value can be user, global, or shared |
Exceeding a rate limit
When a rate limit is exceeded, the API returns an HTTP 429 response code with a JSON body. Your application should rely on theRetry-After header or retry_after field to determine when to retry the request.
Rate limit response structure
| Field | Type | Description |
|---|---|---|
message | string | A message saying you are being rate limited |
retry_after | float | The number of seconds to wait before submitting another request |
global | boolean | A value indicating if you are being globally rate limited or not |
code? | integer | An error code for some limits |
Example responses
- User rate limit
- Global rate limit
Global rate limit bans
If your bot gets big enough, based on its functionality, it may be impossible to stay below 50 requests per second during normal operations. Global rate limit issues generally show up as repeatedly getting banned from the Discord API when your bot starts.If your bot gets temporarily Cloudflare banned every once in a while, it is most likely not a global rate limit issue. You probably had a spike of errors that was not properly handled and hit the error threshold.
Invalid request limit
IP addresses that make too many invalid HTTP requests are automatically and temporarily restricted from accessing the Discord API. Currently, this limit is 10,000 invalid requests per 10 minutes. An invalid request is one that results in 401, 403, or 429 statuses. All applications should make reasonable attempts to avoid invalid requests:- 401 responses are avoided by providing a valid token in the authorization header when required and stopping further requests after a token becomes invalid.
- 403 responses are avoided by inspecting role or channel permissions before making requests restricted by such permissions.
- 429 responses are avoided by inspecting the rate limit headers and not making requests on exhausted buckets until after they reset.
429 errors returned with
X-RateLimit-Scope: shared are not counted against the invalid request limit.