Skip to main content
The API is rate limited per category. Each endpoint belongs to a category, and the limit is counted either per guild or per API key, depending on the category.

Quotas

All windows are 60 seconds.
CategoryLimit per minuteCounted perEndpoints
lookup60GuildAll lookup endpoints
bindings_read100GuildGET /bindings/list
bindings_write30GuildAdd, update, remove, test, validate bindings
moderation_check300API keyBan status, mute status, Shield check and batch
moderation_read100GuildActive bans and mutes
moderation_write50GuildRoblox ban, unban, mute, unmute
config_read100GuildGuild roles
roblox_activity200API keyStaff permission lookups
staff_activity200API keyAction logging, game registration
staff_session100API keySession start and end
staff_heartbeat300API keyStaff heartbeat
server_heartbeat300API keyServer heartbeat
server_poll300API keyCommand polling
server_ack100API keyCommand acknowledgement
The high-frequency checks that a game runs per player join, ban and mute status and Shield, sit in moderation_check at 300 per minute per key, which is generous for normal play.

When you hit a limit

A request over the limit returns 429 with a Retry-After header.
429
{
  "status": "error",
  "code": 429,
  "message": "Rate limit exceeded. Please try again later.",
  "details": {
    "category": "moderation_write",
    "limit": 50,
    "window": 60,
    "retryAfter": 37
  }
}
These headers are set on a 429:
HeaderMeaning
Retry-AfterSeconds to wait before retrying
X-RateLimit-LimitThe category’s limit
X-RateLimit-RemainingRequests left in the window, 0 on a 429
X-RateLimit-ResetUnix timestamp when the window resets

Staying under the limit

  • Cache status checks. Ban and mute checks are already cached server-side for a short window. Avoid adding no_cache=true unless you truly need a live read.
  • Batch where you can. Use POST /lookup/status and POST /shield/batch instead of looping single requests.
  • Back off on 429. Respect Retry-After rather than retrying immediately.