Input

469 chars

Output

0 chars

Slack Has Three Different "Webhook" Formats

The word "Slack webhook" is overloaded. There are three distinct payload types, and they don't share a schema:

  • Incoming Webhooks — You POST JSON to a Slack URL to send a message. Schema: text, blocks[], attachments[].
  • Events API — Slack POSTs JSON to your URL when something happens in a workspace. Schema: event_callback wrapper with the actual event nested in event.
  • Slash commands & Interactive components — Slack POSTs application/x-www-form-urlencoded with a JSON-encoded payload field. Different schema again.

This page is pre-loaded with an Events API payload (an app_mention event) — the most common one developers debug. Replace it with your own captured payload to validate the structure.

The Events API Envelope

Every Events API payload has the same outer envelope:

  • type — Always event_callback for actual events. url_verification appears once during initial endpoint setup; respond by echoing back the challenge field.
  • token — Verification token. Deprecated for new apps; modern apps verify the X-Slack-Signature header instead.
  • team_id — The workspace where the event happened.
  • api_app_id — Your Slack app's ID. Useful when one server handles webhooks for multiple apps.
  • event — The actual event object. Its schema depends on event.type (message, app_mention, reaction_added, etc.).
  • event_id — Unique ID for idempotency. Slack retries failed deliveries up to 3 times — store and check this ID.
  • event_time — Unix timestamp of the event. Distinct from event.ts, which is the message timestamp.

Block Kit: Slack's Rich Message Format

Modern Slack messages use Block Kit — an array of blocks, each with a type (section, divider, actions, image, context, etc.). Block Kit replaced the older attachments field, which still works but is deprecated for new development. When debugging an "interactive button doesn't fire", confirm the block has an action_id and your endpoint handles the block_actions interactive payload type.

Common Slack Webhook Bugs

"My event endpoint URL won't verify." Slack sends a url_verification challenge first. Your endpoint must respond within 3 seconds with { "challenge": "..." } echoed back. A 200 with the wrong body fails verification.

"I'm getting duplicate events." Slack retries failed deliveries (anything other than 2xx) up to 3 times within an hour. Use event_id for idempotency.

"My bot can't see messages it should see." The bot's OAuth scopes determine what events it receives. message.channels only fires for public channels the bot is in; message.groups for private channels; message.im for DMs. Each is a separate scope.

Related Tools

Common Use Cases

Related Articles