Slack apps send several kinds of HTTP requests to your application: Events API callbacks, slash commands, shortcuts, Block Kit actions, and modal submissions. They share request signing and a strict acknowledgment deadline, but their payloads and replay risks differ.
This guide covers HTTP Request URLs. It does not cover Socket Mode, sending messages through Slack incoming-webhook URLs, or CatchHook's separate outgoing Slack App.
Choose HTTP Request URLs or Socket Mode
Use an HTTP Request URL when you want Slack to call a stable public HTTPS endpoint. Use Socket Mode when your app deliberately maintains a WebSocket connection to Slack and does not expose an HTTP callback.
CatchHook receives HTTP callbacks. It does not proxy Socket Mode or host your bot process.
Open Slack Events API and Interactivity Webhook Testing to create a temporary demonstration endpoint. Save it before registering it with a Slack app because Slack needs a stable Request URL.
Find and configure the signing secret
Open your app at Slack API Apps, then find App Credentials on the Basic Information page. Copy the Signing Secret.
Do not substitute any of these:
- bot or user OAuth access token
- client secret
- deprecated verification token
- slash-command
response_url - Slack incoming-webhook URL
On the saved CatchHook endpoint, add a Slack signature configuration and paste the Signing Secret. CatchHook stores it with the existing encrypted secret and rotation contract. The endpoint does not require CatchHook's outgoing Slack App to be installed.
Register an Events API Request URL
In Event Subscriptions, enable events and paste the permanent CatchHook endpoint URL into Request URL.
Slack sends JSON shaped like:
{
"token": "deprecated-verification-token",
"challenge": "synthetic-challenge",
"type": "url_verification"
}
CatchHook automatically returns the challenge only when:
- the body is valid bounded JSON,
- the type is exactly
url_verification, - the challenge is a bounded string,
- the endpoint has Slack signature verification enabled, and
- the request's Slack signature verifies.
The response is 200 text/plain. It takes precedence over a static endpoint response and is recorded with response source provider_handshake. An unsigned or invalid challenge follows the endpoint's ordinary custom or default response and is never echoed.
Understand Slack request signing
Slack sends X-Slack-Request-Timestamp and X-Slack-Signature. The signature covers the exact raw request body:
v0:{timestamp}:{raw_body}
Compute HMAC SHA-256 with the app signing secret and prefix the hexadecimal digest with v0=. Reject requests whose timestamp differs from current time by more than five minutes.
For slash commands and interactivity, verify the original form-encoded bytes before decoding parameters. Rebuilding a form body or re-serializing JSON changes the signed bytes.
Read Webhook Signature Verification for the common middleware and encoding failure modes.
Trigger and inspect an Events API callback
Subscribe to a safe event such as app_home_opened, install the development app into a non-sensitive workspace, and trigger the event.
An Events API callback contains a top-level delivery envelope and an inner event:
{
"type": "event_callback",
"team_id": "T_TEST_WORKSPACE",
"api_app_id": "A_TEST_APP",
"event_id": "Ev_TEST_EVENT",
"event_time": 1785348000,
"event": {
"type": "app_home_opened",
"user": "U_TEST_USER",
"event_ts": "1785348000.000100"
}
}
CatchHook promotes only bounded request family, event type, workspace/app/event/user/channel IDs, timestamps, and retry context. Message text, names, state values, private metadata, tokens, trigger_id, and response_url stay only in the access-controlled raw capture.
Acknowledge within three seconds
Slack expects a successful acknowledgment within three seconds for Events API callbacks and interactive requests. CatchHook verifies the request, stores response evidence with the initial capture, enqueues provider enrichment, and returns the response without calling Slack APIs or running Endpoint Actions synchronously.
Ordinary requests use the endpoint's custom response when configured, otherwise an empty 200. The verified URL challenge is the only Slack-specific synchronous response in this release.
Diagnose retries and duplicate event IDs
Slack may retry Events API deliveries when an acknowledgment times out or fails. Retry attempts include:
X-Slack-Retry-Num: 1
X-Slack-Retry-Reason: http_timeout
The retry normally retains the same event_id. Store that stable event ID before performing side effects so a repeated delivery does not repeat billing, notifications, or writes.
CatchHook captures every attempt rather than discarding duplicates. It shows the retry number and reason alongside the event ID so you can diagnose delivery behavior. See Webhook Retries and Idempotency.
Test slash commands and interactivity
Slash commands arrive as application/x-www-form-urlencoded fields including command, workspace/user/channel IDs, a trigger_id, and usually a response_url.
Shortcuts, Block Kit actions, and modal events use a form field named payload whose value is JSON. Useful interaction families include:
block_actionsshortcutandmessage_actionview_submissionview_closed
CatchHook parses the bounded nested payload only after capturing and verifying the original form bytes. It promotes stable action, callback, and view IDs but not action values, view state, private metadata, trigger IDs, or response URLs.
Slack trigger IDs expire after three seconds and can be used only once. Treat a captured trigger ID as historical evidence, not reusable replay state.
Deliver requests to localhost
Register the hosted CatchHook endpoint with Slack, then stream captured requests to your local application:
npx @catchhook/tunnel start --endpoint ep_xxx --port 3000
Slack still receives CatchHook's fast acknowledgment while your local handler can restart, raise an exception, or return diagnostic responses. The hosted capture remains available for inspection. See Test Webhooks Locally.
Replay with explicit signature behavior
A captured Slack signature normally becomes stale after five minutes.
- Preserve keeps the historical timestamp and signature and warns that verification will usually fail.
- Strip removes both Slack signature headers.
- Re-sign creates a fresh timestamp and v0 signature over the exact replay body using the endpoint's current Slack signing secret.
For Events API JSON, New identity changes only the top-level event_id. It does not invent new workspace, app, user, channel, trigger, view, or response URL values. Form-encoded commands and interactions do not support identity regeneration.
Always replay into a controlled handler. CatchHook never follows a captured response_url.
Turn a working request into a Replay Case
Save a representative Events API callback or interaction as a Replay Case when you want a durable, versioned scenario with explicit target, signature mode, and assertions.
Replay Case runs snapshot the privacy-safe provider advice and the chosen signature behavior. Use them to test status codes, response headers, and bounded response bodies after handler changes.
Use Slack fields in Actions and MCP
Endpoint Actions can filter on allowlisted Slack fields such as request family, event type, retry reason, workspace/app/event IDs, and action or view ID. Arbitrary payload traversal and blocked fields are not exposed as provider fields.
CatchHook's REST API and MCP server expose the same bounded provider metadata, signature status, and response evidence. Full-request tools can still return the access-controlled raw capture when explicitly requested.
Production validation checklist
- Use a dedicated development app and non-sensitive workspace.
- Configure the app signing secret on a permanent CatchHook endpoint.
- Complete Events API URL verification.
- Capture a signed event callback.
- Capture a slash command or interactive payload.
- Observe or safely simulate a retry.
- Confirm the acknowledgment stays comfortably inside three seconds.
- Replay once with the stale signature and once with a fresh CatchHook signature.
- Review HTML, REST, MCP, Actions, and notifications for privacy-safe metadata.
Start with the Slack Request URL testing endpoint, then validate every assumption against requests from your own development app.