> ## Documentation Index
> Fetch the complete documentation index at: https://supahooks.ar27111994.dev/llms.txt
> Use this file to discover all available pages before exploring further.

# Inspect Slack event API callbacks and signatures

> Capture Slack Events API callbacks and slash commands, verify X-Slack-Signature v0= signatures with timestamp validation, and prototype response bodies.

Slack signs every Events API request with an HMAC-SHA256 value in the `X-Slack-Signature` header using a `v0=<hex>` format, alongside a timestamp in `X-Slack-Request-Timestamp`. Use the Webhook Debugger to confirm your signing secret is correct, capture both JSON event callbacks and form-encoded interactivity payloads, and prototype immediate response bodies without deploying your real Slack backend.

## Configure the actor for Slack

Start the actor with the following input. Replace `slack_signing_secret` with the signing secret from your Slack app's **Basic Information** page.

```json theme={null}
{
  "urlCount": 1,
  "retentionHours": 24,
  "authKey": "slack-debug-key",
  "enableJSONParsing": true,
  "maskSensitiveData": true,
  "signatureVerificationSecret": "slack_signing_secret",
  "signatureVerification": {
    "provider": "slack",
    "tolerance": 300
  },
  "defaultResponseCode": 200,
  "defaultResponseBody": "{\"ok\":true}",
  "defaultResponseHeaders": {
    "Content-Type": "application/json"
  },
  "forwardUrl": "https://staging.example.com/slack/events",
  "forwardHeaders": true
}
```

Slack request verification uses the signed raw body and the `X-Slack-Request-Timestamp` header. The `tolerance` value (in seconds) controls how far apart the request timestamp and server clock can be before verification fails. The default of `300` seconds matches Slack's own tolerance window.

After the actor starts, call `/info` to retrieve the generated webhook URL.

## Set the request URL in your Slack app

<Steps>
  <Step title="Open your Slack app settings">
    Go to [api.slack.com/apps](https://api.slack.com/apps), select your app, and open **Event Subscriptions** or **Interactivity & Shortcuts** depending on what you want to test.
  </Step>

  <Step title="Paste the endpoint URL">
    Copy the `/webhook/:id` URL from `/info` and paste it into the **Request URL** field.
  </Step>

  <Step title="Handle the URL verification challenge">
    Slack immediately sends a `url_verification` challenge when you save the URL. The actor returns `{"ok":true}` by default, which does not satisfy Slack's challenge response requirement.

    Use a `customScript` to return the challenge value:

    ```javascript theme={null}
    const body = typeof event.body === 'string' ? JSON.parse(event.body) : event.body;
    if (body && body.type === 'url_verification') {
      event.responseBody = { challenge: body.challenge };
      event.responseHeaders = { 'Content-Type': 'application/json' };
    }
    ```

    Paste this script into the `customScript` field in the actor input before saving the Request URL in Slack.
  </Step>

  <Step title="Subscribe to events or enable interactivity">
    Once the URL is verified, subscribe to the event types your app handles (for example, `message.channels` or `app_mention`) or enable interactivity for slash commands and interactive components.
  </Step>
</Steps>

<Warning>
  Interactive payloads from slash commands and block actions are sent as `application/x-www-form-urlencoded`, not JSON. The actor captures them as raw text. Use the `customScript` or forward the payload to app code that already knows how to decode Slack interactivity data.
</Warning>

## Test event callbacks and slash commands

After Slack delivers a callback, query `/logs` to see what was captured.

Filter for Events API JSON callbacks:

```bash theme={null}
GET /logs?webhookId=wh_abc123&body.type=event_callback
```

Filter for signature failures:

```bash theme={null}
GET /logs?webhookId=wh_abc123&signatureValid=false
```

Filter for form-encoded interactivity payloads:

```bash theme={null}
GET /logs?webhookId=wh_abc123&body=payload%3D
```

A captured event callback looks like this:

```json theme={null}
{
  "id": "evt_8m2L5p9xR",
  "webhookId": "wh_abc123",
  "timestamp": "2026-01-30T12:00:00.000Z",
  "method": "POST",
  "statusCode": 200,
  "signatureValid": true,
  "signatureProvider": "slack",
  "body": {
    "type": "event_callback",
    "event": {
      "type": "app_mention",
      "text": "hello",
      "user": "U01234567"
    }
  }
}
```

## Prototype a custom immediate response

Use `customScript` to return a custom response body for interactivity requests without deploying your real Slack backend:

```javascript theme={null}
event.responseHeaders = { "Content-Type": "application/json" };
event.responseBody = { text: "Handled by the sandbox" };
```

Turn on forwarding after you confirm the payload shape you want your real app to consume.

## Common failure patterns

| Signal                                     | What it usually means                               | What to do                                                                                      |
| :----------------------------------------- | :-------------------------------------------------- | :---------------------------------------------------------------------------------------------- |
| `signatureValid=false`                     | Wrong signing secret or timestamp outside tolerance | Verify the Slack signing secret and check for server clock skew                                 |
| `dispatch_failed` in Slack                 | Slack did not receive a fast enough 2xx             | Keep the immediate actor response lightweight and move heavy work behind forwarding or replay   |
| Raw `payload=` body instead of nested JSON | Slack interactivity was sent as form-encoded data   | Inspect the raw body string or forward it to app code that decodes Slack interactivity payloads |
