Skip to main content
Every event we send includes a response_url. POST Block Kit to it, and the message lands in that conversation. The key is already inside the URL, so there is nothing to set up. That is why this is the main path for n8n, Make, and Zapier.

The pattern

1

Confirm the webhook

Return an empty body with 2xx. The typing dots stay on, because we know a reply is coming.
2

Do the slow work

Call your LLM, query your database, build the PDF. Take up to 45 minutes.
3

POST the result

Send Block Kit to the response_url. It shows up in the chat and turns off the typing dots.
The typing dots give up after about 3 minutes, but the token keeps working. A reply at minute 10 still lands — it just shows up without the dots first.

Send a reply

No Authorization header. Having the URL is your permission.
A success returns a handle for every message you created:
updated tells you if the call created a new message or replaced one — see Updating messages.

Token rules

Lifetime
45 minutes
Counted from when the event was created, not from your first use.
Reuse
multi-use
Post several messages, or update one many times, until it expires.
Rate limit
30 / minute
Per token.
Retries
same token
Every retry of one event carries the exact same response_url.

Errors

An empty body is fine as a webhook reply (it means “got it”). Here it is an error (422 EMPTY_BODY). This endpoint only exists to create messages.
A 422 is also written to your delivery log. So even if your scenario ignores HTTP responses, you can still see why nothing showed up.

Attaching files

Upload through the token — no API key needed mid-flow:
See Sending files.

Next

Progress updates

Turn one bubble from “queued” into “done”.

Past 45 minutes?

Switch to a key. It never expires.