Skip to main content
Zapier works differently from n8n and Make. It is worth knowing why before you build.
Zapier cannot reply in the same request. A Catch Hook always returns Zapier’s own fixed response — you cannot change the body. Every Zapier bot must answer through the response_url.
That one rule shapes the whole setup: confirm automatically, then POST the answer.

Set up the trigger

1

Add a Catch Hook

Create a Zap with Webhooks by ZapierCatch Hook. Copy the custom webhook URL.
2

Paste it into your bot

Add it as your bot’s webhook URL.
3

Verify with the code

Press Verify. Zapier cannot echo the challenge, so we skip that check for zapier.com addresses — any 2xx counts as reachable.Instead, the event carries a human-readable verification_code like XXXX-XXXX. Open the Zap’s trigger data, find verification_code, and paste it into the wizard.
The code lasts 30 minutes. Dashes and capital letters do not matter. If it runs out, press Verify again for a new one.
We match the real hostname: hooks.zapier.com counts; look-alikes such as zapier.com.example.org or notzapier.com do not.

Reply to a message

1

Filter to real messages

Add a Filter so the Zap only continues when event exactly matches message.created. Without it, verify and test events run your whole Zap.
2

Do the work

ChatGPT, a lookup, a spreadsheet row — whatever your bot does.
3

POST the reply

Add Webhooks by ZapierPOST:
  • URL: map response_url from the trigger
  • Payload Type: JSON
  • Data:
  • Unflatten: no
  • Headers: none — the key is in the URL
Set Unflatten to no. If it stays on yes, Zapier turns a key like message.text into a nested object, and your payload stops being valid Block Kit.

Sending blocks from Zapier

Zapier’s Data fields are flat key-value pairs. They cannot build a nested blocks array. You have two options.

Use the shortcut

Most replies do not need nesting. This is a complete, valid body: We turn it into a proper text block on our side.

Use Code by Zapier

For buttons, forms, or files, add a Code by Zapier step and build the JSON yourself:
Map event_id, reply, order_id, and response_url into the step’s Input Data.
Code by Zapier is also the only real way to upload a file from a Zap, because the upload needs multipart/form-data.

Handle button clicks

Clicks arrive at the same Catch Hook with event set to interaction.button_clicked. Use a Filter or Paths to branch on it, then read action_id, value, and message_metadata. Reply the same way as above — POST to that event’s own response_url.

Always set a mid

Zapier replays and retries more than most tools. A mid turns a repeat POST into an update instead of a second message: event_id stays the same across retries of one event, so this makes your Zap safe to retry — for free.

Fixing problems

Reaching your hook and the code are two separate checks. A 2xx only proves we found it. You must also paste the verification_code from the trigger data into the wizard, within 30 minutes.
Pull a fresh sample: press Verify, then Test trigger in the Zap. The event has event set to webhook.verify and carries the code.
Add a Filter on event exactly matching message.created. Verify and test events both set test to true.
Zapier cannot reply in the same request — returning from the trigger does nothing. You need a Webhooks by Zapier → POST action aimed at response_url.
The Zap took more than 45 minutes, likely queued on a busy plan. For work that slow, switch to an API key, which never expires.
Usually Unflatten is on, so blocks arrived broken. Set it to no, or build the JSON in a Code step.