# Using an Amazon SNS notification channel

Source: https://developer.nylas.com/docs/v3/notifications/sns-channel/

You can set up an Amazon SNS notification channel to receive notifications about activity and changes on the provider. Your project can then consume the notifications from your SNS topic and respond to power your app's logic.

Nylas SNS notification channels send data to an SNS topic in your AWS account, which you can subscribe to for notifications. This is different from webhooks, which deliver notifications directly to an HTTPS endpoint.

You can use an SNS notification channel along with [webhooks](/docs/v3/notifications/) and [Pub/Sub channels](/docs/v3/notifications/pubsub-channel/), and you can use up to five separate SNS channels to separate your notifications.

## How SNS channels work

The Nylas SNS notification channel stores information that allows Nylas to connect to and send messages into an SNS topic in your AWS account. Nylas runs on Google Cloud Platform (GCP), and uses AWS STS `AssumeRoleWithWebIdentity` with a GCP-issued OIDC token to securely assume an IAM role in your AWS account. The assumed role is then used to publish notifications to your SNS topic. Each Nylas application can have up to five SNS channels. ([Contact Nylas Support](/docs/support/#contact-nylas-support) if your project requires more than five channels.)

You can use SNS as a complete replacement for webhook notifications, or alongside existing webhook and Pub/Sub architecture. For example, you might use an SNS channel for notification subscriptions that produce a high volume of messages, but use webhooks for lower volume notification subscriptions.

Each SNS channel subscribes to any number of notification triggers, so you can split your notifications across separate SNS topics. Nylas includes the `trigger_type` as an SNS [message attribute](https://docs.aws.amazon.com/sns/latest/dg/sns-message-attributes.html), which you can use for filtering and routing with SNS subscription filter policies.

> **Info:** 
> **Keep in mind**: It might take up to two minutes for you to receive SNS notifications for newly authenticated grants.

### Verification on creation

When you create an SNS notification channel, Nylas immediately publishes a `connector.verification` test event to your SNS topic. This verifies that the IAM role can be assumed and that Nylas has permission to publish to the topic.

If the verification fails (for example, because of an invalid role ARN, missing permissions, or an inaccessible topic), Nylas rejects the channel creation request with a descriptive error. This ensures that your SNS channel is functional from the moment it's created.

The verification notification arrives as a standard SNS `Notification` message:

```json

{
  "Type": "Notification",
  "MessageId": "<SNS_MESSAGE_ID>",
  "TopicArn": "arn:aws:sns:<REGION>:<ACCOUNT_ID>:<TOPIC_NAME>",
  "Message": "{\"data\":{\"message\":\"Nylas connectivity verification\"},\"id\":\"<VERIFICATION_ID>\",\"source\":\"/nylas/system\",\"specversion\":\"1.0\",\"time\":1774646707,\"type\":\"connector.verification\"}",
  "Timestamp": "2026-03-27T21:25:07.511Z",
  "SignatureVersion": "1",
  "Signature": "...",
  "SigningCertURL": "https://sns.<REGION>.amazonaws.com/SimpleNotificationService-<CERT_ID>.pem",
  "UnsubscribeURL": "https://sns.<REGION>.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:<REGION>:<ACCOUNT_ID>:<TOPIC_NAME>:<SUBSCRIPTION_ID>"
}


```

The `Message` field is a JSON-encoded string. When you parse it, you get the inner CloudEvents payload:

```json

{
  "data": {
    "message": "Nylas connectivity verification"
  },
  "id": "<VERIFICATION_ID>",
  "source": "/nylas/system",
  "specversion": "1.0",
  "time": 1774646707,
  "type": "connector.verification"
}


```

Verification notifications do not include `MessageAttributes`.

### Compressed SNS notifications

When you enable compressed delivery by setting `compressed_delivery` to `true` on an SNS channel, Nylas gzip-compresses the notification payload and then base64-encodes it before publishing to your SNS topic. The base64 encoding is required because SNS messages must be valid UTF-8 strings and cannot contain raw binary data.

> **Success:** 
> **Nylas recommends enabling compressed delivery for SNS channels** to reduce the chance of payload truncation. SNS has a 256 KB message size limit, and compressed delivery can significantly reduce payload sizes. Set `compressed_delivery` to `true` when you [create](#create-an-sns-notification-channel) or update your SNS channel.

Nylas adds a `content_encoding: gzip+base64` [message attribute](https://docs.aws.amazon.com/sns/latest/dg/sns-message-attributes.html) alongside the existing `trigger_type` attribute when delivering compressed notifications. To process compressed messages:

1. Check for the `content_encoding` attribute on the SNS message.
2. If it equals `gzip+base64`, **base64-decode** the message body to get the raw gzip bytes.
3. **Gzip-decompress** the decoded bytes to get the JSON CloudEvents payload.

Compressed delivery is useful in two situations:

- **Avoiding truncation**: Compression can reduce payloads that would otherwise exceed the 256 KB SNS limit, preventing data loss from truncation.
- **Avoiding firewall issues**: Some firewalls and WAFs inspect message bodies and block content that contains HTML tags. Email message notifications often include HTML content, which can trigger these rules. Compressed payloads are opaque base64 strings that pass through without being flagged.

To enable compressed delivery, set `compressed_delivery` to `true` when you [create](/docs/reference/api/amazon-sns-notifications/create-sns-channel/) or [update](/docs/reference/api/amazon-sns-notifications/put-sns-by-id/) an SNS channel.

> **Info:** 
> **Compression and truncation**: Nylas checks the original (uncompressed) payload size against the SNS truncation threshold _before_ compressing. If the original payload exceeds ~250 KB, Nylas strips the body content first and then compresses the truncated payload. Compression helps payloads that are large but below the truncation threshold stay well within SNS limits after compression.

### Truncated SNS notifications

Nylas sends SNS notifications as JSON payloads, up to a maximum payload size of 256 KB. If a notification exceeds 250 KB, Nylas truncates the payload and adds the `.truncated` suffix to the notification type (for example, `message.created.truncated` or `event.created.truncated`). For `message.*` notifications, Nylas blanks the `body` field. For `event.*` notifications, Nylas removes the `description` field.

> **Warn:** 
> **Unlike webhook truncation, SNS truncation applies to all trigger types**, not just `message.*` triggers. This means you may receive `event.created.truncated` and `event.updated.truncated` notifications from SNS channels that don't occur with webhooks. See the [notification schemas](/docs/v3/notifications/notification-schemas/#truncated-event-notifications-sns-only) for more details.

When you receive a truncated notification, re-query the Nylas APIs to get the full object data. For example, if you receive an `event.updated.truncated` notification, make a [Get Event request](/docs/reference/api/events/get-events-id/) that includes the specified event ID.

You don't need to subscribe to `*.truncated` triggers, but you _do_ need to make sure your project can handle these notification types.

## SNS message format

All Nylas notifications arrive as SNS messages with `"Type": "Notification"`. The `Message` field contains a JSON-encoded string with the CloudEvents payload, which is the same format used by [webhook notifications](/docs/v3/notifications/notification-schemas/).

### Webhook notification envelope

The following example shows a complete SNS notification for an `event.created` trigger:

```json

{
  "Type": "Notification",
  "MessageId": "<SNS_MESSAGE_ID>",
  "TopicArn": "arn:aws:sns:<REGION>:<ACCOUNT_ID>:<TOPIC_NAME>",
  "Message": "{\"specversion\":\"1.0\",\"type\":\"event.created\",\"source\":\"/microsoft/events/realtime\",\"id\":\"<NOTIFICATION_ID>\",\"time\":1774647196,\"webhook_delivery_attempt\":1,\"data\":{\"application_id\":\"<NYLAS_APPLICATION_ID>\",\"object\":{...}}}",
  "Timestamp": "2026-03-27T21:33:17.402Z",
  "SignatureVersion": "1",
  "Signature": "...",
  "SigningCertURL": "https://sns.<REGION>.amazonaws.com/SimpleNotificationService-<CERT_ID>.pem",
  "UnsubscribeURL": "https://sns.<REGION>.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:<REGION>:<ACCOUNT_ID>:<TOPIC_NAME>:<SUBSCRIPTION_ID>",
  "MessageAttributes": {
    "trigger_type": {
      "Type": "String",
      "Value": "event.created"
    }
  }
}


```

The `MessageAttributes` object includes `trigger_type`, which contains the notification type as a string. You can use this attribute to set up [SNS subscription filter policies](https://docs.aws.amazon.com/sns/latest/dg/sns-subscription-filter-policies.html) to route specific trigger types to different subscribers.

> **Info:** 
> **The `Message` field is a JSON-encoded string**, not a nested object. You need to parse it separately to access the CloudEvents payload fields (`type`, `source`, `data`, etc.). See the [notification schemas](/docs/v3/notifications/notification-schemas/) page for full inner payload schemas for each trigger type.

## Before you begin

Before you can start using SNS channels, you need the following prerequisites:

- A Nylas application.
- Your Nylas application's client ID and API key.
- An AWS account.
- The [AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) installed (optional, for CLI-based setup).

## Create the SNS topic

1. Log in to the [Amazon SNS console](https://console.aws.amazon.com/sns/v3/home).
2. From the **Topics** page, click **Create topic**.
3. Select **Standard** as the type.
4. Give your topic a name and click **Create topic**.

> **Warn:** 
> **FIFO topics are not supported**. Make sure you select "Standard" when creating your topic. Topics with a `.fifo` suffix are rejected.

Make note of the **Topic ARN** (format: `arn:aws:sns:<region>:<account-id>:<topic-name>`), because you'll use it in the next steps.

## Configure IAM for Nylas access

Nylas runs on Google Cloud Platform and authenticates to your AWS account using a Google-issued OIDC token. You need to create an IAM role that trusts Google's web identity federation.

1. **Create an IAM role** that Nylas can assume.

   Go to the [IAM Roles page](https://console.aws.amazon.com/iam/home#/roles) and click **Create role**.

   - **Trusted entity type**: Web identity
   - **Identity provider**: `accounts.google.com`

   For the permission policy, create a custom policy that grants `sns:Publish` on your topic:

   ```json
   {
     "Version": "2012-10-17",
     "Statement": [
       {
         "Effect": "Allow",
         "Action": "sns:Publish",
         "Resource": "arn:aws:sns:<REGION>:<ACCOUNT_ID>:<TOPIC_NAME>"
       }
     ]
   }
   ```

2. **Update the role's trust policy** to allow only Nylas service accounts.

   After creating the role, edit its trust policy to match the following. This restricts access to specific Nylas service accounts using `sub`, `aud`, and `oaud` claims from the Google OIDC token:

   ```json
   {
     "Version": "2012-10-17",
     "Statement": [
       {
         "Effect": "Allow",
         "Principal": {
           "Federated": "accounts.google.com"
         },
         "Action": "sts:AssumeRoleWithWebIdentity",
         "Condition": {
           "StringEquals": {
             "accounts.google.com:sub": [
               "100119423980618968561",
               "103168769681049948092",
               "110331549526886502703"
             ],
             "accounts.google.com:aud": [
               "100119423980618968561",
               "103168769681049948092",
               "110331549526886502703"
             ],
             "accounts.google.com:oaud": "nylas-datapublisher"
           }
         }
       }
     ]
   }
   ```

   Give the role a descriptive name (for example, `nylas-sns-publish-role`), and click **Create role**.

Make note of the **Role ARN** (format: `arn:aws:iam::<account-id>:role/<role-name>`), because you'll need it when creating the SNS channel.

## Create an SNS notification channel

Next, connect the SNS topic to your application. You can do this from the Nylas Dashboard by navigating to the **Notifications** page and clicking **Create SNS Channel**, or by making a [`POST /v3/channels/sns` request](/docs/reference/api/amazon-sns-notifications/create-sns-channel/).

This creates a notification channel and sets up the destination where Nylas sends notifications. This request is also where you select the notification triggers you want the SNS channel to subscribe to.

Both `topic` and `role_arn` are required. Nylas verifies your configuration by publishing a test event to the topic when the channel is created.

```bash

curl --request POST \
  --url 'https://api.us.nylas.com/v3/channels/sns' \
  --header 'Content-Type: application/json' \
  --header 'Accept: application/json' \
  --header 'Authorization: Bearer <NYLAS_API_KEY>' \
  --data-raw '{
    "description": "SNS Test",
    "trigger_types": ["message.send_success"],
    "topic": "arn:aws:sns:us-east-1:123456789012:my-topic",
    "role_arn": "arn:aws:iam::123456789012:role/nylas-sns-role",
    "notification_email_addresses": ["leyah@example.com"]
  }'

```

## Troubleshooting

If you receive an error when creating or using an SNS notification channel, check the following common issues.

### Role trust policy misconfigured

**Error**: SNS verification failed when creating the channel.

The IAM role's trust policy must allow `sts:AssumeRoleWithWebIdentity` from `accounts.google.com` with the correct Nylas service account conditions. Verify that:

- The role's `Principal.Federated` is set to `accounts.google.com`.
- The `accounts.google.com:sub` and `accounts.google.com:aud` conditions include all three Nylas service account IDs (`100119423980618968561`, `103168769681049948092`, `110331549526886502703`).
- The `accounts.google.com:oaud` condition is set to `nylas-datapublisher`.

### Topic not found

**Error**: SNS verification failed. The topic does not exist or is not accessible.

- Verify that the `topic` is correct and the topic exists in the specified region.
- Make sure the topic is a **Standard** topic, not a FIFO topic (`.fifo` suffix).
- Confirm the IAM role's permission policy grants `sns:Publish` on the exact topic ARN.

### KMS access denied

**Error**: SNS publish failed with a KMS access denied error.

If your SNS topic uses server-side encryption (SSE) with an AWS KMS key, the IAM role that Nylas assumes must also have permissions to use the KMS key. Add the following permissions to the role's policy:

```json
{
  "Effect": "Allow",
  "Action": [
    "kms:Decrypt",
    "kms:GenerateDataKey"
  ],
  "Resource": "arn:aws:kms:<REGION>:<ACCOUNT_ID>:key/<KMS_KEY_ID>"
}
```

### Invalid ARN format

**Error**: `invalid IAM role ARN format` or topic ARN validation error.

- The **topic ARN** must match the format `arn:aws:sns:<region>:<account-id>:<topic-name>`.
- The **role ARN** must match the format `arn:aws:iam::<account-id>:role/<role-name>`, where the account ID is exactly 12 digits.

## Related resources

- [Notification schemas](/docs/v3/notifications/notification-schemas/): Schema references for each type of notification that Nylas sends.
- [Using webhooks with Nylas](/docs/v3/notifications/): How to use webhook notifications as an alternative or alongside SNS.
- [Using a Pub/Sub notification channel](/docs/v3/notifications/pubsub-channel/): How to use Google Pub/Sub as an alternative notification channel.