Errors
Every error has the same shape and a stable code. Branch on the code, never on the message.
On this page
The error shape
Every REST error answers with a 4xx or 5xx status and this body:
{"error": {"code": "missing_permission", "message": "you do not have permission to do that"}}
codeis stable and machine readable. Branch on it.messageis for people and may change at any time. Log it, show it to your users if you like, but never compare it.
A few errors carry extra details. For example, a message refused by a server's AutoMod rule (400 auto_moderation_blocked) also carries auto_moderation with the trigger type and the server's custom message; see Send message.
The Log in with Palloo token, userinfo and revocation endpoints answer in the OAuth shape instead ({"error": "invalid_grant", "error_description": "..."}), as OAuth libraries expect. See Log in with Palloo.
Things worth knowing
- 404 hides what you cannot see. A server your bot is not in, or a channel it cannot view, answers 404 (
community_not_found,channel_not_found) exactly like one that does not exist. Check membership and View Channel before assuming an ID is wrong. - Unknown fields are refused. A body with a field the operation does not define answers
400 invalid_body, as does a body that is not a single JSON object. 429 rate_limitedand503 rate_limiter_unavailableboth carryRetry-After. See Rate limits.500 internalmeans something failed on Palloo's side. Retry later with backoff.
Codes the bot and app operations can return
Generated from the error codes in the server's OpenAPI document, version 0.1.0. A code is listed here when an operation in the API reference documents it. The status is the HTTP status the code comes with.
| Code | Status | Meaning |
|---|---|---|
age_restriction_not_allowed |
400 | |
attachment_not_found |
404 | No such attachment, or the caller cannot see its channel. |
auto_moderation_blocked |
400 | An AutoMod rule refused the message. |
auto_moderation_disabled |
403 | |
auto_moderation_rule_limit |
409 | The community has the most rules of that trigger type. |
auto_moderation_rule_not_found |
404 | |
ban_not_found |
404 | |
blocking_user |
409 | The caller blocked the recipient. |
bot_required |
403 | Only bot accounts can do this. |
bots_not_allowed |
403 | Bot accounts cannot do this. |
cannot_ban_owner |
403 | Nobody can ban the owner. |
cannot_ban_self |
409 | |
cannot_kick_owner |
403 | Nobody can kick the owner. |
cannot_kick_self |
409 | |
cannot_set_member_profile |
400 | |
cannot_target_self |
409 | |
cannot_timeout_owner |
403 | |
cannot_timeout_self |
409 | |
cannot_view_thread |
403 | |
channel_limit_reached |
409 | The community has 500 channels (categories count). |
channel_not_found |
404 | No such channel, or the caller is not a member of its community or cannot view the channel. |
channel_not_text |
409 | Messages only exist in text channels. |
channel_not_voice |
409 | |
command_limit_reached |
409 | |
command_not_found |
404 | No such command for this channel (its bot is not in the community or cannot view the channel). |
community_not_found |
404 | No such community, or the caller is not a member. |
content_type_mismatch |
400 | The body is not what the slot was created for. |
directory_disabled |
403, 404 | This instance has no public directory. |
directory_requirements_unmet |
409 | The message names the unmet requirement keys. |
dm_not_allowed |
403 | The recipient does not accept DMs from the caller (a block looks the same). |
everyone_role |
400 | |
file_too_large |
413 | |
file_too_large_to_scan |
403, 413 | |
gateway_unavailable |
503 | This server is shutting down. |
image_too_large |
400 | |
interaction_already_acknowledged |
409 | It was answered before. |
interaction_expired |
409 | |
interaction_not_acknowledged |
409 | Answer it first. |
interaction_not_deferred |
409 | It was not deferred, or was already completed. |
interaction_not_found |
404 | No such interaction for the calling bot, or the token is wrong. |
internal |
500 | An unexpected server error. |
invalid_answer |
400 | The message is not a message of this thread. |
invalid_attachment |
400 | |
invalid_auto_archive_duration |
400 | |
invalid_auto_moderation_rule |
400 | |
invalid_banner_color |
400 | |
invalid_bio |
400 | |
invalid_bitrate |
400 | |
invalid_body |
400 | The body is not a single JSON object matching the schema. |
invalid_category |
400 | |
invalid_channel_kind |
400 | |
invalid_color |
400 | |
invalid_command |
400 | |
invalid_content |
400 | |
invalid_description |
400 | |
invalid_display_name |
400 | |
invalid_emoji |
400 | Not one Unicode emoji. |
invalid_expiry |
400 | |
invalid_image |
400 | |
invalid_interaction_response |
400 | |
invalid_keywords |
400 | |
invalid_language |
400 | |
invalid_max_uses |
400 | |
invalid_name |
400 | |
invalid_nickname |
400 | |
invalid_nonce |
400 | |
invalid_parent |
400 | |
invalid_permissions |
400 | |
invalid_positions |
400 | |
invalid_pronouns |
400 | |
invalid_public_channel |
400 | Only text channels (not threads, voice channels or categories) can be public. |
invalid_public_web |
400 | |
invalid_query |
400 | More than one cursor, a cursor that is not a message ID. |
invalid_reason |
400 | |
invalid_reference |
400 | |
invalid_rules_channel |
400 | |
invalid_setting |
400 | |
invalid_thread |
400 | The channel is not a public thread. |
invalid_thread_change |
400 | |
invalid_thread_kind |
400 | |
invalid_thread_parent |
400 | |
invalid_timeout |
400 | |
invalid_token |
400, 401 | Unknown, expired, used, or for an address the account no longer has. |
invalid_topic |
400 | |
invalid_upload |
400 | |
invalid_user_limit |
400 | |
invalid_vanity_code |
400 | |
invite_limit_reached |
409 | The community, or the caller in it, has the maximum number of active invites. |
invite_not_found |
404 | The invite code is unknown, expired, used up or revoked. |
last_text_channel |
409 | A community must keep at least one text channel. |
listing_delisted |
409 | Instance admins delisted it. |
listing_not_found |
404 | No such listing, or it is not visible. |
managed_role |
400 | A bot's managed role cannot be deleted, assigned or removed. |
member_not_found |
404 | The target is not a member. |
message_not_found |
404 | The message does not exist in this channel. |
mfa_sudo_required |
403 | The account has MFA and this session has not verified a factor in the last 5 minutes. |
missing_permission |
403 | The caller is a member but lacks the permission. |
moderation_mfa_required |
403 | |
name_reserved |
400 | |
not_in_voice |
409 | The caller is not in a voice channel of this server. |
not_thread |
400 | The channel is not a thread. |
oidc_disabled |
404 | |
organization_not_found |
404 | No pending invitation. |
overwrite_limit_reached |
409 | The channel has 100 overwrites. |
owner_cannot_leave |
409 | The owner must delete the community instead. |
pin_limit_reached |
409 | The channel already has 50 pins. |
public_channel_age_restricted |
409 | The channel is age-restricted. |
public_channel_not_everyone |
409 | |
public_channels_disabled |
404 | |
public_web_needs_scanner |
409 | The instance has no upload scanner. |
rate_limited |
429 | Too many attempts. |
reaction_limit_reached |
409 | The message already has 20 different emoji. |
reactions_disabled |
403 | |
reference_not_found |
400 | |
replies_disabled |
403 | |
role_hierarchy |
403 | |
role_limit_reached |
409 | |
role_not_found |
404 | |
scan_unavailable |
503 | |
sensitive_media_disabled |
400 | |
sticker_explicit |
400 | |
sticker_too_large |
400 | |
sticker_too_slow |
400 | |
stickers_disabled |
403 | |
storage_unavailable |
503 | File storage could not be reached. |
system_message |
400 | System messages cannot be pinned. |
terms_acceptance_required |
403 | The instance's terms of service changed (or were never accepted) and this account has not accepted the current version. |
thread_archived |
409 | Unarchive the thread first. |
thread_exists |
409 | |
thread_limit_reached |
409 | |
thread_locked |
403 | |
thread_member_limit_reached |
409 | |
thread_member_not_found |
404 | |
thread_user_limit_reached |
409 | |
threads_disabled |
403 | |
tier_required |
403 | |
timed_out |
403 | |
timeout_not_found |
404 | |
too_many_attachments |
400 | |
too_many_files |
400 | |
too_many_syncs |
400 | |
topic_not_allowed |
400 | |
unauthenticated |
401 | The bearer token is missing, invalid or expired. |
unsupported_type |
400 | |
upgrade_required |
426 | The request was not a WebSocket upgrade. |
upload_already_received |
409 | |
upload_changed |
409 | |
upload_expired |
410 | The slot or the finished upload expired. |
upload_incomplete |
409 | |
upload_limit_reached |
409 | 50 unfinished uploads. |
upload_malware |
400, 429 | |
upload_not_found |
404 | No such slot, or the token is wrong. |
upload_processing |
503 | |
upload_quota_exceeded |
400, 429 | |
upload_rejected |
400, 429 | |
upload_size_mismatch |
400 | |
uploads_paused |
403 | |
uploads_restricted |
403 | |
user_not_found |
404 | |
vanity_not_found |
404 | |
vanity_reserved |
409 | |
vanity_taken |
409 | The receiving community could not take the code. |
voice_channel_full |
409 | |
voice_disabled |
403 | |
voice_setting_not_allowed |
400 | |
webhook_disabled |
403 | The webhook's creator is suspended (any message), or the creator no longer has an account (messages with files, which are charged to the creator). |
webhook_limit_reached |
409 | |
webhook_not_found |
404 | No such webhook, or the token is missing or wrong. |
Codes for people's accounts and staff
These come from operations a bot cannot call, such as signing in, sessions and instance administration. They are listed so that every code in the API is documented.
| Code | Status | Meaning |
|---|---|---|
account_moved |
403 | |
account_moves_disabled |
403 | |
account_pending_deletion |
403 | |
account_suspended |
403 | An instance admin, or the server after an upload matched an abuse hash list, suspended the account. |
admin_required |
403 | The caller has no instance role. |
already_friends |
409 | |
already_member |
409 | The caller is a member. |
applicant_suspended |
409 | |
backup_limit_reached |
409 | |
backup_not_found |
404 | |
backup_not_ready |
409 | |
backup_not_revocable |
409 | |
backup_revoked |
403 | |
backup_too_large |
413 | |
badge_not_found |
404 | An unknown key. |
badge_not_grantable |
400 | |
badge_not_held |
404 | |
badge_not_hideable |
400 | |
banned |
403 | The invite is for a community this account is banned from. |
blocklist_not_published |
404 | This instance keeps its block list private. |
body_too_large |
413 | More than 64 KiB. |
bot_creation_disabled |
403 | |
bot_limit_reached |
409 | |
bot_not_found |
404 | No such bot, or the caller does not own it. |
bot_private |
403 | The bot is private and the caller is not its owner. |
cannot_act_on_instance_staff |
403 | |
cannot_act_on_own_report |
403 | |
cannot_change_owner |
409 | The target is the owner. |
cannot_remove_domain_owner |
409 | The owner deletes the domain instead. |
cannot_remove_organization_owner |
409 | |
cannot_report_self |
400 | |
cannot_transfer_to_bot |
409 | |
cannot_transfer_to_self |
409 | |
captcha_failed |
403 | The instance uses a captcha and the token was missing or rejected. |
captcha_required |
403 | After repeated failures, solve the captcha and send its token with the same credentials. |
captcha_unavailable |
503 | The captcha provider could not be reached. |
checksum_mismatch |
400 | |
community_backup_disabled |
404 | |
community_backup_unavailable |
503 | |
community_full |
409 | The invite's community is at its member limit (the check is exact under concurrent joins). |
community_limit_reached |
409 | The user is already in 200 communities. |
community_linked |
409 | |
community_restoring |
Varies | |
confirmation_mismatch |
400 | |
content_deletion_disabled |
400 | |
content_hold_reason_required |
400 | |
delegation_not_configured |
Varies | |
deletion_not_pending |
409 | The account is active. |
discord_rate_limited |
503 | Discord is limiting this instance, or the instance has made as many template lookups as it allows for now. |
discord_templates_disabled |
403 | The instance has template import turned off. |
discord_unavailable |
502 | Discord could not be reached or answered with an error. |
domain_already_claimed |
409 | |
domain_claim_limit_reached |
429 | The account made 10 claims of any kind in the last day, including removed ones, since each claim makes the server run DNS and HTTPS checks. |
domain_limit_reached |
409 | |
domain_member_exists |
409 | |
domain_member_limit_reached |
409 | |
domain_member_not_found |
404 | |
domain_not_active |
409 | |
domain_not_found |
404 | No such domain, or it is not yours. |
domain_not_shared |
409 | |
domain_not_verified |
409 | |
domain_owner_required |
403 | |
domain_request_limit_reached |
409 | |
domain_reserved |
403 | |
domain_taken |
409 | |
email_already_verified |
409 | |
email_not_set |
409 | |
email_required |
400 | The instance requires an address, so it cannot be removed. |
email_taken |
409 | Another account already verified this address. |
entitlement_not_found |
404 | |
entitlement_required |
403 | |
export_not_found |
404 | Unknown, another user's, or expired. |
export_not_ready |
409 | Still being built, or it failed. |
feature_beta_not_found |
400 | |
feature_beta_scope |
400 | |
feature_not_found |
404 | |
feature_not_tier_unlockable |
400 | |
feature_tier_required |
400 | |
feature_unchanged |
409 | The flag is already set that way. |
foreign_archive |
400 | |
gif_busy |
503 | |
gif_direct |
404 | |
gif_favorite_limit |
409 | The account already has 500 favorites. |
gif_favorite_not_found |
404 | |
gif_proxy |
404 | |
gif_unavailable |
502 | The provider failed and nothing is cached. |
gifs_disabled |
403 | |
handle_taken |
409 | |
hub_token_expired |
400 | |
hub_token_untrusted |
400 | |
hub_token_wrong_instance |
400 | |
ineligible_user |
409 | Remote or deleted accounts have no keys here. |
invalid_action |
400 | |
invalid_archive |
400, 415 | |
invalid_backup_signature |
400 | |
invalid_badge_grant |
400 | |
invalid_credential |
400 | The response does not verify (wrong origin, challenge or relying party, or a malformed response). |
invalid_credentials |
401 | |
invalid_decision |
400 | |
invalid_domain |
400 | |
invalid_domain_kind |
400 | |
invalid_download_link |
403 | |
invalid_email |
400 | |
invalid_entitlement |
400 | |
invalid_feature_beta |
400 | |
invalid_feature_mode |
400 | |
invalid_feature_percentage |
400 | |
invalid_feature_tier |
400 | |
invalid_gif |
400 | Not a GIF from this instance's provider, or the ID differs from the path. |
invalid_handle |
400 | |
invalid_hub_token |
400 | |
invalid_join |
400 | |
invalid_key_name |
400 | |
invalid_mfa |
401, 403 | The code or key was wrong, or the ticket is unknown, expired, used up or for another purpose. |
invalid_mfa_code |
400 | The code does not match. |
invalid_move_target |
400 | The name must follow the username rules (2 to 32 letters, digits. |
invalid_note |
400 | |
invalid_oauth_client |
400 | |
invalid_options |
400 | |
invalid_organization |
400 | |
invalid_password |
400 | |
invalid_policy_level |
400 | |
invalid_profile_reset |
400 | |
invalid_push_subscription |
400 | |
invalid_report |
400 | |
invalid_search |
400 | A parameter is malformed or out of range (the message says which), or the search has neither content nor a filter. |
invalid_search_scope |
400 | The channel is not a DM. |
invalid_setup_token |
403 | The setup token is wrong, was already used, or the instance already has an owner. |
invalid_share |
400 | The token was not issued by this instance. |
invalid_signature |
401 | |
invalid_status |
400 | |
invalid_sticker |
Varies | |
invalid_sticker_description |
400 | |
invalid_sticker_name |
400 | |
invalid_sticker_tags |
400 | |
invalid_sticker_upload |
400 | |
invalid_takedown |
400 | |
invalid_template_code |
400 | The code is not 8 to 32 letters and digits. |
invalid_transition |
409 | |
invalid_username |
400 | |
invite_not_for_signup |
403 | |
invite_required |
403 | Signup needs an invite code. |
key_already_registered |
409 | |
key_not_found |
404 | |
listing_state_conflict |
409 | |
mfa_disabled |
403 | |
mfa_method_unavailable |
409 | The account has no security key. |
mfa_not_enabled |
409 | |
mfa_required |
200, 403 | The account has MFA, so the reset also needs a second factor. |
mfa_setup_not_found |
404 | No setup was started, or it expired. |
no_content_hold |
409 | |
no_terms |
404 | The instance has no terms version configured. |
not_community_owner |
403 | |
not_found |
404 | Voice is off. |
not_permitted |
403 | |
not_suspended |
409 | |
oauth_client_has_no_secret |
409 | |
oauth_client_not_found |
404 | |
oauth_grant_not_found |
404 | |
oauth_invalid_client |
400 | |
oauth_invalid_redirect_uri |
400 | |
oauth_invalid_request |
400 | |
organization_closed |
409 | |
organization_community_limit_reached |
409 | |
organization_exists |
409 | |
organization_invite_not_allowed |
403 | |
organization_limit_reached |
409 | |
organization_member_exists |
409 | |
organization_member_limit_reached |
409 | |
organization_not_approved |
409 | |
organization_owner_required |
403 | |
over_limits |
409 | |
owner_cannot_delete |
409 | |
owner_cannot_move |
409 | |
owner_mfa_required |
403 | |
owner_required |
403 | The admin applied for, belongs to or is invited to the organization. |
owns_communities |
409 | |
policy_exists |
409 | The normalized domain already has a policy. |
policy_not_found |
404 | |
public_web_busy |
Varies | |
push_disabled |
503 | This instance has no VAPID keys configured. |
push_endpoint_not_allowed |
400 | |
push_subscription_not_found |
404 | |
rate_limiter_unavailable |
Varies | |
reason_required |
400 | |
reauthentication_required |
403 | |
registration_closed |
403 | This instance does not allow signup. |
relationship_limit_reached |
409 | The caller already has 1000 friends and outgoing requests. |
relationship_not_found |
404 | The caller has no such relationship with that user. |
report_duplicate_open |
409 | Reopening this report would give its reporter two open reports about the same message or user, because they filed a newer one that is still open. |
report_limit_reached |
409 | The caller has 20 open reports. |
report_not_found |
404 | No such report, or one the caller may not see (another scope or community, a channel they cannot read, or a report about themselves or a webhook or bot they control). |
request_not_allowed |
403 | The target does not accept friend requests from the caller. |
restore_in_progress |
409 | |
restore_not_found |
404 | |
restore_uploads_busy |
503 | |
search_disabled |
403 | Search is turned off on this instance. |
search_unavailable |
503 | The search took longer than 3 seconds or the pod is already running its maximum of searches. |
sensitive_media_locked |
403 | |
session_not_found |
404 | |
signing_keys_unavailable |
503 | PALLOO_INSTANCE_SECRET is not configured. |
staff_mfa_required |
403 | |
sticker_name_taken |
409 | |
sticker_not_found |
404 | |
sticker_not_usable |
Varies | |
sticker_slots_full |
409 | |
subject_not_found |
404 | |
template_changed |
409 | The template no longer maps to the previewed plan. |
template_channel_limit |
409 | |
template_not_found |
404 | Discord does not know the template, or it expired. |
template_overwrite_limit |
409 | A channel has more than 100 permission overwrites. |
template_overwrite_total_limit |
409 | The template has more than 2000 permission overwrites. |
template_role_limit |
409 | |
template_unreadable |
502 | Discord's answer could not be read as a template. |
terms_outdated |
409 | |
terms_required |
400 | |
thread_overwrites |
Varies | |
too_many_keys |
409 | An account has at most 10. |
too_many_stickers |
Varies | |
totp_already_enabled |
409 | Remove the current app first. |
totp_not_enabled |
404 | |
transfer_target_ineligible |
409 | |
unknown_issuer |
400 | |
unsupported_archive |
400 | |
username_taken |
409 | |
wrong_password |
403 | The current password is incorrect. |