Skip to content
donutchat.com

Errors

Look up an error from an incoming webhook, the bot HTTP API or the event stream to see what it means and what to change.

Most errors are JSON with "ok": false:

{
"ok": false,
"error": "not_in_chat",
"message": "Bot is not a member of this chat"
}

Use error in your code. message explains the problem for people.

These responses aren’t JSON:

StatusBodyCause
404404 page not found (plain text)The URL doesn’t match any endpoint, for example a webhook URL with a missing token or an extra / at the end.
405Empty, with an Allow headerWrong HTTP method. The chat list, attachment downloads and the event stream use GET; every other endpoint uses POST.
503server is not ready (plain text)DonutChat is restarting or in maintenance. Retry with backoff.
400 or 426Plain textA request to the event stream URL with a valid token but no WebSocket handshake.
NameEndpointReference
WebhookPOST /webhooks/v1/{webhook_id}/{token}Incoming webhooks API
MessagesPOST /bots/v1/messagesSend messages
ChatsGET /bots/v1/chatsSend messages
TypingPOST /bots/v1/typingSend messages
Thread repliesPOST /bots/v1/thread-repliesThread replies and streaming
Reply updatesPOST /bots/v1/thread-replies/streamThread replies and streaming
ActivityPOST /bots/v1/thread-replies/activityThread replies and streaming
AttachmentsGET /bots/v1/chats/{chat_id}/messages/…/attachments/{attachment_id}/contentAttachments
Event streamwss://api.donutchat.com/bots/v1/streamEvent stream
errorReturned byCause and fix
invalid_jsonWebhook, Messages, Thread replies, Reply updates, TypingThe body isn’t valid JSON, or a field has the wrong type. Send IDs as JSON numbers, not strings.
missing_contentWebhook, Messagescontent is missing or empty.
content_too_longWebhook, Messages, Thread replies, Reply updatescontent or content_chunk is over 80,000 UTF-8 bytes. Shorten the text or split it.
missing_chat_idMessages, Thread replies, Reply updates, Typingchat_id is missing or isn’t a positive number.
missing_parent_message_idThread replies, Reply updatesparent_message_id is missing or isn’t a positive number.
missing_reply_idReply updatesreply_id is missing or isn’t a positive number.
invalid_statusThread replies, Reply updatesCreate a reply with GN or OK; FL is only for updates, which accept GN, OK or FL. Mixed case such as Ok is rejected.
invalid_content_typeMessages, Thread repliescontent_type must be TX or MD.
invalid_avatar_urlMessages, Thread repliesavatar_url must be an absolute http:// or https:// URL with no spaces around it.
status_text_too_longTypingstatus_text is over 80 bytes. The message says characters, but the limit counts bytes.
invalid_activityActivityAn unknown field, an invalid value, a non-positive ID or sequence, extra data after the JSON, or a body over 4,096 bytes.
invalid_idAttachmentsAn ID in the path isn’t a positive 64-bit integer.
invalid_multipart, missing_payload, missing_file, empty_file, too_many_filesThread replies with filesSend one payload part and one to four non-empty file parts. See Attach files.

Every endpoint returns unauthorized. The message tells you which check failed:

