Skip to content
donutchat.com

Incoming webhooks API

Post a plain-text message into one chat with a single HTTPS request, without a bot or an Authorization header. To create a webhook and copy its URL, see Incoming webhooks.

POST https://donutchat.com/webhooks/v1/{webhook_id}/{token}

Send requests to the URL exactly as you copied it from the app. The same path also works on https://api.donutchat.com. The token at the end of the URL is the credential, so keep the whole URL secret. See Authentication.

Send a JSON body with Content-Type: application/json.

FieldTypeRequiredDescription
contentstringYesThe message text, up to 80,000 UTF-8 bytes. Can’t be empty.
usernamestringNoSender name for this message, up to 32 bytes. Defaults to the webhook’s Display Name, or Webhook if it has none.
avatar_urlstringNoSender picture for this message. Use a public https image URL. Defaults to the webhook’s avatar.

Other fields are ignored. Webhook messages are always plain text; there’s no field for Markdown.

These examples read the URL from the DONUT_WEBHOOK_URL environment variable:

Terminal window
curl -X POST "$DONUT_WEBHOOK_URL" \
-H "Content-Type: application/json" \
-d '{"content": "Build 482 passed on main.", "username": "CI"}'

A successful request returns HTTP 200:

{
"ok": true,
"message_id": 5678,
"chat_id": 1234
}

In JavaScript, read these IDs with a parser that keeps 64-bit integers exact. See IDs are 64-bit integers.

Most errors return a JSON body:

{
"ok": false,
"error": "rate_limit_exceeded",
"message": "Too many requests. Please try again later."
}
HTTPerrorCauseWhat to do
400invalid_jsonThe body isn’t valid JSON, or a field isn’t a string.Send a JSON object with string fields.
400missing_contentcontent is missing or empty.Include the message text.
400content_too_longcontent is over 80,000 UTF-8 bytes.Shorten or split the message.
401unauthorizedThe token is wrong, the URL was rotated, or the webhook was deleted.Copy the current URL from the app.
403webhook_disabledThe webhook is switched off.Switch it back on in the app.
404not_foundThe webhook ID in the URL isn’t a number.Use the URL exactly as copied.
404None (plain text 404 page not found)The URL has the wrong shape, such as a missing token, an extra path segment or a trailing slash.Use the URL exactly as copied.
405None (empty body)The method isn’t POST.Send a POST request.
429rate_limit_exceededThe webhook reached a rate limit.Wait, then retry with increasing delays.
500send_failedusername is longer than 32 bytes, or something went wrong on the server.Shorten username. Otherwise, retry with increasing delays.
503None (plain text server is not ready)DonutChat is briefly unavailable, for example during maintenance.Retry with increasing delays.

Each webhook accepts up to 60 requests per minute and 1,000 requests per hour.

  • Both limits are rolling windows: they count the requests in the last 60 seconds and the last 60 minutes. There’s no fixed reset time.
  • Requests that are rejected for invalid JSON or content still count.
  • A 429 response has no Retry-After header.
  • You can’t change the limits. The webhook’s screen in the app shows them under Rate Limit.

Webhooks accept requests from any IP address.

  • The message shows the webhook’s display name and avatar, or the username and avatar_url from the request. The default name is “Webhook”.
  • Markdown shows as typed unless a reader in the iPhone, Android or desktop app chooses Formatted under Message display or selects View formatted on the message. The web app always shows it as typed.
  • Members get the message like any other. Members who don’t have the app open get a push notification with the message text, unless they muted the chat. The person who created the webhook doesn’t get push notifications for its messages.
  • Bots never receive webhook messages, so a webhook can’t trigger a bot.

Webhooks only post new plain-text messages. They can’t attach files, reply in threads, send Markdown or cards, react, or edit or delete their messages. To reply in threads or send Markdown and cards, use a bot: see Send messages and Thread replies and streaming. Bots can’t attach files, react, or edit or delete posted messages either; a bot can only update its own thread replies.