Skip to main content
Every message your bot sends is Block Kit JSON. There are three ways to send it, and they all accept the same body. You can switch between them without changing your JSON.

Pick a path

Webhook response

Reply in the same request. No setup, but a hard 10-second limit.

Response URL

POST back within 45 minutes. No keys to manage.

API key

Send any time. No time limit, and no event needed first.

Side by side

How to choose

1

Can you answer in under 10 seconds?

Return the JSON from your webhook. Done — nothing else to set up.
2

Will it take longer, but under 45 minutes?

Return an empty body first. Then POST your reply to the response_url when the work is done.
3

Longer than that, or no event to reply to?

Use an API key. This is the path for cron jobs, batch results, and messages you start yourself.
You can mix these. A common pattern: return a status block right away from the webhook, then update it through the response_url as the job runs. See Updating messages.

The body is always the same

This works on all three:
And so does this, because we accept shortcuts:
See the Block Kit overview for every shortcut we accept.

Rules that apply to all three

  • 256 KB body limit, and at most 10 messages per call. Bigger bodies return 413 PAYLOAD_TOO_LARGE.
  • A human always wins. Once a person takes over a conversation, all three paths return 409 conversation_taken_over. The bot cannot talk over a person. That is on purpose.
  • mid makes retries safe. Send the same mid again and we update the message instead of posting a copy. See Updating messages.
  • All errors look the same. Every failure returns { "ok": false, "error": { "code", "message" } }. See Limits and errors.