messageCause and fix
Missing or invalid Authorization header. Use: Authorization: Bearer <token>No token, or the header isn’t exactly Bearer, a space and the token. On the event stream, you can pass ?token= instead.
Invalid bot tokenThe token is wrong or was regenerated, or the bot is paused. Use the current token, or switch the bot back on.
Bot bearer token requiredAn attachment download was sent without a token.
Invalid webhook tokenThe webhook URL is wrong, its token was rotated, or the webhook was deleted. Use the URL exactly as copied from the app.
errorReturned byCause and fix
not_in_chatMessages, Thread replies, Reply updates, Typing, ActivityThe bot isn’t an active member of the chat: it was never added or was removed, or the chat was deleted. Add the bot to the chat.
not_ownerReply updatesNo reply from this bot matches the reply_id, chat_id and parent_message_id. The reply may not exist, may be deleted or may belong to another bot. Use the IDs of the reply you created.
activity_unavailableActivityThe IDs don’t identify a reply from this bot, or the step can’t change that way, for example retrying without an earlier failed.
attachment_unavailableAttachmentsThe bot isn’t an active member of the chat.
webhook_disabledWebhookThe webhook is switched off. Switch it on in the app.
uploads_disabledThread replies with filesThe bot’s owner hasn’t turned on Allow file uploads.
execution_requiredMessages, Thread replies, Reply updates, ActivityPosting by this bot is paused in this chat. This is rare. Don’t retry in a loop.
errorReturned byCause and fix
not_foundWebhookThe webhook ID in the URL isn’t a number. Use the URL exactly as copied from the app.
attachment_unavailableAttachmentsThe file, message or reply doesn’t exist, was deleted or has expired, or the IDs don’t belong together. For a file in a top-level message, also when the bot was never added to the chat or was removed.
errorReturned byCause and fix
attachment_unavailableAttachmentsThe file is larger than 10 MiB, the most a bot can download.
file_too_large, payload_too_large, request_too_largeThread replies with filesA file is over 10 MiB, or the request is too large.
errorReturned byCause and fix
unsupported_file_typeThread replies with filesA file’s contents aren’t PNG, JPEG, GIF, WebP, PDF or UTF-8 text. Renaming a file or declaring another type doesn’t change this.
errorReturned byCause and fix
rate_limit_exceededWebhookMore than 60 requests in the past minute or 1,000 in the past hour for this webhook. Requests rejected for bad JSON or content count too. There’s no Retry-After header: wait, then retry with backoff.
busyAttachmentsToo many downloads at the moment. Retry later with backoff.
rate_limitedThread replies with filesThe bot uploaded 30 files in the past hour. Wait, then retry.
uploads_busyThread replies with filesToo many uploads at the moment. Retry with backoff.
errorReturned byCause and fix
send_failedWebhook, MessagesThe sender name is over 32 bytes: username, or the bot’s name when you don’t send username. Otherwise a server error.
create_failedThread repliesThe parent message doesn’t exist, was deleted, is in another chat or is itself a thread reply, or username is over 64 bytes. Otherwise a server error.
stream_failedReply updatesOverlapping updates to the same reply, or a server error. Send one update at a time per reply, then retry.
membership_check_failedThread replies, Reply updates, ActivityA temporary problem. Retry.
list_failedChatsA temporary problem. Retry.
typing_failedTypingThe typing indicator wasn’t sent. Retry or skip it.
upload_failedThread replies with filesThe files couldn’t be stored, and nothing was kept. Retry.
internal_errorEvent streamThe connection couldn’t start. Reconnect with backoff.
errorReturned byCause and fix
threads_unavailable, typing_unavailable, activity_unavailable, unavailable, stream_unavailable, uploads_unavailableThread replies, Typing, Activity, Attachments, Event streamThe feature is temporarily unavailable. Retry with backoff.

Once the connection is open, the event stream never sends error messages. It ends in one of these ways:

How it endsCauseWhat to do
Close code 1000, reason server shutdownAnother connection for the same bot replaced this one, or DonutChat is restarting.Run one copy of your integration, and reconnect with backoff.
No close frame (code 1006 or end of stream)Your client sent nothing for 5 minutes, didn’t answer a ping within 10 seconds or read events too slowly, or the network failed.Send a short text frame every minute or two, and reconnect with backoff and last_event_id.
  • For 400, 401, 403, 404 and 413, fix the request. Sending it again unchanged fails again.
  • For 429, 500 and 503, retry with exponential backoff, after checking the causes listed above.
  • Creating a message or reply isn’t idempotent: if a create request times out without a response, it may already have posted, and retrying can post it twice. Retrying a reply update with the full text is safe.