# Multi-Event Hooks

## Overview

Stream now supports configuring multiple webhook endpoints for different event types, giving you more flexibility in handling various events. This feature allows you to route different types of events to different endpoints, making your webhook architecture more organized and efficient.

## Configuration

You can configure multi-event hooks through the Stream Dashboard or using the server-side SDKs.

### Using the Dashboard

1. Go to the [Stream Dashboard](https://getstream.io/dashboard/)
2. Select your app
3. Navigate to your app's settings until "Webhook & Event Configuration" section
4. Add and configure webhook, SQS, SNS, and pending message

### Using Server-Side SDKs

Here's how to configure event hooks using our server SDKs:

<codetabs>

<codetabs-item value="javascript" label="JavaScript">

```js
// Get app settings
await client.getAppSettings();

// Response
{
  // ... all existing app settings
  "event_hooks": [
    {
      "id": "d2ce8c4f-bf5f-40b7-aeda-d2aef381fb54",
      "enabled": true,
      "hook_type": "webhook",
      "webhook_url": "http://url1-webhook.com",
      "event_types": ["channel.created"]
    },
    {
      "id": "e9b2c15b-53bd-4998-9791-491bb6742e23",
      "enabled": true,
      "hook_type": "sqs",
      "sqs_queue_url": "http://url1-sqs.com",
      "sqs_auth_type": "keys",
      "sqs_key": "sqs-key",
      "sqs_secret": "sqs-secret",
      "event_types": ["channel.created"]
    },
    {
      "id": "e9b2c15b-53bd-4998-9791-adiqeq13mqw",
      "enabled": true,
      "hook_type": "sns",
      "sns_arn_topic": "arn:aws:sns:us-east-1:123456789012:MyTopic2",
      "sns_auth_type": "role",
      "sns_role_arn": "arn:aws:iam::123456789012:role/SNSPublishRole",
      "event_types": ["channel.created", "channel.updated"]
    },
    {
      "enabled": true,
      "hook_type": "pending_message",
      "webhook_url": "http://test-url.com",
      "timeout_ms": 500,
      "callback": {
        "mode": "CALLBACK_MODE_REST"
      }
    }
  ]
}

// Update app settings
await client.updateAppSettings({
  event_hooks: [
    {
      "id": "d2ce8c4f-bf5f-40b7-aeda-d2aef381fb54",
      "enabled": true,
      "hook_type": "webhook",
      "webhook_url": "http://url1-new-webhook.com", // change the URL
      "event_types": ["channel.created", "message.new"] // add a new event type
    },
    {
      "id": "e9b2c15b-53bd-4998-9791-491bb6742e23",
      "enabled": false, // disable a hook
      "hook_type": "sqs",
      "sqs_queue_url": "http://url1-sqs.com",
      "sqs_auth_type": "keys",
      "sqs_key": "sqs-key",
      "sqs_secret": "sqs-secret",
      "event_types": ["channel.created"]
    }
    // remove e9b2c15b-53bd-4998-9791-adiqeq13mqw from the update app settings request will delete it from DB
  ]
});
```

</codetabs-item>

<codetabs-item value="python" label="Python">

```python
# Get app settings
client.get_app_settings()

# Response
{
    # ... all existing app settings
    "event_hooks": [
        {
            "id": "d2ce8c4f-bf5f-40b7-aeda-d2aef381fb54",
            "enabled": True,
            "hook_type": "webhook",
            "webhook_url": "http://url1-webhook.com",
            "event_types": ["channel.created"]
        },
        {
            "id": "e9b2c15b-53bd-4998-9791-491bb6742e23",
            "enabled": True,
            "hook_type": "sqs",
            "sqs_queue_url": "http://url1-sqs.com",
            "sqs_auth_type": "keys",
            "sqs_key": "sqs-key",
            "sqs_secret": "sqs-secret",
            "event_types": ["channel.created"]
        },
        {
            "id": "e9b2c15b-53bd-4998-9791-adiqeq13mqw",
            "enabled": True,
            "hook_type": "sns",
            "sns_arn_topic": "arn:aws:sns:us-east-1:123456789012:MyTopic2",
            "sns_auth_type": "role",
            "sns_role_arn": "arn:aws:iam::123456789012:role/SNSPublishRole",
            "event_types": ["channel.created", "channel.updated"]
        },
        {
            "enabled": True,
            "hook_type": "pending_message",
            "webhook_url": "http://test-url.com",
            "timeout_ms": 500,
            "callback": {
                "mode": "CALLBACK_MODE_REST"
            }
        }
    ]
}

# Update app settings
client.update_app_settings(
    event_hooks=[
        {
            "id": "d2ce8c4f-bf5f-40b7-aeda-d2aef381fb54",
            "enabled": True,
            "hook_type": "webhook",
            "webhook_url": "http://url1-new-webhook.com",  # change the URL
            "event_types": ["channel.created", "message.new"]  # add a new event type
        },
        {
            "id": "e9b2c15b-53bd-4998-9791-491bb6742e23",
            "enabled": False,  # disable a hook
            "hook_type": "sqs",
            "sqs_queue_url": "http://url1-sqs.com",
            "sqs_auth_type": "keys",
            "sqs_key": "sqs-key",
            "sqs_secret": "sqs-secret",
            "event_types": ["channel.created"]
        }
        # remove e9b2c15b-53bd-4998-9791-adiqeq13mqw from the update app settings request will delete it from DB
    ]
)
```

</codetabs-item>

<codetabs-item value="ruby" label="Ruby">

```ruby
# Get app settings
client.get_app_settings

# Response
{
    # ... all existing app settings
    "event_hooks": [
        {
            "id": "d2ce8c4f-bf5f-40b7-aeda-d2aef381fb54",
            "enabled": true,
            "hook_type": "webhook",
            "webhook_url": "http://url1-webhook.com",
            "event_types": ["channel.created"]
        },
        {
            "id": "e9b2c15b-53bd-4998-9791-491bb6742e23",
            "enabled": true,
            "hook_type": "sqs",
            "sqs_queue_url": "http://url1-sqs.com",
            "sqs_auth_type": "keys",
            "sqs_key": "sqs-key",
            "sqs_secret": "sqs-secret",
            "event_types": ["channel.created"]
        },
        {
            "id": "e9b2c15b-53bd-4998-9791-adiqeq13mqw",
            "enabled": true,
            "hook_type": "sns",
            "sns_arn_topic": "arn:aws:sns:us-east-1:123456789012:MyTopic2",
            "sns_auth_type": "role",
            "sns_role_arn": "arn:aws:iam::123456789012:role/SNSPublishRole",
            "event_types": ["channel.created", "channel.updated"]
        },
        {
            "enabled": true,
            "hook_type": "pending_message",
            "webhook_url": "http://test-url.com",
            "timeout_ms": 500,
            "callback": {
                "mode": "CALLBACK_MODE_REST"
            }
        }
    ]
}

# Update app settings
client.update_app_settings(
    event_hooks: [
        {
            "id": "d2ce8c4f-bf5f-40b7-aeda-d2aef381fb54",
            "enabled": true,
            "hook_type": "webhook",
            "webhook_url": "http://url1-new-webhook.com", # change the URL
            "event_types": ["channel.created", "message.new"] # add a new event type
        },
        {
            "id": "e9b2c15b-53bd-4998-9791-491bb6742e23",
            "enabled": false, # disable a hook
            "hook_type": "sqs",
            "sqs_queue_url": "http://url1-sqs.com",
            "sqs_auth_type": "keys",
            "sqs_key": "sqs-key",
            "sqs_secret": "sqs-secret",
            "event_types": ["channel.created"]
        }
        # remove e9b2c15b-53bd-4998-9791-adiqeq13mqw from the update app settings request will delete it from DB
    ]
)
```

</codetabs-item>

<codetabs-item value="php" label="PHP">

```php
// Get app settings
$response = $client->getAppSettings();

// Response
[
    // ... all existing app settings
    'event_hooks' => [
        [
            'id' => 'd2ce8c4f-bf5f-40b7-aeda-d2aef381fb54',
            'enabled' => true,
            'hook_type' => 'webhook',
            'webhook_url' => 'http://url1-webhook.com',
            'event_types' => ['channel.created']
        ],
        [
            'id' => 'e9b2c15b-53bd-4998-9791-491bb6742e23',
            'enabled' => true,
            'hook_type' => 'sqs',
            'sqs_queue_url' => 'http://url1-sqs.com',
            'sqs_auth_type' => 'keys',
            'sqs_key' => 'sqs-key',
            'sqs_secret' => 'sqs-secret',
            'event_types' => ['channel.created']
        ],
        [
            'id' => 'e9b2c15b-53bd-4998-9791-adiqeq13mqw',
            'enabled' => true,
            'hook_type' => 'sns',
            'sns_arn_topic' => 'arn:aws:sns:us-east-1:123456789012:MyTopic2',
            'sns_auth_type' => 'role',
            'sns_role_arn' => 'arn:aws:iam::123456789012:role/SNSPublishRole',
            'event_types' => ['channel.created', 'channel.updated']
        ],
        [
            'enabled' => true,
            'hook_type' => 'pending_message',
            'webhook_url' => 'http://test-url.com',
            'timeout_ms' => 500,
            'callback' => [
                'mode' => 'CALLBACK_MODE_REST'
            ]
        ]
    ]
];

// Update app settings
$client->updateAppSettings([
    'event_hooks' => [
        [
            'id' => 'd2ce8c4f-bf5f-40b7-aeda-d2aef381fb54',
            'enabled' => true,
            'hook_type' => 'webhook',
            'webhook_url' => 'http://url1-new-webhook.com', // change the URL
            'event_types' => ['channel.created', 'message.new'] // add a new event type
        ],
        [
            'id' => 'e9b2c15b-53bd-4998-9791-491bb6742e23',
            'enabled' => false, // disable a hook
            'hook_type' => 'sqs',
            'sqs_queue_url' => 'http://url1-sqs.com',
            'sqs_auth_type' => 'keys',
            'sqs_key' => 'sqs-key',
            'sqs_secret' => 'sqs-secret',
            'event_types' => ['channel.created']
        }
        // remove e9b2c15b-53bd-4998-9791-adiqeq13mqw from the update app settings request will delete it from DB
    ]
]);
```

</codetabs-item>

<codetabs-item value="go" label="Go">

```go
// Get app settings
settings, err := client.GetAppSettings(ctx)

// Response
// settings contains:
/*
{
    // ... all existing app settings
    "event_hooks": [
        {
            "id": "d2ce8c4f-bf5f-40b7-aeda-d2aef381fb54",
            "enabled": true,
            "hook_type": "webhook",
            "webhook_url": "http://url1-webhook.com",
            "event_types": ["channel.created"]
        },
        {
            "id": "e9b2c15b-53bd-4998-9791-491bb6742e23",
            "enabled": true,
            "hook_type": "sqs",
            "sqs_queue_url": "http://url1-sqs.com",
            "sqs_auth_type": "keys",
            "sqs_key": "sqs-key",
            "sqs_secret": "sqs-secret",
            "event_types": ["channel.created"]
        },
        {
            "id": "e9b2c15b-53bd-4998-9791-adiqeq13mqw",
            "enabled": true,
            "hook_type": "sns",
            "sns_arn_topic": "arn:aws:sns:us-east-1:123456789012:MyTopic2",
            "sns_auth_type": "role",
            "sns_role_arn": "arn:aws:iam::123456789012:role/SNSPublishRole",
            "event_types": ["channel.created", "channel.updated"]
        },
        {
            "enabled": true,
            "hook_type": "pending_message",
            "webhook_url": "http://test-url.com",
            "timeout_ms": 500,
            "callback": {
                "mode": "CALLBACK_MODE_REST"
            }
        }
    ]
}
*/

// Update app settings
eventHooks := []stream.EventHook{
    {
        ID:         "d2ce8c4f-bf5f-40b7-aeda-d2aef381fb54",
        Enabled:    true,
        HookType:   "webhook",
        WebhookURL: "http://url1-new-webhook.com", // change the URL
        EventTypes: []string{"channel.created", "message.new"},  // add a new event type
    },
    {
        ID:          "e9b2c15b-53bd-4998-9791-491bb6742e23",
        Enabled:     false, // disable a hook
        HookType:    "sqs",
        SQSQueueURL: "http://url1-sqs.com",
        SQSAuthType: "keys",
        SQSKey:      "sqs-key",
        SQSSecret:   "sqs-secret",
        EventTypes:  []string{"channel.created"},
    },
    // remove e9b2c15b-53bd-4998-9791-adiqeq13mqw from the update app settings request will delete it from DB
}

_, err = client.UpdateAppSettings(ctx, &stream.AppSettings{
    EventHooks: eventHooks,
})
```

</codetabs-item>

<codetabs-item value="csharp" label="C#">

```csharp
// Get app settings
var settings = await client.GetAppSettingsAsync();

// Response contains:
/*
{
    // ... all existing app settings
    "event_hooks": [
        {
            "id": "d2ce8c4f-bf5f-40b7-aeda-d2aef381fb54",
            "enabled": true,
            "hook_type": "webhook",
            "webhook_url": "http://url1-webhook.com",
            "event_types": ["channel.created"]
        },
        {
            "id": "e9b2c15b-53bd-4998-9791-491bb6742e23",
            "enabled": true,
            "hook_type": "sqs",
            "sqs_queue_url": "http://url1-sqs.com",
            "sqs_auth_type": "keys",
            "sqs_key": "sqs-key",
            "sqs_secret": "sqs-secret",
            "event_types": ["channel.created"]
        },
        {
            "id": "e9b2c15b-53bd-4998-9791-adiqeq13mqw",
            "enabled": true,
            "hook_type": "sns",
            "sns_arn_topic": "arn:aws:sns:us-east-1:123456789012:MyTopic2",
            "sns_auth_type": "role",
            "sns_role_arn": "arn:aws:iam::123456789012:role/SNSPublishRole",
            "event_types": ["channel.created", "channel.updated"]
        },
        {
            "enabled": true,
            "hook_type": "pending_message",
            "webhook_url": "http://test-url.com",
            "timeout_ms": 500,
            "callback": {
                "mode": "CALLBACK_MODE_REST"
            }
        }
    ]
}
*/

// Update app settings
await client.UpdateAppSettingsAsync(new AppSettingsRequest
{
    EventHooks = new List<EventHook>
    {
        new EventHook
        {
            Id = "d2ce8c4f-bf5f-40b7-aeda-d2aef381fb54",
            Enabled = true,
            HookType = "webhook",
            WebhookUrl = "http://url1-new-webhook.com", // change the URL
            EventTypes = new List<string> { "channel.created", "message.new" } // add a new event type
        },
        new EventHook
        {
            Id = "e9b2c15b-53bd-4998-9791-491bb6742e23",
            Enabled = false, // disable a hook
            HookType = "sqs",
            SqsQueueUrl = "http://url1-sqs.com",
            SqsAuthType = "keys",
            SqsKey = "sqs-key",
            SqsSecret = "sqs-secret",
            EventTypes = new List<string> { "channel.created" }
        }
        // remove e9b2c15b-53bd-4998-9791-adiqeq13mqw from the update app settings request will delete it from DB
    }
});
```

</codetabs-item>

<codetabs-item value="java" label="Java">

```java
// Get app settings
AppSettings settings = client.getAppSettings();

// Response contains:
/*
{
    // ... all existing app settings
    "event_hooks": [
        {
            "id": "d2ce8c4f-bf5f-40b7-aeda-d2aef381fb54",
            "enabled": true,
            "hook_type": "webhook",
            "webhook_url": "http://url1-webhook.com",
            "event_types": ["channel.created"]
        },
        {
            "id": "e9b2c15b-53bd-4998-9791-491bb6742e23",
            "enabled": true,
            "hook_type": "sqs",
            "sqs_queue_url": "http://url1-sqs.com",
            "sqs_auth_type": "keys",
            "sqs_key": "sqs-key",
            "sqs_secret": "sqs-secret",
            "event_types": ["channel.created"]
        },
        {
            "id": "e9b2c15b-53bd-4998-9791-adiqeq13mqw",
            "enabled": true,
            "hook_type": "sns",
            "sns_arn_topic": "arn:aws:sns:us-east-1:123456789012:MyTopic2",
            "sns_auth_type": "role",
            "sns_role_arn": "arn:aws:iam::123456789012:role/SNSPublishRole",
            "event_types": ["channel.created", "channel.updated"]
        },
        {
            "enabled": true,
            "hook_type": "pending_message",
            "webhook_url": "http://test-url.com",
            "timeout_ms": 500,
            "callback": {
                "mode": "CALLBACK_MODE_REST"
            }
        }
    ]
}
*/

// Update app settings
List<EventHook> eventHooks = Arrays.asList(
    EventHook.builder()
        .id("d2ce8c4f-bf5f-40b7-aeda-d2aef381fb54")
        .enabled(true)
        .hookType("webhook")
        .webhookUrl("http://url1-new-webhook.com") // change the URL
        .eventTypes(Arrays.asList("channel.created", "message.new")) // add a new event type
        .build(),
    EventHook.builder()
        .id("e9b2c15b-53bd-4998-9791-491bb6742e23")
        .enabled(false) // disable a hook
        .hookType("sqs")
        .sqsQueueUrl("http://url1-sqs.com")
        .sqsAuthType("keys")
        .sqsKey("sqs-key")
        .sqsSecret("sqs-secret")
        .eventTypes(Collections.singletonList("channel.created"))
        .build()
    // remove e9b2c15b-53bd-4998-9791-adiqeq13mqw from the update app settings request will delete it from DB
);

client.updateAppSettings(AppSettings.builder().eventHooks(eventHooks).build());
```

</codetabs-item>

</codetabs>

## Configuration Options

Each event hook configuration supports different options based on its type:

### Common Options

| Option      | Type    | Description                                               | Required                                                                           |
| ----------- | ------- | --------------------------------------------------------- | ---------------------------------------------------------------------------------- |
| id          | string  | Unique identifier for the event hook                      | Yes for updating hooks. If empty, it will generate an ID.                          |
| enabled     | boolean | Boolean flag to enable/disable the hook                   | Yes                                                                                |
| hook_type   | string  | Type of hook ("webhook", "sqs", "sns", "pending_message") | Yes                                                                                |
| event_types | array   | Array of event types this hook should handle              | No. Not provided or empty array means subscribe to all existing and future events. |

### Webhook Options

| Option      | Type   | Description                                                                                                                                 | Required |
| ----------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| webhook_url | string | The URL where events will be sent. You can use URL templating to handle events. Example: `http://my.webhook.host/{{.AppID}}/{{.EventType}}` | Yes      |

For more information on configuring webhook server, please refer to the [Webhooks Overview](/chat/docs/<framework>/webhooks_overview/) documentation.

### SQS Options

| Option        | Type   | Description                                         | Required               |
| ------------- | ------ | --------------------------------------------------- | ---------------------- |
| sqs_queue_url | string | The AWS SQS queue URL                               | Yes                    |
| sqs_auth_type | string | Authentication type ("keys", "role", or "resource") | Yes                    |
| sqs_key       | string | AWS access key ID (if auth_type is "keys")          | Yes if using key auth  |
| sqs_secret    | string | AWS secret access key (if auth_type is "keys")      | Yes if using key auth  |
| sqs_role_arn  | string | AWS IAM role ARN (if auth_type is "role")           | Yes if using role auth |

For more information on configuring SQS server, please refer to the [SQS](/chat/docs/<framework>/sqs/) documentation.

### SNS Options

| Option        | Type   | Description                                         | Required               |
| ------------- | ------ | --------------------------------------------------- | ---------------------- |
| sns_topic_arn | string | The AWS SNS topic ARN                               | Yes                    |
| sns_auth_type | string | Authentication type ("keys", "role", or "resource") | Yes                    |
| sns_key       | string | AWS access key ID (if auth_type is "keys")          | Yes if using key auth  |
| sns_secret    | string | AWS secret access key (if auth_type is "keys")      | Yes if using key auth  |
| sns_role_arn  | string | AWS IAM role ARN (if auth_type is "role")           | Yes if using role auth |

For more information on configuring SNS server, please refer to the [SNS](/chat/docs/<framework>/sns/) documentation.

### Pending Message Options

| Option        | Type   | Description                                                                       | Required                             |
| ------------- | ------ | --------------------------------------------------------------------------------- | ------------------------------------ |
| webhook_url   | string | The URL where pending message events will be sent                                 | Yes, except for `CALLBACK_MODE_NONE` |
| timeout_ms    | number | Timeout in milliseconds                                                           | Yes                                  |
| callback.mode | string | Callback mode ("CALLBACK_MODE_NONE", "CALLBACK_MODE_REST", "CALLBACK_MODE_TWIRP") | Yes                                  |

For more information on configuring pending messages, please refer to the [Pending Messages](/chat/docs/<framework>/pending_messages/) documentation.

## Migration

If you only see a single webhook URL in your app settings, your application hasn't been migrated to the new multi-event hooks system yet. We are currently in the process of gradually rolling out this feature across all Stream applications. Once your app is migrated, you'll have access to the multi-event hooks configuration described in this section.

---

This page was last updated at 2025-08-15T14:14:54.799Z.

For the most recent version of this documentation, visit [https://getstream.io/chat/docs/node/multi_event_hooks/](https://getstream.io/chat/docs/node/multi_event_hooks/).