API reference
Errors, limits and IDs
What failed requests look like, how fast you can go, and the formats used everywhere.
Errors
Failed requests answer with an HTTP status and a JSON body:
json
{
"error": {
"code": "missing_permission",
"message": "You don't have permission to send messages here.",
"field": null
}
}code is stable, so check that in your code. message is written for people and may change. field names the input that was wrong, when there is one.
| Status | Means |
|---|---|
400 | Something in the request isn't valid (see code and message) |
401 | No token, or the token is wrong (unauthorized) |
403 | Not allowed: a missing permission (missing_permission) or a route bots can't use (bots_not_allowed) |
404 | It doesn't exist, or your bot can't see it |
413 | A file is too big |
429 | Too fast (rate_limited, or slowmode in a channel with slowmode on) |
500 | Our fault. Try again in a bit |
Rate limits
| What | Limit |
|---|---|
| Sending messages and using commands | 5 every 5 seconds, per account (bots included) |
| Interaction follow-ups | Count toward your bot's message limit |
| Webhooks | 5 every 5 seconds, per webhook |
| Slowmode | Set per channel; Manage Messages and Manage Channels skip it |
When you hit a limit, wait a few seconds and try again. Don't retry in a tight loop.
Other limits
| What | Limit |
|---|---|
| Message length | 2000 characters |
| Files | 10 per message, 10 MB each |
| Applications | 25 per account |
| Commands | 100 everywhere, plus 100 per server; 25 options each |
| Reactions | 20 different emoji per message |
| Pins | 50 per channel |
IDs
Everything has an ID: a number that's unique across Bafflux and grows over time, so newer things have bigger IDs. IDs are sent as strings ("103745999999999999") because they're too big for JavaScript numbers. Keep them as strings.
Timestamps
Times are ISO 8601 in UTC, like "2026-10-14T03:12:45.120Z".