

# Using Amazon SNS for application-to-person messaging
Application-to-person messaging

Amazon SNS application-to-person (A2P) messaging lets you to deliver notifications and alerts directly to your customers' mobile devices through SMS (Short Message Service). Using this feature, you can send push notifications to mobile apps, text messages to mobile phone numbers, and plain-text emails to email addresses. Additionally, you have the flexibility to distribute messages by using topics to reach multiple recipients, or publish messages directly to individual mobile endpoints for personalized communication.

This topic explains how to use Amazon SNS for user notifications with subscribers such as mobile applications, mobile phone numbers, and email addresses.

![\[An overview of how Amazon SNS supports application-to-person (A2P) messaging by allowing publishers to send notifications directly to customers. It shows two primary ways of distributing messages: direct publishing to individual endpoints (such as email addresses, phone numbers, or mobile apps) and topic-based publishing, which sends messages to multiple subscribers at once. The subscribers, represented on the right, can receive notifications through push notifications, text messages, or emails, providing flexibility for different use cases.\]](http://docs.aws.amazon.com/sns/latest/dg/images/sns-a2p-overview.png)


# Mobile text messaging with Amazon SNS
Mobile text messaging

**Important**  
The Amazon SNS SMS Developer Guide has been updated. Amazon SNS has integrated with [AWS End User Messaging SMS](https://docs.aws.amazon.com/sms-voice/latest/userguide/what-is-service.html) for the delivery of SMS messages. This guide contains the latest information on how to create, configure, and manage your Amazon SNS SMS messages.

Amazon SNS mobile text messaging (SMS) is designed to facilitate message delivery to various platforms, such as web, mobile, and business applications that support SMS. Users can send messages to one or multiple phone numbers by subscribing them to a topic, simplifying the distribution process.

Amazon SNS messages are delivered by AWS End User Messaging SMS, which ensures reliable message transmission. Within Amazon SNS APIs, you can set various properties such as message types (promotional or transactional), [monthly spending limits](sms_preferences.md#sms_preferences_console), [opt-out lists](sms_manage.md#sms_manage_optout), and [message delivery optimization](sms_preferences.md#sms_preferences_console).

AWS End User Messaging SMS handles the transmission of messages to the destination phone number through its global SMS supply network. It manages the routing, delivery status, and any required compliance with regional regulations. To access additional SMS features such as granular permissions, phone pools, configurations sets, SMS simulator, and country rule, see the [AWS End User Messaging SMS User Guide](https://docs.aws.amazon.com/sms-voice/latest/userguide/configurations.html).

![\[An illustration of how Amazon SNS integrates with AWS End User Messaging SMS to deliver mobile text messages reliably. Messages can be sent directly to individual recipients or distributed to groups through Amazon SNS topics. AWS End User Messaging SMS handles message routing, delivery, and compliance across its global network, ensuring scalability and reliability. This setup also allows for configuring message preferences, managing spending limits, and tracking delivery status to optimize AWS SMS messaging.\]](http://docs.aws.amazon.com/sns/latest/dg/images/sns-sms-end-user-messaging.png)


The following key features help you send Amazon SNS SMS messages that are scalable and easily extensible:

**[Customize message preferences](sms_preferences.md)**  
Customize SMS deliveries for your AWS account by setting up SMS preferences based on your budget and use case. For example, you can choose whether your messages prioritize cost efficiency or reliable delivery.

**[Set spending quotas](channels-sms-awssupport-spend-threshold.md)**  
Tailor your SMS deliveries by specifying spending quotas or for individual message deliveries and monthly spending quotas for your AWS account. Where required by local laws and regulations (such as the US and Canada), SMS recipients can [opt-out](sms_manage.md#sms_manage_optout), which means that they choose to stop receiving SMS messages from your AWS account. After a recipient opts-out of receiving messages, you can, with limitations, opt-in the phone number again so that you can resume sending messages.

**[Send SMS messages globally](https://docs.aws.amazon.com/sms-voice/latest/userguide/phone-numbers-sms-by-country.html)**  
Amazon SNS supports SMS messaging in multiple regions, allowing you to send messages to over 240 countries and regions.

## How does Amazon SNS deliver my SMS messages?


When you request Amazon SNS to send SMS on your behalf, the messages are dispatched using AWS End User Messaging SMS. The integration between Amazon SNS and AWS End User Messaging SMS offers the following benefits:

**[IAM policies](sns-mobile-phone-number-getting-started.md#sns-mobile-phone-number-prerequisites)**  
You can leverage IAM and resource policies to control and distribute access to your SMS resources across other AWS services and regions.

**[AWS End User Messaging SMS configurations](https://docs.aws.amazon.com/sms-voice/latest/userguide/configurations.html)**  
All origination ID related configurations (creation, configuration updating, provisioning new origination IDs, changing registration templates) use AWS End User Messaging SMS.

**[AWS End User Messaging SMS billing](https://aws.amazon.com/sns/sms-pricing/)**  
All SMS billing is done though AWS End User Messaging SMS. You can consolidate your AWS spend for your SMS workloads, while procuring and managing your SMS resources in one central location.

# Getting started with Amazon SNS SMS
Getting started

**Important**  
The Amazon SNS SMS Developer Guide has been updated. Amazon SNS has integrated with [AWS End User Messaging SMS](https://docs.aws.amazon.com/sms-voice/latest/userguide/what-is-service.html) for the delivery of SMS messages. This guide contains the latest information on how to create, configure, and manage your Amazon SNS SMS messages.

This topic guides you through managing your SMS sandbox and configuring IAM and resource-based policies to grant Amazon SNS the necessary permissions for accessing and utilizing the AWS End User Messaging SMS APIs. 

## Prerequisites


Amazon SNS recommends updating your IAM policy to include the following actions to ensure comprehensive control and visibility over your Amazon SNS resources:
+ [`AmazonSNSFullAccess`](security-iam-awsmanpol.md#security-iam-awsmanpol-AmazonSNSFullAccess)
+ [`AmazonSNSReadOnly`](security-iam-awsmanpol.md#security-iam-awsmanpol-AmazonSNSReadOnlyAccess) 

# Using the Amazon SNS SMS sandbox
SMS sandbox

Newly created Amazon SNS SMS accounts are automatically placed into the SMS sandbox to ensure the security of both AWS customers and recipients by mitigating the risk of fraud and abuse. This environment serves as a secure space for testing and development purposes. While operating within the SMS sandbox, you have access to all Amazon SNS features but are subject to certain limitations:
+ You can only send SMS messages to verified destination phone numbers.
+ You can have up to 10 verified destination phone numbers.
+ You can delete destination phone numbers only after a minimum of 24 hours have passed since verification, or the last verification attempt.

Once your account transitions out of the sandbox, these restrictions are removed, and you can send SMS messages to any recipient.

## First steps


New Amazon SNS SMS accounts are placed into an SMS sandbox. Use the following steps to create and manage phone numbers in your sandbox, create origination numbers and sender IDs, and register your company.

1. Add a **destination phone number** to the SMS sandbox. For details on adding, managing and moving phone numbers out of the Amazon SNS SMS sandbox, see [Adding and verifying phone numbers in the Amazon SNS SMS sandbox](sns-sms-sandbox-verifying-phone-numbers.md).

1. Create an **origination identity** that your recipients see on their devices when you send them an SMS message. To learn more about origination identities, including the different types you can use, see the [Origination identities for Amazon SNS SMS messages](channels-sms-originating-identities.md) documentation.

1. **Register** your company. Some countries require you to register your company's identity to be able to purchase phone numbers or sender IDs and review the messages you send to recipients in their country. For information on which countries require registration, see [Supported countries and regions for SMS messaging with AWS End User Messaging SMS](https://docs.aws.amazon.com/sms-voice/latest/userguide/phone-numbers-sms-by-country.html) in the *AWS End User Messaging SMS User Guide*.

1. **Send** your messages to a topic or mobile phone. For more information, see [Sending SMS messages using Amazon SNS](sms_sending-overview.md).

# Adding and verifying phone numbers in the Amazon SNS SMS sandbox
Adding and verifying phone numbers

Before you can start sending SMS messages from your AWS account while in the [SMS sandbox](sns-sms-sandbox.md), you must complete the following setup steps. This ensures that your account is ready for SMS messaging and that your destination phone numbers are properly verified.

1. Create an **[origination ID](https://docs.aws.amazon.com/sms-voice/latest/userguide/phone-number-types.html)**. Similar to accounts outside of the SMS sandbox, an origination ID is necessary before you can send SMS messages to recipients in some countries or regions.

1. Add the **destination phone numbers** you want to send messages to within the SMS sandbox.

1. Verify the **phone numbers** to ensure that the destination phone numbers are valid for use in your SMS messages.

**Add and verify destination phone numbers**

1. Sign in to the [Amazon SNS console](https://console.aws.amazon.com/sns/home).

1. In the console menu, choose a [region that supports SMS messaging](https://docs.aws.amazon.com/general/latest/gr/end-user-messaging.html).

1. In the navigation pane, choose **Text messaging (SMS)**.

1. In the **Sandbox destination phone numbers** section, select **Add phone number**.

1. Under **Destination details**, provide the following information, and then select **Add phone number**:
   + **Country code** and **phone number** of the destination.
   + The **language** you want the verification message to be sent in.

1. After adding the phone number, Amazon SNS will send an OTP to the provided destination phone number. This OTP is required for verification.

1. You will receive the OTP as a standard SMS message on the **destination phone number** you provided.
   + If you don’t receive the OTP within 15 minutes, select **Resend verification** code in the Amazon SNS console.
   + You can resend the OTP up to five times in a 24-hour period.

1. Once you receive the OTP, enter it in the **Verification code** box and select **Verify phone number**.

1. Check the **verification status**.
   + After successfully verifying the phone number, the phone number and its verification status will appear in the **Sandbox destination phone numbers** section.
   + If the status is **Pending**, the verification was unsuccessful. This may happen if, for example, you didn’t enter the country code correctly.
   + You can only delete pending or verified phone numbers after 24 hours or more have passed since the last verification attempt.

1. If you wish to use the same destination phone number in other regions, **repeat** the previous steps for each region where you intend to use it.

## Troubleshooting non-receipt of an OTP text
Troubleshooting an OTP text

Troubleshoot common problems that may prevent a phone number from receiving OTP texts.
+ **Amazon SNS SMS spending limit:** If your AWS account has exceeded the spending limit for sending SMS messages, further messages, including OTP texts, might not be delivered until the limit is increased or the billing issue is resolved.
+ **Phone number not opted in for SMS notifications:** In some countries or regions, recipients must opt in to receive SMS messages from short codes, which are commonly used for OTP texts. If the recipient's phone number is not opted in, they will not receive the OTP text.
+ **Carrier restrictions or filtering:** Some mobile carriers may have restrictions or filtering mechanisms in place that prevent delivery of certain types of SMS messages, including OTP texts. This could be due to security policies or anti-spam measures implemented by the carrier.
+ **Invalid or incorrect phone number:** If the phone number provided by the recipient is incorrect or invalid, the OTP text will not be delivered.
+ **Network issues:** Temporary network issues or outages could prevent the delivery of SMS messages, including OTP texts, to the recipient's phone.
+ **Delayed delivery:** In some cases, SMS messages may experience delays in delivery due to network congestion or other factors. The OTP text may eventually be delivered, but it could be delayed beyond the expected timeframe.
+ **Account suspension or termination:** If there are issues with your AWS account, such as non-payment or violation of AWS terms of service, Amazon SNS messaging capabilities, including OTP texts, may be suspended or terminated.

# Deleting phone numbers from the Amazon SNS SMS sandbox
Deleting phone numbers

You can delete both pending and verified destination phone numbers from the [SMS sandbox](sns-sms-sandbox.md).

**Important**  
You can only delete a phone number 24 hours after [verifying the phone number](sns-sms-sandbox-verifying-phone-numbers.md), or 24 hours after your last verification attempt.

**To delete destination phone numbers from the SMS sandbox**

1. Sign in to the [Amazon SNS console](https://console.aws.amazon.com/sns/home).

1. In the console menu, choose a [region that supports SMS messaging](https://docs.aws.amazon.com/general/latest/gr/end-user-messaging.html) where you added a destination phone number.

1. In the navigation pane, select **Text messaging (SMS)**.

1. On the **Mobile text messaging (SMS)** page, navigate to the **Sandbox destination phone numbers** section.

1. Choose the specific phone number you want to delete, and then choose **Delete phone number**.

1. To confirm that you want to delete the phone number, enter **delete me**, and then choose **Delete**.

   Ensure that 24 hours or more have passed since you verified or attempted to verify the destination phone number before proceeding with the deletion.

1. Repeat these steps in each Region where you added the destination phone number and no longer plan to use it.

# Moving out of the Amazon SNS SMS sandbox


Moving your AWS account out of the [SMS sandbox](sns-sms-sandbox.md) requires that you first add, verify, and test destination phone numbers. After doing this, create a case with AWS Support.

**To request that your AWS account is moved out of the SMS sandbox**

1. **Verify phone numbers**

   1. While your AWS account is in the SMS sandbox, open the [Amazon SNS console](https://console.aws.amazon.com/sns/home).

   1. In the navigation pane, under Mobile, choose **Text messaging (SMS)**.

   1. In the Sandbox destination phone numbers section, [add and verify](sns-sms-sandbox-verifying-phone-numbers.md) one or more destination phone numbers. This verification ensures you can successfully send and receive messages.

1. **Test SMS publishing**

   1. Confirm that you are able to send and receive messages to at least one verified phone number. For more detailed instructions on how to publish SMS messages, see [Publishing SMS messages to a mobile phone using Amazon SNS](sms_sending-overview.md#sms_publish-to-phone).

1. **Initiate sandbox edit**

   1. On the Amazon SNS console's **Mobile text messaging (SMS)** page, under **Account information**, choose **Exit SMS sandbox**. This action redirects you to the [Amazon Support Center](https://support.console.aws.amazon.com/support/home?#/case/create?issueType=service-limit-increase) and automatically creates a support case with the **Service quota increase** option selected.

1. **Fill out the form**

   1. In the support form under **Service quota increase**, do the following:

     1. Choose choose **SNS Text Messaging** as the service.

     1. Provide the **website URL** or **app name** from which you intend to send SMS messages.

     1. Specify the type of messages you will send: **One Time Password**, **Promotional**, or **Transactional**.

     1. Choose the **AWS Region** from which you will send SMS messages.

     1. List the **countries** or **regions** where you plan to send SMS messages.

     1. Describe how your customers **opt-in to receive messages**.

     1. Include any **message templates** you intend to use.

1. **Specify quota and Region**

   1. Under **Requests**, do the following:

     1. Choose the **AWS Region** where you want to move your AWS account.

     1. Choose **General Limits** for **Resource Type**.

     1. Choose **Exit SMS Sandbox** for **Quota**.

     1. (Optional) To request additional increases or other adjustments, choose **Add another request** and specify the necessary details.

     1. For **New quota value**, enter the **limit** in USD you are requesting.

1. **Additional details**

   1. In the **Case description**, provide any additional details relevant to your request.

   1. Under **Contact options**, choose your **preferred contact language**.

1. **Submit the request**

   1. Choose **Submit** to send your request to Support.

The Support team provides an initial response to your request within 24 hours.

To prevent our systems from being used to send unsolicited or malicious content, we consider each request carefully. If we can, we will grant your request within this 24-hour period. However, if we need additional information from you, it might take longer to resolve your request.

If your use case doesn't align with our policies, we might be unable to grant your request.

# Origination identities for Amazon SNS SMS messages
Origination identities

**Important**  
The Amazon SNS SMS Developer Guide has been updated. Amazon SNS has integrated with [AWS End User Messaging SMS](https://docs.aws.amazon.com/sms-voice/latest/userguide/what-is-service.html) for the delivery of SMS messages. This guide contains the latest information on how to create, configure, and manage your Amazon SNS SMS messages.

Origination identities for SMS messages are identifiers used to represent the sender of an SMS message. You can identify yourself to your recipients using the following types of originating identities:

**Origination numbers**  
A numeric string that identifies an SMS message sender's phone number. There are several types of origination numbers, including long codes (standard phone numbers that typically have 10 or more digits), 10 digit long codes (10DLC), toll free numbers (TFN) and short codes (phone numbers that contain between four and seven digits).  
Support for origination numbers is not available in countries where local laws require the use of sender IDs instead of origination numbers. When you send an SMS message using an origination number, the recipient's device shows the origination number as the sender's phone number. You can specify different origination numbers by use case.  
For additional information, see [Phone numbers](https://docs.aws.amazon.com/sms-voice/latest/userguide/phone-numbers.html) in the *AWS End User Messaging SMS User Guide*.  
To view a list of all existing origination numbers in your AWS account, in the navigation pane of the [Amazon SNS console](https://console.aws.amazon.com/sns/home), choose **Origination numbers**.

**Sender IDs**  
An alphabetic name that identifies the sender of an SMS message. When you send an SMS message using a sender ID, and the recipient is in an area where sender ID authentication is supported, your sender ID appears on the recipient’s device instead of your phone number. A sender ID provides SMS recipients with more information about the sender than a phone number, long code, or short code provides.  
Sender IDs are supported in several countries and regions around the world. In some places, if you're a business that sends SMS messages to individual customers, you must use a sender ID that's pre-registered with a regulatory agency or industry group. For a complete list of countries and regions that support or require sender IDs, see [Supported countries and regions for SMS messaging with AWS End User Messaging SMS](https://docs.aws.amazon.com/sms-voice/latest/userguide/phone-numbers-sms-by-country.html) in the *AWS End User Messaging SMS User Guide*.  
There's no additional charge for using sender IDs. However, support and requirements for sender ID authentication varies by country. Several major markets (including Canada, China, and the United States) don't support using sender IDs. Some areas require that companies who send SMS messages to individual customers must use a sender ID that's pre-registered with a regulatory agency or industry group.  
For additional information, see [Sender IDs](https://docs.aws.amazon.com/sms-voice/latest/userguide/sender-id.html) in the *AWS End User Messaging SMS User Guide*.

# Configuring SMS messaging in Amazon SNS
Configurations

**Important**  
The Amazon SNS SMS Developer Guide has been updated. Amazon SNS has integrated with [AWS End User Messaging SMS](https://docs.aws.amazon.com/sms-voice/latest/userguide/what-is-service.html) for the delivery of SMS messages. This guide contains the latest information on how to create, configure, and manage your Amazon SNS SMS messages.

You can use the configurations in Amazon SNS SMS to set SMS preferences to suit your requirements, such as adjusting spending quotas and setting-up delivery status logging. This topic also provides details on how to publish SMS messages to topics using the Amazon SNS console and AWS SDK, efficiently handle quotas, and retrieve detailed statistics on SMS activity.

# Sending SMS messages using Amazon SNS
Sending SMS messages

This section describes how to send SMS messages using Amazon SNS, including publishing to a topic, subscribing phone numbers to topics, setting attributes on messages, and publishing directly to mobile phones.

## Publishing SMS messages to an Amazon SNS topic
Publishing to a topic

You can publish a single SMS message to many phone numbers at once by subscribing those phone numbers to an Amazon SNS topic. An SNS topic is a communication channel to which you can add subscribers and then publish messages to all of those subscribers. A subscriber receives all messages published to the topic until you cancel the subscription, or until the subscriber opts out of receiving SMS messages from your AWS account.

### Sending a message to a topic using the AWS console


**To create a topic**

Complete the following steps if you don't already have a topic to which you want to send SMS messages.

1. Sign in to the [Amazon SNS console](https://console.aws.amazon.com/sns/home).

1. In the console menu, choose a [region that supports SMS messaging](https://docs.aws.amazon.com/general/latest/gr/end-user-messaging.html).

1. In the navigation pane, choose **Topics**.

1. On the **Topics** page, choose **Create topic**.

1. On the **Create topic** page, under **Details**, do the following:

   1. For **Type**, choose **Standard**.

   1. For **Name**, enter a topic name.

   1. (Optional) For **Display name**, enter a custom prefix for your SMS messages. When you send a message to the topic, Amazon SNS prepends the display name followed by a right angle bracket (>) and a space. Display names are not case sensitive, and Amazon SNS converts display names to uppercase characters. For example, if the display name of a topic is `MyTopic` and the message is `Hello World!`, the message appears as:

      ```
      MYTOPIC> Hello World!
      ```

1. Choose **Create topic**. The topic's name and Amazon Resource Name (ARN) appear on the **Topics** page.

**To create an SMS subscription**

You can use subscriptions to send an SMS message to multiple recipients by publishing the message only once to your topic.
**Note**  
When you start using Amazon SNS to send SMS messages, your AWS account is in the *SMS sandbox*. The SMS sandbox provides a safe environment for you to try Amazon SNS features without risking your reputation as an SMS sender. While your account is in the SMS sandbox, you can use all of the features of Amazon SNS, but you can send SMS messages only to verified destination phone numbers. For more information, see [Using the Amazon SNS SMS sandbox](sns-sms-sandbox.md).

1. Sign in to the [Amazon SNS console](https://console.aws.amazon.com/sns/home).

1. In the navigation pane, choose **Subscriptions**.

1. On the **Subscriptions** page, choose **Create subscription**.

1. On the **Create subscription** page, under **Details**, do the following:

   1. For **Topic ARN**, enter or choose the Amazon Resource Name (ARN) of the topic to which you want to send SMS messages.

   1. For **Protocol**, choose **SMS**.

   1. For **Endpoint**, enter the phone number that you want to subscribe to your topic.

1. Choose **Create subscription**. The subscription information appears on the **Subscriptions** page.

   To add more phone numbers, repeat these steps. You can also add other types of subscriptions, such as email.

**To send a message**

When you publish a message to a topic, Amazon SNS attempts to deliver that message to every phone number that is subscribed to the topic.

1. In the [Amazon SNS console](https://console.aws.amazon.com/sns/home), on the **Topics** page, choose the name of the topic to which you want to send SMS messages.

1. On the topic details page, choose **Publish message**.

1. On the **Publish message to topic** page, under **Message details**, do the following:

   1. For **Subject**, keep the field blank unless your topic contains email subscriptions and you want to publish to both email and SMS subscriptions. Amazon SNS uses the **Subject** that you enter as the email subject line.

   1. (Optional) For **Time to Live (TTL)**, enter a number of seconds that Amazon SNS has to send your SMS message to any mobile application endpoint subscribers.

1. Under **Message body**, do the following:

   1. For **Message structure**, choose **Identical payload for all delivery protocols** to send the same message to all protocol types subscribed to your topic. Or, choose **Custom payload for each delivery protocol** to customize the message for subscribers of different protocol types. For example, you can enter a default message for phone number subscribers and a custom message for email subscribers.

   1. For **Message body to send to the endpoint**, enter your message, or your custom messages per delivery protocol.

      If your topic has a display name, Amazon SNS adds it to the message, which increases the message length. The display name length is the number of characters in the name plus two characters for the right angle bracket (>) and the space that Amazon SNS adds.

      For information about the size quotas for SMS messages, see [Publishing SMS messages to a mobile phone using Amazon SNS](#sms_publish-to-phone).

1. (Optional) For **Message attributes**, add message metadata such as timestamps, signatures, and IDs.

1. Choose **Publish message**. Amazon SNS sends the SMS message and displays a success message.

### Sending a message to a topic using the AWS SDKs


To use an AWS SDK, you must configure it with your credentials. For more information, see [The shared config and credentials files](https://docs.aws.amazon.com/sdkref/latest/guide/creds-config-files.html) in the *AWS SDKs and Tools Reference Guide*.

The following code example shows how to:
+ Create an Amazon SNS topic.
+ Subscribe phone numbers to the topic.
+ Publish SMS messages to the topic so that all subscribed phone numbers receive the message at once.

------
#### [ Java ]

**SDK for Java 2.x**  
 There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/javav2/example_code/sns#code-examples). 
Create a topic and return its ARN.  

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.sns.SnsClient;
import software.amazon.awssdk.services.sns.model.CreateTopicRequest;
import software.amazon.awssdk.services.sns.model.CreateTopicResponse;
import software.amazon.awssdk.services.sns.model.SnsException;

/**
 * Before running this Java V2 code example, set up your development
 * environment, including your credentials.
 *
 * For more information, see the following documentation topic:
 *
 * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
 */
public class CreateTopic {
    public static void main(String[] args) {
        final String usage = """

                Usage:    <topicName>

                Where:
                   topicName - The name of the topic to create (for example, mytopic).

                """;

        if (args.length != 1) {
            System.out.println(usage);
            System.exit(1);
        }

        String topicName = args[0];
        System.out.println("Creating a topic with name: " + topicName);
        SnsClient snsClient = SnsClient.builder()
                .region(Region.US_EAST_1)
                .build();

        String arnVal = createSNSTopic(snsClient, topicName);
        System.out.println("The topic ARN is" + arnVal);
        snsClient.close();
    }

    public static String createSNSTopic(SnsClient snsClient, String topicName) {
        CreateTopicResponse result;
        try {
            CreateTopicRequest request = CreateTopicRequest.builder()
                    .name(topicName)
                    .build();

            result = snsClient.createTopic(request);
            return result.topicArn();

        } catch (SnsException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
        return "";
    }
}
```
Subscribe an endpoint to a topic.  

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.sns.SnsClient;
import software.amazon.awssdk.services.sns.model.SnsException;
import software.amazon.awssdk.services.sns.model.SubscribeRequest;
import software.amazon.awssdk.services.sns.model.SubscribeResponse;

/**
 * Before running this Java V2 code example, set up your development
 * environment, including your credentials.
 *
 * For more information, see the following documentation topic:
 *
 * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
 */
public class SubscribeTextSMS {
    public static void main(String[] args) {
        final String usage = """

                Usage:    <topicArn> <phoneNumber>

                Where:
                   topicArn - The ARN of the topic to subscribe.
                   phoneNumber - A mobile phone number that receives notifications (for example, +1XXX5550100).
                """;

        if (args.length < 2) {
            System.out.println(usage);
            System.exit(1);
        }

        String topicArn = args[0];
        String phoneNumber = args[1];
        SnsClient snsClient = SnsClient.builder()
                .region(Region.US_EAST_1)
                .build();

        subTextSNS(snsClient, topicArn, phoneNumber);
        snsClient.close();
    }

    public static void subTextSNS(SnsClient snsClient, String topicArn, String phoneNumber) {
        try {
            SubscribeRequest request = SubscribeRequest.builder()
                    .protocol("sms")
                    .endpoint(phoneNumber)
                    .returnSubscriptionArn(true)
                    .topicArn(topicArn)
                    .build();

            SubscribeResponse result = snsClient.subscribe(request);
            System.out.println("Subscription ARN: " + result.subscriptionArn() + "\n\n Status is "
                    + result.sdkHttpResponse().statusCode());

        } catch (SnsException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
    }
}
```
Set attributes on the message, such as the ID of the sender, the maximum price, and its type. Message attributes are optional.  

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.sns.SnsClient;
import software.amazon.awssdk.services.sns.model.SetSmsAttributesRequest;
import software.amazon.awssdk.services.sns.model.SetSmsAttributesResponse;
import software.amazon.awssdk.services.sns.model.SnsException;
import java.util.HashMap;

/**
 * Before running this Java V2 code example, set up your development
 * environment, including your credentials.
 *
 * For more information, see the following documentation topic:
 *
 * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
 */
public class SetSMSAttributes {
    public static void main(String[] args) {
        HashMap<String, String> attributes = new HashMap<>(1);
        attributes.put("DefaultSMSType", "Transactional");
        attributes.put("UsageReportS3Bucket", "janbucket");

        SnsClient snsClient = SnsClient.builder()
                .region(Region.US_EAST_1)
                .build();
        setSNSAttributes(snsClient, attributes);
        snsClient.close();
    }

    public static void setSNSAttributes(SnsClient snsClient, HashMap<String, String> attributes) {
        try {
            SetSmsAttributesRequest request = SetSmsAttributesRequest.builder()
                    .attributes(attributes)
                    .build();

            SetSmsAttributesResponse result = snsClient.setSMSAttributes(request);
            System.out.println("Set default Attributes to " + attributes + ". Status was "
                    + result.sdkHttpResponse().statusCode());

        } catch (SnsException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
    }
}
```
Publish a message to a topic. The message is sent to every subscriber.  

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.sns.SnsClient;
import software.amazon.awssdk.services.sns.model.PublishRequest;
import software.amazon.awssdk.services.sns.model.PublishResponse;
import software.amazon.awssdk.services.sns.model.SnsException;

/**
 * Before running this Java V2 code example, set up your development
 * environment, including your credentials.
 *
 * For more information, see the following documentation topic:
 *
 * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
 */
public class PublishTextSMS {
    public static void main(String[] args) {
        final String usage = """

                Usage:    <message> <phoneNumber>

                Where:
                   message - The message text to send.
                   phoneNumber - The mobile phone number to which a message is sent (for example, +1XXX5550100).\s
                """;

        if (args.length != 2) {
            System.out.println(usage);
            System.exit(1);
        }

        String message = args[0];
        String phoneNumber = args[1];
        SnsClient snsClient = SnsClient.builder()
                .region(Region.US_EAST_1)
                .build();
        pubTextSMS(snsClient, message, phoneNumber);
        snsClient.close();
    }

    public static void pubTextSMS(SnsClient snsClient, String message, String phoneNumber) {
        try {
            PublishRequest request = PublishRequest.builder()
                    .message(message)
                    .phoneNumber(phoneNumber)
                    .build();

            PublishResponse result = snsClient.publish(request);
            System.out
                    .println(result.messageId() + " Message sent. Status was " + result.sdkHttpResponse().statusCode());

        } catch (SnsException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
    }
}
```

------

## Publishing SMS messages to a mobile phone using Amazon SNS
Publishing to a mobile phone

You can use Amazon SNS to send SMS messages directly to a mobile phone without subscribing the phone number to an Amazon SNS topic.

**Note**  
Subscribing phone numbers to a topic is useful if you want to send one message to multiple phone numbers at once. For instructions on publishing an SMS message to a topic, see [Publishing SMS messages to an Amazon SNS topic](#sms_publish-to-topic).

When you send a message, you can control whether the message is optimized for cost or reliable delivery. You can also specify a [sender ID or origination number](channels-sms-originating-identities.md). If you send the message programmatically using the Amazon SNS API or the AWS SDKs, you can specify a maximum price for the message delivery.

Each SMS message can contain up to 140 bytes, and the character quota depends on the encoding scheme. For example, an SMS message can contain:
+ 160 GSM characters
+ 140 ASCII characters
+ 70 UCS-2 characters

If you publish a message that exceeds the size quota, Amazon SNS sends it as multiple messages, each fitting within the size quota. Messages are not cut off in the middle of a word, but instead on whole-word boundaries. The total size quota for a single SMS publish action is 1,600 bytes.

When you send an SMS message, you specify the phone number using the E.164 format, a standard phone numbering structure used for international telecommunication. Phone numbers that follow this format can have a maximum of 15 digits along with the prefix of a plus sign (\$1) and the country code. For example, a US phone number in E.164 format appears as \$11XXX5550100.

### Sending a message (console)


1. Sign in to the [Amazon SNS console](https://console.aws.amazon.com/sns/home).

1. In the console menu, choose a [region that supports SMS messaging](https://docs.aws.amazon.com/general/latest/gr/end-user-messaging.html).

1. In the navigation pane, choose **Text messaging (SMS)**.

1. On the **Mobile text messaging (SMS)** page, choose **Publish text message**.

1. On the **Publish SMS message** page, for **Message type**, choose one of the following:
   + **Promotional** – Non-critical messages, such as marketing messages.
   + **Transactional** – Critical messages that support customer transactions, such as one-time passcodes for multi-factor authentication.
**Note**  
This message-level setting overrides your account-level default message type. You can set an account-level default message type from the **Text messaging preferences** section of the **Mobile text messaging (SMS)** page.

   For pricing information for promotional and transactional messages, see [Worldwide SMS Pricing](https://aws.amazon.com/sns/sms-pricing/).

1. For **Destination phone number**, enter the phone number to which you want to send the message.

1. For **Message**, enter the message to send.

1. (Optional) Under **Origination identities**, specify how to identify yourself to your recipients:
   + To specify a **Sender ID**, type a custom ID that contains 3-11 alphanumeric characters, including at least one letter and no spaces. The sender ID is displayed as the message sender on the receiving device. For example, you can use your business brand to make the message source easier to recognize.

     Support for sender IDs varies by country and/or region. For example, messages delivered to U.S. phone numbers will not display the sender ID. For the countries and regions that support sender IDs, see [Supported countries and regions for SMS messaging with AWS End User Messaging SMS](https://docs.aws.amazon.com/sms-voice/latest/userguide/phone-numbers-sms-by-country.html) in the *AWS End User Messaging SMS User Guide*.

     If you do not specify a sender ID, one of the following is displayed as the originating identity:
     + In countries that support long codes, the long code is shown.
     + In countries where only sender IDs are supported, *NOTICE* is shown.

     This message-level sender ID overrides your default sender ID, which you set on the **Text messaging preferences** page.
   + To specify an **Origination number**, enter a string of 5-14 numbers to display as the sender's phone number on the receiver's device. This string must match an origination number that is configured in your AWS account for the destination country. The origination number can be a 10DLC number, toll-free number, person-to-person long code, or short codes. For more information, see [Origination identities for Amazon SNS SMS messages](channels-sms-originating-identities.md).

     If you don't specify an origination number, Amazon SNS selects an origination number to use for the SMS text message, based on your AWS account configuration.

1. If you're sending SMS messages to recipients in India, expand **Country-specific attributes**, and specify the following attributes:
   + **Entity ID** – The entity ID or principal entity (PE) ID for sending SMS messages to recipients in India. This ID is a unique string of 1–50 characters that the Telecom Regulatory Authority of India (TRAI) provides to identify the entity that you registered with the TRAI.
   + **Template ID** – The template ID for sending SMS messages to recipients in India. This ID is a unique, TRAI-provided string of 1–50 characters that identifies the template that you registered with the TRAI. The template ID must be associated with the sender ID that you specified for the message.

   For more information on sending SMS messages to recipients in India, [India sender ID registration process](https://docs.aws.amazon.com/sms-voice/latest/userguide/registrations-sms-senderid-india.html) in the *AWS End User Messaging SMS User Guide*.

1. Choose **Publish message**.

**Tip**  
To send SMS messages from an origination number, you can also choose **Origination numbers** in the Amazon SNS console navigation panel. Choose an origination number that includes **SMS** in the **Capabilities** column, and then choose **Publish text message**.

### Sending a message (AWS SDKs)


To send an SMS message using one of the AWS SDKs, use the API operation in that SDK that corresponds to the `Publish` request in the Amazon SNS API. With this request, you can send an SMS message directly to a phone number. You can also use the `MessageAttributes` parameter to set values for the following attribute names:

**`AWS.SNS.SMS.SenderID`**  
A custom ID that contains 3–11 alphanumeric characters or hyphen (-) characters, including at least one letter and no spaces. The sender ID appears as the message sender on the receiving device. For example, you can use your business brand to help make the message source easier to recognize.  
Support for sender IDs varies by country or region. For example, messages delivered to US phone numbers don't display the sender ID. For a list of the countries or regions that support sender IDs, see [Supported countries and regions for SMS messaging with AWS End User Messaging SMS](https://docs.aws.amazon.com/sms-voice/latest/userguide/phone-numbers-sms-by-country.html) in the *AWS End User Messaging SMS User Guide*.  
If you don't specify a sender ID, a [long code](https://docs.aws.amazon.com/sms-voice/latest/userguide/phone-numbers-request-long-code.html) appears as the sender ID in supported countries or regions. For countries or regions that require an alphabetic sender ID, *NOTICE* appears as the sender ID.  
This message-level attribute overrides the account-level attribute `DefaultSenderID`, which you can set using the `SetSMSAttributes` request.

**`AWS.MM.SMS.OriginationNumber`**  
A custom string of 5–14 numbers, which can include an optional leading plus sign (`+`). This string of numbers appears as the sender's phone number on the receiving device. The string must match an origination number that's configured in your AWS account for the destination country. The origination number can be a 10DLC number, toll-free number, person-to-person (P2P) long code, or short code. For more information, see [Phone numbers](https://docs.aws.amazon.com/sms-voice/latest/userguide/phone-numbers.html) in the *AWS End User Messaging SMS User Guide*.  
If you don't specify an origination number, Amazon SNS chooses an origination number based on your AWS account configuration.

**`AWS.SNS.SMS.MaxPrice`**  
The maximum price in USD that you're willing to spend to send the SMS message. If Amazon SNS determines that sending the message would incur a cost that exceeds your maximum price, it doesn't send the message.  
This attribute has no effect if your month-to-date SMS costs have already exceeded the quota set for the `MonthlySpendLimit` attribute. You can set the `MonthlySpendLimit` attribute using the `SetSMSAttributes` request.  
If you're sending the message to an Amazon SNS topic, the maximum price applies to each message delivery to each phone number that is subscribed to the topic.

**`AWS.SNS.SMS.SMSType`**  
The type of message that you're sending:  
+ **`Promotional`** (default) – Non-critical messages, such as marketing messages.
+ **`Transactional`** – Critical messages that support customer transactions, such as one-time passcodes for multi-factor authentication.
This message-level attribute overrides the account-level attribute `DefaultSMSType`, which you can set using the `SetSMSAttributes` request.

**`AWS.MM.SMS.EntityId`**  
This attribute is required only for sending SMS messages to recipients in India.  
This is your entity ID or principal entity (PE) ID for sending SMS messages to recipients in India. This ID is a unique string of 1–50 characters that the Telecom Regulatory Authority of India (TRAI) provides to identify the entity that you registered with the TRAI.

**`AWS.MM.SMS.TemplateId`**  
This attribute is required only for sending SMS messages to recipients in India.  
This is your template for sending SMS messages to recipients in India. This ID is a unique, TRAI-provided string of 1–50 characters that identifies the template that you registered with the TRAI. The template ID must be associated with the sender ID that you specified for the message.

#### Sending a message


The following code examples show how to publish SMS messages using Amazon SNS.

------
#### [ .NET ]

**SDK for .NET**  
 There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/dotnetv3/SNS#code-examples). 

```
namespace SNSMessageExample
{
    using System;
    using System.Threading.Tasks;
    using Amazon;
    using Amazon.SimpleNotificationService;
    using Amazon.SimpleNotificationService.Model;

    public class SNSMessage
    {
        private AmazonSimpleNotificationServiceClient snsClient;

        /// <summary>
        /// Initializes a new instance of the <see cref="SNSMessage"/> class.
        /// Constructs a new SNSMessage object initializing the Amazon Simple
        /// Notification Service (Amazon SNS) client using the supplied
        /// Region endpoint.
        /// </summary>
        /// <param name="regionEndpoint">The Amazon Region endpoint to use in
        /// sending test messages with this object.</param>
        public SNSMessage(RegionEndpoint regionEndpoint)
        {
            snsClient = new AmazonSimpleNotificationServiceClient(regionEndpoint);
        }

        /// <summary>
        /// Sends the SMS message passed in the text parameter to the phone number
        /// in phoneNum.
        /// </summary>
        /// <param name="phoneNum">The ten-digit phone number to which the text
        /// message will be sent.</param>
        /// <param name="text">The text of the message to send.</param>
        /// <returns>Async task.</returns>
        public async Task SendTextMessageAsync(string phoneNum, string text)
        {
            if (string.IsNullOrEmpty(phoneNum) || string.IsNullOrEmpty(text))
            {
                return;
            }

            // Now actually send the message.
            var request = new PublishRequest
            {
                Message = text,
                PhoneNumber = phoneNum,
            };

            try
            {
                var response = await snsClient.PublishAsync(request);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error sending message: {ex}");
            }
        }
    }
}
```
+  For API details, see [Publish](https://docs.aws.amazon.com/goto/DotNetSDKV3/sns-2010-03-31/Publish) in *AWS SDK for .NET API Reference*. 

------
#### [ C\$1\$1 ]

**SDK for C\$1\$1**  
 There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/sns#code-examples). 

```
/**
 * Publish SMS: use Amazon Simple Notification Service (Amazon SNS) to send an SMS text message to a phone number.
 * Note: This requires additional AWS configuration prior to running example. 
 * 
 *  NOTE: When you start using Amazon SNS to send SMS messages, your AWS account is in the SMS sandbox and you can only
 *  use verified destination phone numbers. See https://docs.aws.amazon.com/sns/latest/dg/sns-sms-sandbox.html.
 *  NOTE: If destination is in the US, you also have an additional restriction that you have use a dedicated
 *  origination ID (phone number). You can request an origination number using Amazon Pinpoint for a fee.
 *  See https://aws.amazon.com/blogs/compute/provisioning-and-using-10dlc-origination-numbers-with-amazon-sns/ 
 *  for more information. 
 * 
 *  <phone_number_value> input parameter uses E.164 format. 
 *  For example, in United States, this input value should be of the form: +12223334444
 */

//! Send an SMS text message to a phone number.
/*!
  \param message: The message to publish.
  \param phoneNumber: The phone number of the recipient in E.164 format.
  \param clientConfiguration: AWS client configuration.
  \return bool: Function succeeded.
 */
bool AwsDoc::SNS::publishSms(const Aws::String &message,
                             const Aws::String &phoneNumber,
                             const Aws::Client::ClientConfiguration &clientConfiguration) {
    Aws::SNS::SNSClient snsClient(clientConfiguration);

    Aws::SNS::Model::PublishRequest request;
    request.SetMessage(message);
    request.SetPhoneNumber(phoneNumber);

    const Aws::SNS::Model::PublishOutcome outcome = snsClient.Publish(request);

    if (outcome.IsSuccess()) {
        std::cout << "Message published successfully with message id, '"
                  << outcome.GetResult().GetMessageId() << "'."
                  << std::endl;
    }
    else {
        std::cerr << "Error while publishing message "
                  << outcome.GetError().GetMessage()
                  << std::endl;
    }

    return outcome.IsSuccess();
}
```
+  For API details, see [Publish](https://docs.aws.amazon.com/goto/SdkForCpp/sns-2010-03-31/Publish) in *AWS SDK for C\$1\$1 API Reference*. 

------
#### [ Java ]

**SDK for Java 2.x**  
 There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/javav2/example_code/sns#code-examples). 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.sns.SnsClient;
import software.amazon.awssdk.services.sns.model.PublishRequest;
import software.amazon.awssdk.services.sns.model.PublishResponse;
import software.amazon.awssdk.services.sns.model.SnsException;

/**
 * Before running this Java V2 code example, set up your development
 * environment, including your credentials.
 *
 * For more information, see the following documentation topic:
 *
 * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
 */
public class PublishTextSMS {
    public static void main(String[] args) {
        final String usage = """

                Usage:    <message> <phoneNumber>

                Where:
                   message - The message text to send.
                   phoneNumber - The mobile phone number to which a message is sent (for example, +1XXX5550100).\s
                """;

        if (args.length != 2) {
            System.out.println(usage);
            System.exit(1);
        }

        String message = args[0];
        String phoneNumber = args[1];
        SnsClient snsClient = SnsClient.builder()
                .region(Region.US_EAST_1)
                .build();
        pubTextSMS(snsClient, message, phoneNumber);
        snsClient.close();
    }

    public static void pubTextSMS(SnsClient snsClient, String message, String phoneNumber) {
        try {
            PublishRequest request = PublishRequest.builder()
                    .message(message)
                    .phoneNumber(phoneNumber)
                    .build();

            PublishResponse result = snsClient.publish(request);
            System.out
                    .println(result.messageId() + " Message sent. Status was " + result.sdkHttpResponse().statusCode());

        } catch (SnsException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
    }
}
```
+  For API details, see [Publish](https://docs.aws.amazon.com/goto/SdkForJavaV2/sns-2010-03-31/Publish) in *AWS SDK for Java 2.x API Reference*. 

------
#### [ Kotlin ]

**SDK for Kotlin**  
 There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/kotlin/services/sns#code-examples). 

```
suspend fun pubTextSMS(
    messageVal: String?,
    phoneNumberVal: String?,
) {
    val request =
        PublishRequest {
            message = messageVal
            phoneNumber = phoneNumberVal
        }

    SnsClient.fromEnvironment { region = "us-east-1" }.use { snsClient ->
        val result = snsClient.publish(request)
        println("${result.messageId} message sent.")
    }
}
```
+  For API details, see [Publish](https://sdk.amazonaws.com/kotlin/api/latest/index.html) in *AWS SDK for Kotlin API reference*. 

------
#### [ PHP ]

**SDK for PHP**  
 There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/php/example_code/sns#code-examples). 

```
require 'vendor/autoload.php';

use Aws\Exception\AwsException;
use Aws\Sns\SnsClient;


/**
 * Sends a text message (SMS message) directly to a phone number using Amazon SNS.
 *
 * This code expects that you have AWS credentials set up per:
 * https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/guide_credentials.html
 */

$SnSclient = new SnsClient([
    'profile' => 'default',
    'region' => 'us-east-1',
    'version' => '2010-03-31'
]);

$message = 'This message is sent from a Amazon SNS code sample.';
$phone = '+1XXX5550100';

try {
    $result = $SnSclient->publish([
        'Message' => $message,
        'PhoneNumber' => $phone,
    ]);
    var_dump($result);
} catch (AwsException $e) {
    // output error message if fails
    error_log($e->getMessage());
}
```
+  For more information, see [AWS SDK for PHP Developer Guide](https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/sns-examples-sending-sms.html#publish-to-a-text-message-sms-message). 
+  For API details, see [Publish](https://docs.aws.amazon.com/goto/SdkForPHPV3/sns-2010-03-31/Publish) in *AWS SDK for PHP API Reference*. 

------
#### [ Python ]

**SDK for Python (Boto3)**  
 There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/python/example_code/sns#code-examples). 

```
class SnsWrapper:
    """Encapsulates Amazon SNS topic and subscription functions."""

    def __init__(self, sns_resource):
        """
        :param sns_resource: A Boto3 Amazon SNS resource.
        """
        self.sns_resource = sns_resource


    def publish_text_message(self, phone_number, message):
        """
        Publishes a text message directly to a phone number without need for a
        subscription.

        :param phone_number: The phone number that receives the message. This must be
                             in E.164 format. For example, a United States phone
                             number might be +12065550101.
        :param message: The message to send.
        :return: The ID of the message.
        """
        try:
            response = self.sns_resource.meta.client.publish(
                PhoneNumber=phone_number, Message=message
            )
            message_id = response["MessageId"]
            logger.info("Published message to %s.", phone_number)
        except ClientError:
            logger.exception("Couldn't publish message to %s.", phone_number)
            raise
        else:
            return message_id
```
+  For API details, see [Publish](https://docs.aws.amazon.com/goto/boto3/sns-2010-03-31/Publish) in *AWS SDK for Python (Boto3) API Reference*. 

------
#### [ SAP ABAP ]

**SDK for SAP ABAP**  
 There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/sap-abap/services/sns#code-examples). 

```
    " iv_phone_number = '+12065550101' - Phone number in E.164 format
    TRY.
        oo_result = lo_sns->publish(              " oo_result is returned for testing purposes. "
          iv_phonenumber = iv_phone_number
          iv_message = iv_message ).
        MESSAGE 'Message published to phone number.' TYPE 'I'.
      CATCH /aws1/cx_snsnotfoundexception.
        MESSAGE 'Phone number does not exist.' TYPE 'E'.
    ENDTRY.
```
+  For API details, see [Publish](https://docs.aws.amazon.com/sdk-for-sap-abap/v1/api/latest/index.html) in *AWS SDK for SAP ABAP API reference*. 

------

# Setting SMS messaging preferences in Amazon SNS
Setting SMS preferences

Use Amazon SNS to specify preferences for SMS messaging. For example, you can specify whether to optimize deliveries for cost or reliability, your monthly spending limit, how deliveries are logged, and whether to subscribe to daily SMS usage reports.

These preferences take effect for every SMS message that you send from your account, but you can override some of them when you send an individual message. For more information, see [Publishing SMS messages to a mobile phone using Amazon SNS](sms_sending-overview.md#sms_publish-to-phone).

## Setting SMS messaging preferences using the AWS Management Console


1. Sign in to the [Amazon SNS console](https://console.aws.amazon.com/sns/home).

1. Choose a [region that supports SMS messaging](https://docs.aws.amazon.com/general/latest/gr/end-user-messaging.html).

1. On the navigation panel, choose **Mobile** and then **Text messaging (SMS)**.

1. On the **Mobile text messaging (SMS)** page, in the **Text messaging preferences** section, choose **Edit**.

1. On the **Edit text messaging preferences** page, in the **Details** section, do the following:

   1. For **Default message type**, choose one of the following:
      + **Promotional** – Non-critical messages (for example, marketing). Amazon SNS optimizes message delivery to incur the lowest cost.
      + **Transactional** (default) – Critical messages that support customer transactions, such as one-time passcodes for multi-factor authentication. Amazon SNS optimizes message delivery to achieve the highest reliability.

      For pricing information for promotional and transactional messages, see [Global SMS Pricing](https://aws.amazon.com/sns/sms-pricing/).

   1. (Optional) For **Account spend limit**, enter the amount (in USD) that you want to spend on SMS messages each calendar month.
**Important**  
By default, the spend quota is set to 1.00 USD. If you want to raise the service quota, [submit a request](https://console.aws.amazon.com/support/home#/case/create?issueType=service-limit-increase&limitType=service-code-sns).
If the amount set in the console exceeds your service quota, Amazon SNS stops publishing SMS messages.
Because Amazon SNS is a distributed system, it stops sending SMS messages within minutes of the spend quota being exceeded. During this interval, if you continue to send SMS messages, you might incur costs that exceed your quota.

1. (Optional) For **Default sender ID**, enter a custom ID, such as your business brand, which is displayed as the sender of the receiving device.
**Note**  
Support for sender IDs varies by country.

1. (Optional) Enter the name of the **Amazon S3 bucket name for usage reports**.
**Note**  
The Amazon S3 bucket policy must grant write access to Amazon SNS.

1. Choose **Save changes**.

## Setting preferences (AWS SDKs)


To set your SMS preferences using one of the AWS SDKs, use the action in that SDK that corresponds to the `SetSMSAttributes` request in the Amazon SNS API. With this request, you assign values to the different SMS attributes, such as your monthly spend quota and your default SMS type (promotional or transactional). For all SMS attributes, see [SetSMSAttributes](https://docs.aws.amazon.com/sns/latest/api/API_SetSMSAttributes.html) in the *Amazon Simple Notification Service API Reference*.

The following code examples show how to use `SetSMSAttributes`.

------
#### [ C\$1\$1 ]

**SDK for C\$1\$1**  
 There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/sns#code-examples). 
How to use Amazon SNS to set the DefaultSMSType attribute.  

```
//! Set the default settings for sending SMS messages.
/*!
  \param smsType: The type of SMS message that you will send by default.
  \param clientConfiguration: AWS client configuration.
  \return bool: Function succeeded.
 */
bool AwsDoc::SNS::setSMSType(const Aws::String &smsType,
                             const Aws::Client::ClientConfiguration &clientConfiguration) {
    Aws::SNS::SNSClient snsClient(clientConfiguration);

    Aws::SNS::Model::SetSMSAttributesRequest request;
    request.AddAttributes("DefaultSMSType", smsType);

    const Aws::SNS::Model::SetSMSAttributesOutcome outcome = snsClient.SetSMSAttributes(
            request);

    if (outcome.IsSuccess()) {
        std::cout << "SMS Type set successfully " << std::endl;
    }
    else {
        std::cerr << "Error while setting SMS Type: '"
                  << outcome.GetError().GetMessage()
                  << "'" << std::endl;
    }

    return outcome.IsSuccess();
}
```
+  For API details, see [SetSMSAttributes](https://docs.aws.amazon.com/goto/SdkForCpp/sns-2010-03-31/SetSMSAttributes) in *AWS SDK for C\$1\$1 API Reference*. 

------
#### [ CLI ]

**AWS CLI**  
**To set SMS message attributes**  
The following `set-sms-attributes` example sets the default sender ID for SMS messages to `MyName`.  

```
aws sns set-sms-attributes \
    --attributes DefaultSenderID=MyName
```
This command produces no output.  
+  For API details, see [SetSMSAttributes](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/sns/set-sms-attributes.html) in *AWS CLI Command Reference*. 

------
#### [ Java ]

**SDK for Java 2.x**  
 There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/javav2/example_code/sns#code-examples). 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.sns.SnsClient;
import software.amazon.awssdk.services.sns.model.SetSmsAttributesRequest;
import software.amazon.awssdk.services.sns.model.SetSmsAttributesResponse;
import software.amazon.awssdk.services.sns.model.SnsException;
import java.util.HashMap;

/**
 * Before running this Java V2 code example, set up your development
 * environment, including your credentials.
 *
 * For more information, see the following documentation topic:
 *
 * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
 */
public class SetSMSAttributes {
    public static void main(String[] args) {
        HashMap<String, String> attributes = new HashMap<>(1);
        attributes.put("DefaultSMSType", "Transactional");
        attributes.put("UsageReportS3Bucket", "janbucket");

        SnsClient snsClient = SnsClient.builder()
                .region(Region.US_EAST_1)
                .build();
        setSNSAttributes(snsClient, attributes);
        snsClient.close();
    }

    public static void setSNSAttributes(SnsClient snsClient, HashMap<String, String> attributes) {
        try {
            SetSmsAttributesRequest request = SetSmsAttributesRequest.builder()
                    .attributes(attributes)
                    .build();

            SetSmsAttributesResponse result = snsClient.setSMSAttributes(request);
            System.out.println("Set default Attributes to " + attributes + ". Status was "
                    + result.sdkHttpResponse().statusCode());

        } catch (SnsException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
    }
}
```
+  For API details, see [SetSMSAttributes](https://docs.aws.amazon.com/goto/SdkForJavaV2/sns-2010-03-31/SetSMSAttributes) in *AWS SDK for Java 2.x API Reference*. 

------
#### [ JavaScript ]

**SDK for JavaScript (v3)**  
 There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/javascriptv3/example_code/sns#code-examples). 
Create the client in a separate module and export it.  

```
import { SNSClient } from "@aws-sdk/client-sns";

// The AWS Region can be provided here using the `region` property. If you leave it blank
// the SDK will default to the region set in your AWS config.
export const snsClient = new SNSClient({});
```
Import the SDK and client modules and call the API.  

```
import { SetSMSAttributesCommand } from "@aws-sdk/client-sns";
import { snsClient } from "../libs/snsClient.js";

/**
 * @param {"Transactional" | "Promotional"} defaultSmsType
 */
export const setSmsType = async (defaultSmsType = "Transactional") => {
  const response = await snsClient.send(
    new SetSMSAttributesCommand({
      attributes: {
        // Promotional – (Default) Noncritical messages, such as marketing messages.
        // Transactional – Critical messages that support customer transactions,
        // such as one-time passcodes for multi-factor authentication.
        DefaultSMSType: defaultSmsType,
      },
    }),
  );
  console.log(response);
  // {
  //   '$metadata': {
  //     httpStatusCode: 200,
  //     requestId: '1885b977-2d7e-535e-8214-e44be727e265',
  //     extendedRequestId: undefined,
  //     cfId: undefined,
  //     attempts: 1,
  //     totalRetryDelay: 0
  //   }
  // }
  return response;
};
```
+  For more information, see [AWS SDK for JavaScript Developer Guide](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/sns-examples-sending-sms.html#sending-sms-setattributes). 
+  For API details, see [SetSMSAttributes](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/sns/command/SetSMSAttributesCommand) in *AWS SDK for JavaScript API Reference*. 

------
#### [ PHP ]

**SDK for PHP**  
 There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/php/example_code/sns#code-examples). 

```
$SnSclient = new SnsClient([
    'profile' => 'default',
    'region' => 'us-east-1',
    'version' => '2010-03-31'
]);

try {
    $result = $SnSclient->SetSMSAttributes([
        'attributes' => [
            'DefaultSMSType' => 'Transactional',
        ],
    ]);
    var_dump($result);
} catch (AwsException $e) {
    // output error message if fails
    error_log($e->getMessage());
}
```
+  For more information, see [AWS SDK for PHP Developer Guide](https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/sns-examples-sending-sms.html#set-sms-attributes). 
+  For API details, see [SetSMSAttributes](https://docs.aws.amazon.com/goto/SdkForPHPV3/sns-2010-03-31/SetSMSAttributes) in *AWS SDK for PHP API Reference*. 

------

## Setting SMS messaging preferences for country-specific delivery


You can manage and control your SMS traffic by sending messages only to specific destination countries. This ensures that your messages are sent only to approved countries, avoiding unwanted SMS charges. The following instructions use Amazon Pinpoint's Protect configuration to specify the countries you want to allow or block.

1. Open the AWS SMS console at [https://console.aws.amazon.com/sms-voice/](https://console.aws.amazon.com/sms-voice/).

1. In the navigation pane, under **Overview**, in the **Quick start** section, choose **Create a protect configuration**.

1. Under **Protect configuration details**, enter a **business-friendly name** for your protect configuration (for example, Allow-Only-AU).

1. Under **SMS country rules**, select the **Region/Country** checkbox to block sending messages to all supported countries.

1. Deselect the checkboxes for the countries where you want to send messages. For example, to allow messages only to Australia, deselect the checkbox for **Australia**.

1. In the **Protect configuration associations** section, under **Association type**, select **Account default**. This will ensure that the AWS End User Messaging SMS Protect configuration affects all messages sent through Amazon SNS, [Amazon Cognito](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-identity-pools.html), and the Amazon Pinpoint [https://docs.aws.amazon.com/pinpoint/latest/developerguide/send-messages-sms.html](https://docs.aws.amazon.com/pinpoint/latest/developerguide/send-messages-sms.html) API call.

1. Choose **Create protect configuration** to save your settings.

   The following confirmation message is displayed:

   ```
   Success Protect configuration protect-abc0123456789 has been created.
   ```

1. Sign in to the [Amazon SNS console](https://console.aws.amazon.com/sns/home).

1. [**Publish a message**](sns-publishing.md) to one of the blocked countries, such as India.

   The message will not be delivered. You can verify this in the delivery failure logs using [CloudWatch](sms_stats_cloudwatch.md). Search for log group **sns/region/AccountID/DirectPublishToPhoneNumber/Failure** for a response similar to the following example:

   ```
   {
   "notification": {
   "messageId": "bd59a509-XXXX-XXXX-82f8-fbdb8cb68217",
   "timestamp": "YYYY-MM-DD XX:XX:XX.XXXX“
   },
   "delivery": {
   "destination": "+91XXXXXXXXXX",
   "smsType": "Transactional",
   "providerResponse": "Cannot deliver message to the specified destination country",
   "dwellTimeMs": 85
   },
   "status": "FAILURE"
   }
   ```

# Managing Amazon SNS phone numbers and subscriptions
Managing SMS subscriptions

Amazon SNS provides several options for managing who receives SMS messages from your account. With a limited frequency, you can opt in phone numbers that have opted out of receiving SMS messages from your account. To stop sending messages to SMS subscriptions, you can remove subscriptions or the topics that publish to them.

## Opting out of receiving SMS messages


Where required by local laws and regulations (such as the US and Canada), SMS recipients can use their devices to opt-out by replying to the message with any of the following: 
+ ARRET (French)
+ CANCEL
+ END
+ OPT-OUT
+ OPTOUT
+ QUIT
+ REMOVE
+ STOP
+ TD
+ UNSUBSCRIBE

To opt-out, the recipient must reply to the same [origination number](https://docs.aws.amazon.com/sms-voice/latest/userguide/phone-numbers.html) that Amazon SNS used to deliver the message. After opting-out, the recipient will no longer receive SMS messages delivered from your AWS account unless you opt-in the phone number.

If the phone number is subscribed to an Amazon SNS topic, opting-out does not remove the subscription, but SMS messages will fail to deliver to that subscription unless you opt-in the phone number.

## Managing phone numbers and subscriptions using the Amazon SNS console


You can use the Amazon SNS console to control which phone numbers receive SMS messages from your account.

### Opting-in a phone number that has been opted-out the Amazon SNS console


You can view which phone numbers have been opted-out of receiving SMS messages from your account, and you can opt-in these phone numbers to resume sending messages to them.

You can opt-in a phone number only once every 30 days.

1. Sign in to the [Amazon SNS console](https://console.aws.amazon.com/sns/home).

1. In the console menu, set the region selector to a [region that supports SMS messaging](https://docs.aws.amazon.com/general/latest/gr/end-user-messaging.html).

1. On the navigation panel, choose **Text messaging (SMS)**.

1. On the **Mobile text messaging (SMS)** page, in the **Opted-out phone numbers** section, opted-out phone numbers are displayed.

1. Select the check box for the phone number that you want to opt-in, and choose **Opt in**. The phone number is no longer opted-out and will receive SMS messages that you send to it.

#### Deleting an SMS subscription the Amazon SNS console


Delete an SMS subscription to stop sending SMS messages to that phone number when you publish to your topics.

1. On the navigation panel, choose **Subscriptions**.

1. Select the check boxes for the subscriptions that you want to delete. Then choose **Actions**, and choose **Delete Subscriptions**.

1. In the **Delete** window, choose **Delete**. Amazon SNS deletes the subscription and displays a success message.

#### Deleting a topic the Amazon SNS console


Delete a topic when you no longer want to publish messages to its subscribed endpoints.

1. On the navigation panel, choose **Topics**.

1. Select the check boxes for the topics that you want to delete. Then choose **Actions**, and choose **Delete Topics**.

1. In the **Delete** window, choose **Delete**. Amazon SNS deletes the topic and displays a success message.

### Managing phone numbers and subscriptions using the AWS SDK


You can use the AWS SDKs to make programmatic requests to Amazon SNS and manage which phone numbers can receive SMS messages from your account.

To use an AWS SDK, you must configure it with your credentials. For more information, see [Shared config and credentials files](https://docs.aws.amazon.com/sdkref/latest/guide/file-format.html) in the *AWS SDKs and Tools Reference Guide*.

#### Viewing all opted-out phone numbers using the AWS SDK


To view all opted-out phone numbers, submit a `ListPhoneNumbersOptedOut` request with the Amazon SNS API.

The following code examples show how to use `ListPhoneNumbersOptedOut`.

------
#### [ CLI ]

**AWS CLI**  
**To list SMS message opt-outs**  
The following `list-phone-numbers-opted-out` example lists the phone numbers opted out of receiving SMS messages.  

```
aws sns list-phone-numbers-opted-out
```
Output:  

```
{
    "phoneNumbers": [
        "+15555550100"
    ]
}
```
+  For API details, see [ListPhoneNumbersOptedOut](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/sns/list-phone-numbers-opted-out.html) in *AWS CLI Command Reference*. 

------
#### [ Java ]

**SDK for Java 2.x**  
 There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/javav2/example_code/sns#code-examples). 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.sns.SnsClient;
import software.amazon.awssdk.services.sns.model.ListPhoneNumbersOptedOutRequest;
import software.amazon.awssdk.services.sns.model.ListPhoneNumbersOptedOutResponse;
import software.amazon.awssdk.services.sns.model.SnsException;

/**
 * Before running this Java V2 code example, set up your development
 * environment, including your credentials.
 *
 * For more information, see the following documentation topic:
 *
 * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
 */
public class ListOptOut {
    public static void main(String[] args) {
        SnsClient snsClient = SnsClient.builder()
                .region(Region.US_EAST_1)
                .build();

        listOpts(snsClient);
        snsClient.close();
    }

    public static void listOpts(SnsClient snsClient) {
        try {
            ListPhoneNumbersOptedOutRequest request = ListPhoneNumbersOptedOutRequest.builder().build();
            ListPhoneNumbersOptedOutResponse result = snsClient.listPhoneNumbersOptedOut(request);
            System.out.println("Status is " + result.sdkHttpResponse().statusCode() + "\n\nPhone Numbers: \n\n"
                    + result.phoneNumbers());

        } catch (SnsException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
    }
}
```
+  For API details, see [ListPhoneNumbersOptedOut](https://docs.aws.amazon.com/goto/SdkForJavaV2/sns-2010-03-31/ListPhoneNumbersOptedOut) in *AWS SDK for Java 2.x API Reference*. 

------
#### [ PHP ]

**SDK for PHP**  
 There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/php/example_code/sns#code-examples). 

```
require 'vendor/autoload.php';

use Aws\Exception\AwsException;
use Aws\Sns\SnsClient;


/**
 * Returns a list of phone numbers that are opted out of receiving SMS messages from your AWS SNS account.
 *
 * This code expects that you have AWS credentials set up per:
 * https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/guide_credentials.html
 */

$SnSclient = new SnsClient([
    'profile' => 'default',
    'region' => 'us-east-1',
    'version' => '2010-03-31'
]);

try {
    $result = $SnSclient->listPhoneNumbersOptedOut();
    var_dump($result);
} catch (AwsException $e) {
    // output error message if fails
    error_log($e->getMessage());
}
```
+  For more information, see [AWS SDK for PHP Developer Guide](https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/sns-examples-sending-sms.html#list-opted-out-phone-numbers). 
+  For API details, see [ListPhoneNumbersOptedOut](https://docs.aws.amazon.com/goto/SdkForPHPV3/sns-2010-03-31/ListPhoneNumbersOptedOut) in *AWS SDK for PHP API Reference*. 

------

#### Checking whether a phone number is opted-out using the AWS SDK


To check whether a phone number is opted-out, submit a `CheckIfPhoneNumberIsOptedOut` request with the Amazon SNS API.

The following code examples show how to use `CheckIfPhoneNumberIsOptedOut`.

------
#### [ .NET ]

**SDK for .NET**  
 There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/dotnetv3/SNS#code-examples). 

```
    using System;
    using System.Threading.Tasks;
    using Amazon.SimpleNotificationService;
    using Amazon.SimpleNotificationService.Model;

    /// <summary>
    /// This example shows how to use the Amazon Simple Notification Service
    /// (Amazon SNS) to check whether a phone number has been opted out.
    /// </summary>
    public class IsPhoneNumOptedOut
    {
        public static async Task Main()
        {
            string phoneNumber = "+15551112222";

            IAmazonSimpleNotificationService client = new AmazonSimpleNotificationServiceClient();

            await CheckIfOptedOutAsync(client, phoneNumber);
        }

        /// <summary>
        /// Checks to see if the supplied phone number has been opted out.
        /// </summary>
        /// <param name="client">The initialized Amazon SNS Client object used
        /// to check if the phone number has been opted out.</param>
        /// <param name="phoneNumber">A string representing the phone number
        /// to check.</param>
        public static async Task CheckIfOptedOutAsync(IAmazonSimpleNotificationService client, string phoneNumber)
        {
            var request = new CheckIfPhoneNumberIsOptedOutRequest
            {
                PhoneNumber = phoneNumber,
            };

            try
            {
                var response = await client.CheckIfPhoneNumberIsOptedOutAsync(request);

                if (response.HttpStatusCode == System.Net.HttpStatusCode.OK)
                {
                    string optOutStatus = response.IsOptedOut ? "opted out" : "not opted out.";
                    Console.WriteLine($"The phone number: {phoneNumber} is {optOutStatus}");
                }
            }
            catch (AuthorizationErrorException ex)
            {
                Console.WriteLine($"{ex.Message}");
            }
        }
    }
```
+  For API details, see [CheckIfPhoneNumberIsOptedOut](https://docs.aws.amazon.com/goto/DotNetSDKV3/sns-2010-03-31/CheckIfPhoneNumberIsOptedOut) in *AWS SDK for .NET API Reference*. 

------
#### [ CLI ]

**AWS CLI**  
**To check SMS message opt-out for a phone number**  
The following `check-if-phone-number-is-opted-out` example checks whether the specified phone number is opted out of receiving SMS messages from the current AWS account.  

```
aws sns check-if-phone-number-is-opted-out \
    --phone-number +1555550100
```
Output:  

```
{
    "isOptedOut": false
}
```
+  For API details, see [CheckIfPhoneNumberIsOptedOut](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/sns/check-if-phone-number-is-opted-out.html) in *AWS CLI Command Reference*. 

------
#### [ Java ]

**SDK for Java 2.x**  
 There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/javav2/example_code/sns#code-examples). 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.sns.SnsClient;
import software.amazon.awssdk.services.sns.model.CheckIfPhoneNumberIsOptedOutRequest;
import software.amazon.awssdk.services.sns.model.CheckIfPhoneNumberIsOptedOutResponse;
import software.amazon.awssdk.services.sns.model.SnsException;

/**
 * Before running this Java V2 code example, set up your development
 * environment, including your credentials.
 *
 * For more information, see the following documentation topic:
 *
 * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
 */
public class CheckOptOut {
    public static void main(String[] args) {

        final String usage = """

                Usage:    <phoneNumber>

                Where:
                   phoneNumber - The mobile phone number to look up (for example, +1XXX5550100).

                """;

        if (args.length != 1) {
            System.out.println(usage);
            System.exit(1);
        }

        String phoneNumber = args[0];
        SnsClient snsClient = SnsClient.builder()
                .region(Region.US_EAST_1)
                .build();

        checkPhone(snsClient, phoneNumber);
        snsClient.close();
    }

    public static void checkPhone(SnsClient snsClient, String phoneNumber) {
        try {
            CheckIfPhoneNumberIsOptedOutRequest request = CheckIfPhoneNumberIsOptedOutRequest.builder()
                    .phoneNumber(phoneNumber)
                    .build();

            CheckIfPhoneNumberIsOptedOutResponse result = snsClient.checkIfPhoneNumberIsOptedOut(request);
            System.out.println(
                    result.isOptedOut() + "Phone Number " + phoneNumber + " has Opted Out of receiving sns messages." +
                            "\n\nStatus was " + result.sdkHttpResponse().statusCode());

        } catch (SnsException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
    }
}
```
+  For API details, see [CheckIfPhoneNumberIsOptedOut](https://docs.aws.amazon.com/goto/SdkForJavaV2/sns-2010-03-31/CheckIfPhoneNumberIsOptedOut) in *AWS SDK for Java 2.x API Reference*. 

------
#### [ JavaScript ]

**SDK for JavaScript (v3)**  
 There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/javascriptv3/example_code/sns#code-examples). 
Create the client in a separate module and export it.  

```
import { SNSClient } from "@aws-sdk/client-sns";

// The AWS Region can be provided here using the `region` property. If you leave it blank
// the SDK will default to the region set in your AWS config.
export const snsClient = new SNSClient({});
```
Import the SDK and client modules and call the API.  

```
import { CheckIfPhoneNumberIsOptedOutCommand } from "@aws-sdk/client-sns";

import { snsClient } from "../libs/snsClient.js";

export const checkIfPhoneNumberIsOptedOut = async (
  phoneNumber = "5555555555",
) => {
  const command = new CheckIfPhoneNumberIsOptedOutCommand({
    phoneNumber,
  });

  const response = await snsClient.send(command);
  console.log(response);
  // {
  //   '$metadata': {
  //     httpStatusCode: 200,
  //     requestId: '3341c28a-cdc8-5b39-a3ee-9fb0ee125732',
  //     extendedRequestId: undefined,
  //     cfId: undefined,
  //     attempts: 1,
  //     totalRetryDelay: 0
  //   },
  //   isOptedOut: false
  // }
  return response;
};
```
+  For more information, see [AWS SDK for JavaScript Developer Guide](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/sns-examples-sending-sms.html#sending-sms-checkifphonenumberisoptedout). 
+  For API details, see [CheckIfPhoneNumberIsOptedOut](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/sns/command/CheckIfPhoneNumberIsOptedOutCommand) in *AWS SDK for JavaScript API Reference*. 

------
#### [ PHP ]

**SDK for PHP**  
 There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/php/example_code/sns#code-examples). 

```
require 'vendor/autoload.php';

use Aws\Exception\AwsException;
use Aws\Sns\SnsClient;


/**
 * Indicates whether the phone number owner has opted out of receiving SMS messages from your AWS SNS account.
 *
 * This code expects that you have AWS credentials set up per:
 * https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/guide_credentials.html
 */

$SnSclient = new SnsClient([
    'profile' => 'default',
    'region' => 'us-east-1',
    'version' => '2010-03-31'
]);

$phone = '+1XXX5550100';

try {
    $result = $SnSclient->checkIfPhoneNumberIsOptedOut([
        'phoneNumber' => $phone,
    ]);
    var_dump($result);
} catch (AwsException $e) {
    // output error message if fails
    error_log($e->getMessage());
}
```
+  For more information, see [AWS SDK for PHP Developer Guide](https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/sns-examples-sending-sms.html#check-if-a-phone-number-has-opted-out). 
+  For API details, see [CheckIfPhoneNumberIsOptedOut](https://docs.aws.amazon.com/goto/SdkForPHPV3/sns-2010-03-31/CheckIfPhoneNumberIsOptedOut) in *AWS SDK for PHP API Reference*. 

------

#### Opting-in a phone number that has been opted-out using the Amazon SNS API


To opt-in a phone number, submit an `OptInPhoneNumber` request with the Amazon SNS API.

You can opt-in a phone number only once every 30 days.

#### Deleting an SMS subscription using the AWS SDK


To delete an SMS subscription from an Amazon SNS topic, get the subscription ARN by submitting a `ListSubscriptions` request with the Amazon SNS API, and then pass the ARN to an `Unsubscribe` request.

The following code examples show how to use `Unsubscribe`.

------
#### [ .NET ]

**SDK for .NET**  
 There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/dotnetv3/cross-service/TopicsAndQueues#code-examples). 
Unsubscribe from a topic by a subscription ARN.  

```
    /// <summary>
    /// Unsubscribe from a topic by a subscription ARN.
    /// </summary>
    /// <param name="subscriptionArn">The ARN of the subscription.</param>
    /// <returns>True if successful.</returns>
    public async Task<bool> UnsubscribeByArn(string subscriptionArn)
    {
        var unsubscribeResponse = await _amazonSNSClient.UnsubscribeAsync(
            new UnsubscribeRequest()
            {
                SubscriptionArn = subscriptionArn
            });
        return unsubscribeResponse.HttpStatusCode == HttpStatusCode.OK;
    }
```
+  For API details, see [Unsubscribe](https://docs.aws.amazon.com/goto/DotNetSDKV3/sns-2010-03-31/Unsubscribe) in *AWS SDK for .NET API Reference*. 

------
#### [ C\$1\$1 ]

**SDK for C\$1\$1**  
 There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/sns#code-examples). 

```
//! Delete a subscription to an Amazon Simple Notification Service (Amazon SNS) topic.
/*!
  \param subscriptionARN: The Amazon Resource Name (ARN) for an Amazon SNS topic subscription.
  \param clientConfiguration: AWS client configuration.
  \return bool: Function succeeded.
 */
bool AwsDoc::SNS::unsubscribe(const Aws::String &subscriptionARN,
                              const Aws::Client::ClientConfiguration &clientConfiguration) {
    Aws::SNS::SNSClient snsClient(clientConfiguration);

    Aws::SNS::Model::UnsubscribeRequest request;
    request.SetSubscriptionArn(subscriptionARN);

    const Aws::SNS::Model::UnsubscribeOutcome outcome = snsClient.Unsubscribe(request);

    if (outcome.IsSuccess()) {
        std::cout << "Unsubscribed successfully " << std::endl;
    }
    else {
        std::cerr << "Error while unsubscribing " << outcome.GetError().GetMessage()
                  << std::endl;
    }

    return outcome.IsSuccess();
}
```
+  For API details, see [Unsubscribe](https://docs.aws.amazon.com/goto/SdkForCpp/sns-2010-03-31/Unsubscribe) in *AWS SDK for C\$1\$1 API Reference*. 

------
#### [ CLI ]

**AWS CLI**  
**To unsubscribe from a topic**  
The following `unsubscribe` example deletes the specified subscription from a topic.  

```
aws sns unsubscribe \
    --subscription-arn arn:aws:sns:us-west-2:0123456789012:my-topic:8a21d249-4329-4871-acc6-7be709c6ea7f
```
This command produces no output.  
+  For API details, see [Unsubscribe](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/sns/unsubscribe.html) in *AWS CLI Command Reference*. 

------
#### [ Java ]

**SDK for Java 2.x**  
 There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/javav2/example_code/sns#code-examples). 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.sns.SnsClient;
import software.amazon.awssdk.services.sns.model.SnsException;
import software.amazon.awssdk.services.sns.model.UnsubscribeRequest;
import software.amazon.awssdk.services.sns.model.UnsubscribeResponse;

/**
 * Before running this Java V2 code example, set up your development
 * environment, including your credentials.
 *
 * For more information, see the following documentation topic:
 *
 * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
 */
public class Unsubscribe {
    public static void main(String[] args) {
        final String usage = """

                Usage:    <subscriptionArn>

                Where:
                   subscriptionArn - The ARN of the subscription to delete.
                """;

        if (args.length < 1) {
            System.out.println(usage);
            System.exit(1);
        }

        String subscriptionArn = args[0];
        SnsClient snsClient = SnsClient.builder()
                .region(Region.US_EAST_1)
                .build();

        unSub(snsClient, subscriptionArn);
        snsClient.close();
    }

    public static void unSub(SnsClient snsClient, String subscriptionArn) {
        try {
            UnsubscribeRequest request = UnsubscribeRequest.builder()
                    .subscriptionArn(subscriptionArn)
                    .build();

            UnsubscribeResponse result = snsClient.unsubscribe(request);
            System.out.println("\n\nStatus was " + result.sdkHttpResponse().statusCode()
                    + "\n\nSubscription was removed for " + request.subscriptionArn());

        } catch (SnsException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
    }
}
```
+  For API details, see [Unsubscribe](https://docs.aws.amazon.com/goto/SdkForJavaV2/sns-2010-03-31/Unsubscribe) in *AWS SDK for Java 2.x API Reference*. 

------
#### [ JavaScript ]

**SDK for JavaScript (v3)**  
 There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/javascriptv3/example_code/sns#code-examples). 
Create the client in a separate module and export it.  

```
import { SNSClient } from "@aws-sdk/client-sns";

// The AWS Region can be provided here using the `region` property. If you leave it blank
// the SDK will default to the region set in your AWS config.
export const snsClient = new SNSClient({});
```
Import the SDK and client modules and call the API.  

```
import { UnsubscribeCommand } from "@aws-sdk/client-sns";
import { snsClient } from "../libs/snsClient.js";

/**
 * @param {string} subscriptionArn - The ARN of the subscription to cancel.
 */
const unsubscribe = async (
  subscriptionArn = "arn:aws:sns:us-east-1:xxxxxxxxxxxx:mytopic:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
) => {
  const response = await snsClient.send(
    new UnsubscribeCommand({
      SubscriptionArn: subscriptionArn,
    }),
  );
  console.log(response);
  // {
  //   '$metadata': {
  //     httpStatusCode: 200,
  //     requestId: '0178259a-9204-507c-b620-78a7570a44c6',
  //     extendedRequestId: undefined,
  //     cfId: undefined,
  //     attempts: 1,
  //     totalRetryDelay: 0
  //   }
  // }
  return response;
};
```
+  For more information, see [AWS SDK for JavaScript Developer Guide](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/sns-examples-managing-topics.html#sns-examples-unsubscribing). 
+  For API details, see [Unsubscribe](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/sns/command/UnsubscribeCommand) in *AWS SDK for JavaScript API Reference*. 

------
#### [ Kotlin ]

**SDK for Kotlin**  
 There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/kotlin/services/sns#code-examples). 

```
suspend fun unSub(subscriptionArnVal: String) {
    val request =
        UnsubscribeRequest {
            subscriptionArn = subscriptionArnVal
        }

    SnsClient.fromEnvironment { region = "us-east-1" }.use { snsClient ->
        snsClient.unsubscribe(request)
        println("Subscription was removed for ${request.subscriptionArn}")
    }
}
```
+  For API details, see [Unsubscribe](https://sdk.amazonaws.com/kotlin/api/latest/index.html) in *AWS SDK for Kotlin API reference*. 

------
#### [ PHP ]

**SDK for PHP**  
 There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/php/example_code/sns#code-examples). 

```
require 'vendor/autoload.php';

use Aws\Exception\AwsException;
use Aws\Sns\SnsClient;


/**
 * Deletes a subscription to an Amazon SNS topic.
 *
 * This code expects that you have AWS credentials set up per:
 * https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/guide_credentials.html
 */

$SnSclient = new SnsClient([
    'profile' => 'default',
    'region' => 'us-east-1',
    'version' => '2010-03-31'
]);

$subscription = 'arn:aws:sns:us-east-1:111122223333:MySubscription';

try {
    $result = $SnSclient->unsubscribe([
        'SubscriptionArn' => $subscription,
    ]);
    var_dump($result);
} catch (AwsException $e) {
    // output error message if fails
    error_log($e->getMessage());
}
```
+  For more information, see [AWS SDK for PHP Developer Guide](https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/sns-examples-subscribing-unsubscribing-topics.html#unsubscribe-from-a-topic). 
+  For API details, see [Unsubscribe](https://docs.aws.amazon.com/goto/SdkForPHPV3/sns-2010-03-31/Unsubscribe) in *AWS SDK for PHP API Reference*. 

------
#### [ Python ]

**SDK for Python (Boto3)**  
 There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/python/example_code/sns#code-examples). 

```
class SnsWrapper:
    """Encapsulates Amazon SNS topic and subscription functions."""

    def __init__(self, sns_resource):
        """
        :param sns_resource: A Boto3 Amazon SNS resource.
        """
        self.sns_resource = sns_resource


    @staticmethod
    def delete_subscription(subscription):
        """
        Unsubscribes and deletes a subscription.
        """
        try:
            subscription.delete()
            logger.info("Deleted subscription %s.", subscription.arn)
        except ClientError:
            logger.exception("Couldn't delete subscription %s.", subscription.arn)
            raise
```

```
class SnsWrapper:
    """Wrapper class for managing Amazon SNS operations."""

    def __init__(self, sns_client: Any) -> None:
        """
        Initialize the SnsWrapper.

        :param sns_client: A Boto3 Amazon SNS client.
        """
        self.sns_client = sns_client

    @classmethod
    def from_client(cls) -> 'SnsWrapper':
        """
        Create an SnsWrapper instance using a default boto3 client.

        :return: An instance of this class.
        """
        sns_client = boto3.client('sns')
        return cls(sns_client)


    def unsubscribe(self, subscription_arn: str) -> bool:
        """
        Unsubscribe from an SNS topic.

        :param subscription_arn: The ARN of the subscription to remove.
        :return: True if successful.
        :raises ClientError: If the unsubscribe operation fails.
        """
        try:
            self.sns_client.unsubscribe(SubscriptionArn=subscription_arn)
            
            logger.info(f"Unsubscribed: {subscription_arn}")
            return True

        except ClientError as e:
            error_code = e.response.get('Error', {}).get('Code', 'Unknown')
            
            if error_code == 'NotFound':
                logger.warning(f"Subscription not found: {subscription_arn}")
                return True  # Already unsubscribed
            else:
                logger.error(f"Error unsubscribing: {error_code} - {e}")
                raise
```
+  For API details, see [Unsubscribe](https://docs.aws.amazon.com/goto/boto3/sns-2010-03-31/Unsubscribe) in *AWS SDK for Python (Boto3) API Reference*. 

------
#### [ SAP ABAP ]

**SDK for SAP ABAP**  
 There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/sap-abap/services/sns#code-examples). 

```
    TRY.
        lo_sns->unsubscribe( iv_subscriptionarn = iv_subscription_arn ).
        MESSAGE 'Subscription deleted.' TYPE 'I'.
      CATCH /aws1/cx_snsnotfoundexception.
        MESSAGE 'Subscription does not exist.' TYPE 'E'.
      CATCH /aws1/cx_snsinvalidparameterex.
        MESSAGE 'Subscription with "PendingConfirmation" status cannot be deleted/unsubscribed. Confirm subscription before performing unsubscribe operation.' TYPE 'E'.
    ENDTRY.
```
+  For API details, see [Unsubscribe](https://docs.aws.amazon.com/sdk-for-sap-abap/v1/api/latest/index.html) in *AWS SDK for SAP ABAP API reference*. 

------
#### [ Swift ]

**SDK for Swift**  
 There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/swift/example_code/sns#code-examples). 

```
import AWSSNS

        let config = try await SNSClient.SNSClientConfiguration(region: region)
        let snsClient = SNSClient(config: config)

        _ = try await snsClient.unsubscribe(
            input: UnsubscribeInput(
                subscriptionArn: arn
            )
        )

        print("Unsubscribed.")
```
+  For API details, see [Unsubscribe](https://sdk.amazonaws.com/swift/api/awssns/latest/documentation/awssns/snsclient/unsubscribe(input:)) in *AWS SDK for Swift API reference*. 

------

#### Deleting a topic using the AWS SDK


To delete a topic and all of its subscriptions, get the topic ARN by submitting a `ListTopics` request with the Amazon SNS API, and then pass the ARN to the `DeleteTopic` request.

The following code examples show how to use `DeleteTopic`.

------
#### [ .NET ]

**SDK for .NET**  
 There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/dotnetv3/cross-service/TopicsAndQueues#code-examples). 
Delete a topic by its topic ARN.  

```
    /// <summary>
    /// Delete a topic by its topic ARN.
    /// </summary>
    /// <param name="topicArn">The ARN of the topic.</param>
    /// <returns>True if successful.</returns>
    public async Task<bool> DeleteTopicByArn(string topicArn)
    {
        var deleteResponse = await _amazonSNSClient.DeleteTopicAsync(
            new DeleteTopicRequest()
            {
                TopicArn = topicArn
            });
        return deleteResponse.HttpStatusCode == HttpStatusCode.OK;
    }
```
+  For API details, see [DeleteTopic](https://docs.aws.amazon.com/goto/DotNetSDKV3/sns-2010-03-31/DeleteTopic) in *AWS SDK for .NET API Reference*. 

------
#### [ C\$1\$1 ]

**SDK for C\$1\$1**  
 There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/sns#code-examples). 

```
//! Delete an Amazon Simple Notification Service (Amazon SNS) topic.
/*!
  \param topicARN: The Amazon Resource Name (ARN) for an Amazon SNS topic.
  \param clientConfiguration: AWS client configuration.
  \return bool: Function succeeded.
 */
bool AwsDoc::SNS::deleteTopic(const Aws::String &topicARN,
                              const Aws::Client::ClientConfiguration &clientConfiguration) {
    Aws::SNS::SNSClient snsClient(clientConfiguration);

    Aws::SNS::Model::DeleteTopicRequest request;
    request.SetTopicArn(topicARN);

    const Aws::SNS::Model::DeleteTopicOutcome outcome = snsClient.DeleteTopic(request);

    if (outcome.IsSuccess()) {
        std::cout << "Successfully deleted the Amazon SNS topic " << topicARN << std::endl;
    }
    else {
        std::cerr << "Error deleting topic " << topicARN << ":" <<
                  outcome.GetError().GetMessage() << std::endl;
    }

    return outcome.IsSuccess();
}
```
+  For API details, see [DeleteTopic](https://docs.aws.amazon.com/goto/SdkForCpp/sns-2010-03-31/DeleteTopic) in *AWS SDK for C\$1\$1 API Reference*. 

------
#### [ CLI ]

**AWS CLI**  
**To delete an SNS topic**  
The following `delete-topic` example deletes the specified SNS topic.  

```
aws sns delete-topic \
    --topic-arn "arn:aws:sns:us-west-2:123456789012:my-topic"
```
This command produces no output.  
+  For API details, see [DeleteTopic](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/sns/delete-topic.html) in *AWS CLI Command Reference*. 

------
#### [ Go ]

**SDK for Go V2**  
 There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/gov2/workflows/topics_and_queues#code-examples). 

```
import (
	"context"
	"encoding/json"
	"log"

	"github.com/aws/aws-sdk-go-v2/aws"
	"github.com/aws/aws-sdk-go-v2/service/sns"
	"github.com/aws/aws-sdk-go-v2/service/sns/types"
)

// SnsActions encapsulates the Amazon Simple Notification Service (Amazon SNS) actions
// used in the examples.
type SnsActions struct {
	SnsClient *sns.Client
}



// DeleteTopic delete an Amazon SNS topic.
func (actor SnsActions) DeleteTopic(ctx context.Context, topicArn string) error {
	_, err := actor.SnsClient.DeleteTopic(ctx, &sns.DeleteTopicInput{
		TopicArn: aws.String(topicArn)})
	if err != nil {
		log.Printf("Couldn't delete topic %v. Here's why: %v\n", topicArn, err)
	}
	return err
}
```
+  For API details, see [DeleteTopic](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/service/sns#Client.DeleteTopic) in *AWS SDK for Go API Reference*. 

------
#### [ Java ]

**SDK for Java 2.x**  
 There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/javav2/example_code/sns#code-examples). 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.sns.SnsClient;
import software.amazon.awssdk.services.sns.model.DeleteTopicRequest;
import software.amazon.awssdk.services.sns.model.DeleteTopicResponse;
import software.amazon.awssdk.services.sns.model.SnsException;

/**
 * Before running this Java V2 code example, set up your development
 * environment, including your credentials.
 *
 * For more information, see the following documentation topic:
 *
 * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
 */
public class DeleteTopic {
    public static void main(String[] args) {
        final String usage = """

                Usage:     <topicArn>

                Where:
                   topicArn - The ARN of the topic to delete.
                """;

        if (args.length != 1) {
            System.out.println(usage);
            System.exit(1);
        }

        String topicArn = args[0];
        SnsClient snsClient = SnsClient.builder()
                .region(Region.US_EAST_1)
                .build();

        System.out.println("Deleting a topic with name: " + topicArn);
        deleteSNSTopic(snsClient, topicArn);
        snsClient.close();
    }

    public static void deleteSNSTopic(SnsClient snsClient, String topicArn) {
        try {
            DeleteTopicRequest request = DeleteTopicRequest.builder()
                    .topicArn(topicArn)
                    .build();

            DeleteTopicResponse result = snsClient.deleteTopic(request);
            System.out.println("\n\nStatus was " + result.sdkHttpResponse().statusCode());

        } catch (SnsException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
    }
}
```
+  For API details, see [DeleteTopic](https://docs.aws.amazon.com/goto/SdkForJavaV2/sns-2010-03-31/DeleteTopic) in *AWS SDK for Java 2.x API Reference*. 

------
#### [ JavaScript ]

**SDK for JavaScript (v3)**  
 There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/javascriptv3/example_code/sns#code-examples). 
Create the client in a separate module and export it.  

```
import { SNSClient } from "@aws-sdk/client-sns";

// The AWS Region can be provided here using the `region` property. If you leave it blank
// the SDK will default to the region set in your AWS config.
export const snsClient = new SNSClient({});
```
Import the SDK and client modules and call the API.  

```
import { DeleteTopicCommand } from "@aws-sdk/client-sns";
import { snsClient } from "../libs/snsClient.js";

/**
 * @param {string} topicArn - The ARN of the topic to delete.
 */
export const deleteTopic = async (topicArn = "TOPIC_ARN") => {
  const response = await snsClient.send(
    new DeleteTopicCommand({ TopicArn: topicArn }),
  );
  console.log(response);
  // {
  //   '$metadata': {
  //     httpStatusCode: 200,
  //     requestId: 'a10e2886-5a8f-5114-af36-75bd39498332',
  //     extendedRequestId: undefined,
  //     cfId: undefined,
  //     attempts: 1,
  //     totalRetryDelay: 0
  //   }
  // }
};
```
+  For more information, see [AWS SDK for JavaScript Developer Guide](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/sns-examples-managing-topics.html#sns-examples-managing-topics-deletetopic). 
+  For API details, see [DeleteTopic](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/sns/command/DeleteTopicCommand) in *AWS SDK for JavaScript API Reference*. 

------
#### [ Kotlin ]

**SDK for Kotlin**  
 There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/kotlin/services/sns#code-examples). 

```
suspend fun deleteSNSTopic(topicArnVal: String) {
    val request =
        DeleteTopicRequest {
            topicArn = topicArnVal
        }

    SnsClient.fromEnvironment { region = "us-east-1" }.use { snsClient ->
        snsClient.deleteTopic(request)
        println("$topicArnVal was successfully deleted.")
    }
}
```
+  For API details, see [DeleteTopic](https://sdk.amazonaws.com/kotlin/api/latest/index.html) in *AWS SDK for Kotlin API reference*. 

------
#### [ PHP ]

**SDK for PHP**  
 There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/php/example_code/sns#code-examples). 

```
require 'vendor/autoload.php';

use Aws\Exception\AwsException;
use Aws\Sns\SnsClient;


/**
 * Deletes an SNS topic and all its subscriptions.
 *
 * This code expects that you have AWS credentials set up per:
 * https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/guide_credentials.html
 */

$SnSclient = new SnsClient([
    'profile' => 'default',
    'region' => 'us-east-1',
    'version' => '2010-03-31'
]);

$topic = 'arn:aws:sns:us-east-1:111122223333:MyTopic';

try {
    $result = $SnSclient->deleteTopic([
        'TopicArn' => $topic,
    ]);
    var_dump($result);
} catch (AwsException $e) {
    // output error message if fails
    error_log($e->getMessage());
}
```
+  For API details, see [DeleteTopic](https://docs.aws.amazon.com/goto/SdkForPHPV3/sns-2010-03-31/DeleteTopic) in *AWS SDK for PHP API Reference*. 

------
#### [ Python ]

**SDK for Python (Boto3)**  
 There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/python/example_code/sns#code-examples). 

```
class SnsWrapper:
    """Encapsulates Amazon SNS topic and subscription functions."""

    def __init__(self, sns_resource):
        """
        :param sns_resource: A Boto3 Amazon SNS resource.
        """
        self.sns_resource = sns_resource


    @staticmethod
    def delete_topic(topic):
        """
        Deletes a topic. All subscriptions to the topic are also deleted.
        """
        try:
            topic.delete()
            logger.info("Deleted topic %s.", topic.arn)
        except ClientError:
            logger.exception("Couldn't delete topic %s.", topic.arn)
            raise
```

```
class SnsWrapper:
    """Wrapper class for managing Amazon SNS operations."""

    def __init__(self, sns_client: Any) -> None:
        """
        Initialize the SnsWrapper.

        :param sns_client: A Boto3 Amazon SNS client.
        """
        self.sns_client = sns_client

    @classmethod
    def from_client(cls) -> 'SnsWrapper':
        """
        Create an SnsWrapper instance using a default boto3 client.

        :return: An instance of this class.
        """
        sns_client = boto3.client('sns')
        return cls(sns_client)


    def delete_topic(self, topic_arn: str) -> bool:
        """
        Delete an SNS topic.

        :param topic_arn: The ARN of the topic to delete.
        :return: True if successful.
        :raises ClientError: If the topic deletion fails.
        """
        try:
            self.sns_client.delete_topic(TopicArn=topic_arn)
            
            logger.info(f"Deleted topic: {topic_arn}")
            return True

        except ClientError as e:
            error_code = e.response.get('Error', {}).get('Code', 'Unknown')
            
            if error_code == 'NotFound':
                logger.warning(f"Topic not found: {topic_arn}")
                return True  # Already deleted
            else:
                logger.error(f"Error deleting topic: {error_code} - {e}")
                raise
```
+  For API details, see [DeleteTopic](https://docs.aws.amazon.com/goto/boto3/sns-2010-03-31/DeleteTopic) in *AWS SDK for Python (Boto3) API Reference*. 

------
#### [ SAP ABAP ]

**SDK for SAP ABAP**  
 There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/sap-abap/services/sns#code-examples). 

```
    TRY.
        lo_sns->deletetopic( iv_topicarn = iv_topic_arn ).
        MESSAGE 'SNS topic deleted.' TYPE 'I'.
      CATCH /aws1/cx_snsnotfoundexception.
        MESSAGE 'Topic does not exist.' TYPE 'E'.
    ENDTRY.
```
+  For API details, see [DeleteTopic](https://docs.aws.amazon.com/sdk-for-sap-abap/v1/api/latest/index.html) in *AWS SDK for SAP ABAP API reference*. 

------
#### [ Swift ]

**SDK for Swift**  
 There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/swift/example_code/sns#code-examples). 

```
import AWSSNS

        let config = try await SNSClient.SNSClientConfiguration(region: region)
        let snsClient = SNSClient(config: config)

        _ = try await snsClient.deleteTopic(
            input: DeleteTopicInput(topicArn: arn)
        )
```
+  For API details, see [DeleteTopic](https://sdk.amazonaws.com/swift/api/awssns/latest/documentation/awssns/snsclient/deletetopic(input:)) in *AWS SDK for Swift API reference*. 

------

# Amazon SNS SMS activity monitoring
Monitoring SMS activity

By monitoring your SMS activity, you can keep track of destination phone numbers, successful or failed deliveries, reasons for failure, costs, and other information. Amazon SNS helps by summarizing statistics in the console, sending information to Amazon CloudWatch, and sending daily SMS usage reports to an Amazon S3 bucket that you specify.

# Viewing Amazon SNS SMS delivery statistics
Viewing delivery statistics

You can use the Amazon SNS console to view statistics about your recent SMS deliveries.

1. Sign in to the [Amazon SNS console](https://console.aws.amazon.com/sns/home).

1. In the console menu, set the region selector to a [region that supports SMS messaging](https://docs.aws.amazon.com/sms-voice/latest/userguide/phone-numbers-sms-by-country.html).

1. On the navigation panel, choose **Text messaging (SMS)**.

1. On the **Text messaging (SMS)** page, in the **Account stats** section, view the charts for your transactional and promotional SMS message deliveries. Each chart shows the following data for the preceding 15 days:
   + Delivery rate (percentage of successful deliveries)
   + Sent (number of delivery attempts)
   + Failed (number of delivery failures)

On this page, you can also choose the **Usage** button to go to the Amazon S3 bucket where you store your daily usage reports. For more information, see [Subscribing to Amazon SNS daily SMS usage reports](sms_stats_usage.md).

# Amazon SNS SMS delivery monitoring with Amazon CloudWatch metrics and logs
Viewing CloudWatch metrics and logs

You can use Amazon CloudWatch and Amazon CloudWatch Logs to monitor your SMS message deliveries.

## Viewing Amazon CloudWatch metrics


Amazon SNS automatically collects metrics about your SMS message deliveries and pushes them to Amazon CloudWatch. You can use CloudWatch to monitor these metrics and create alarms to alert you when a metric crosses a threshold. For example, you can monitor CloudWatch metrics to learn your SMS delivery rate and your month-to-date SMS charges.

For information about monitoring CloudWatch metrics, setting CloudWatch alarms, and the types of metrics available, see [Monitoring Amazon SNS topics using CloudWatch](sns-monitoring-using-cloudwatch.md).

## Viewing CloudWatch Logs


You can collect information about successful and unsuccessful SMS message deliveries by enabling Amazon SNS to write to Amazon CloudWatch Logs. For each SMS message that you send, Amazon SNS writes a log that includes the message price, the success or failure status, the reason for failure (if the message failed), the message dwell time, and other information.

**To enable and view CloudWatch Logs for your SMS messages**

1. Sign in to the [Amazon SNS console](https://console.aws.amazon.com/sns/home).

1. In the console menu, set the region selector to a [region that supports SMS messaging](https://docs.aws.amazon.com/general/latest/gr/end-user-messaging.html).

1. On the navigation panel, choose **Text messaging (SMS)**.

1. On the **Mobile text messaging (SMS)** page, in the **Text messaging preferences** section, choose **Edit**.

1. On the next page, expand the **Delivery status logging** section.

1. For **Success sample rate**, specify the percentage of successful SMS deliveries for which Amazon SNS will write logs in CloudWatch Logs. For example:
   + To write logs only for failed deliveries, set this value to 0.
   + To write logs for 10% of your successful deliveries, set it to 10.

   If you don't specify a percentage, Amazon SNS writes logs for all successful deliveries.

1. To provide the required permissions, do one of the following:
   + To create a new service role, choose **Create new service role** and then **Create new roles**. On the next page, choose **Allow** to give Amazon SNS write access to your account's resources.
   + To use an existing service role, choose **Use existing service role** and then paste the ARN name in the **IAM role for successful and failed deliveries** box.

     The service role you specify must allow write access to your account's resources. For more information on creating IAM roles, see [Creating a role for an AWS service](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_create_for-service.html#roles-creatingrole-service-console) in the *IAM User Guide*. 

1. Choose **Save changes**.

1. Back on the **Mobile text messaging (SMS)** page, go to the **Delivery status logs** section to view any available logs.
**Note**  
Depending on the destination phone number's carrier, it can take up to 72 hours for delivery logs to appear in the Amazon SNS console. 

## Example log for successful SMS delivery


The delivery status log for a successful SMS delivery will resemble the following example:

```
{
    "notification": {
        "messageId": "34d9b400-c6dd-5444-820d-fbeb0f1f54cf",
        "timestamp": "2016-06-28 00:40:34.558"
    },
    "delivery": {
        "phoneCarrier": "My Phone Carrier",
        "mnc": 270,
        "numberOfMessageParts": 1,
        "destination": "+1XXX5550100",
        "priceInUSD": 0.00645,
        "smsType": "Transactional",
        "mcc": 310,
        "providerResponse": "Message has been accepted by phone carrier",
        "dwellTimeMs": 599,
        "dwellTimeMsUntilDeviceAck": 1344
    },
    "status": "SUCCESS"
}
```

## Example log for failed SMS delivery


The delivery status log for a failed SMS delivery will resemble the following example:

```
{
    "notification": {
        "messageId": "1077257a-92f3-5ca3-bc97-6a915b310625",
        "timestamp": "2016-06-28 00:40:34.559"
    },
    "delivery": {
        "mnc": 0,
        "numberOfMessageParts": 1,
        "destination": "+1XXX5550100",
        "priceInUSD": 0.00645,
        "smsType": "Transactional",
        "mcc": 0,
        "providerResponse": "Unknown error attempting to reach phone",
        "dwellTimeMs": 1420,
        "dwellTimeMsUntilDeviceAck": 1692
    },
    "status": "FAILURE"
}
```

## SMS delivery failure reasons


The reason for a failure is provided with the `providerResponse` attribute. SMS messages might fail to deliver for the following reasons:
+ Blocked as spam by phone carrier
+ Destination is on a blocked list
+ Invalid phone number
+ Message body is invalid
+ Phone carrier has blocked this message
+ Phone carrier is currently unreachable/unavailable
+ Phone has blocked SMS
+ Phone is on a blocked list
+ Phone is currently unreachable/unavailable
+ Phone number is opted out
+ This delivery would exceed max price
+ Unknown error attempting to reach phone

# Subscribing to Amazon SNS daily SMS usage reports
Subscribing to daily SMS usage reports

You can monitor your SMS deliveries by subscribing to daily usage reports from Amazon SNS. For each day that you send at least one SMS message, Amazon SNS delivers a usage report as a CSV file to the specified Amazon S3 bucket. It takes 24 hours for the SMS usage report to be available in the Amazon S3 bucket. 

## Daily usage report information


The usage report includes the following information for each SMS message that you send from your account.

 Note that the report does not include messages that are sent to recipients who have opted out.
+ Time of publication for message (in UTC)
+ Message ID
+ Destination phone number
+ Message type
+ Delivery status
+ Message price (in USD)
+ Part number (a message is split into multiple parts if it is too long for a single message)
+ Total number of parts

**Note**  
If Amazon SNS did not receive the part number, we set its value to zero.

## Subscribing to daily usage reports


To subscribe to daily usage reports, you must create an Amazon S3 bucket with the appropriate permissions.

**To create an Amazon S3 bucket for your daily usage reports**

1. From the AWS account that sends SMS messages, sign in to the [Amazon S3 console](https://console.aws.amazon.com/s3/).

1. Choose **Create Bucket**.

1. For **Bucket Name**, we recommend that you enter a name that is unique for your account and your organization. For example, use the pattern `<my-bucket-prefix>-<account_id>-<org-id>`. 

   For information about conventions and restrictions for bucket names, see [Rules for Bucket Naming](https://docs.aws.amazon.com/AmazonS3/latest/userguide/BucketRestrictions.html#bucketnamingrules) in the *Amazon Simple Storage Service User Guide*.

1. Choose **Create**.

1. In the **All Buckets** table, choose the bucket.

1. In the **Permissions** tab, choose **Bucket policy**.

1. In the **Bucket Policy Editor** window, provide a policy that allows the Amazon SNS service principal to write to your bucket. For an example, see [Example bucket policy](#example_bucket_policy).

   If you use the example policy, remember to replace *my-s3-bucket* with the bucket name that you chose in Step 3.

1. Choose **Save**.

**To subscribe to daily usage reports**

1. Sign in to the [Amazon SNS console](https://console.aws.amazon.com/sns/).

1. On the navigation panel, choose **Text messaging (SMS)**.

1. On the **Text messaging (SMS)** page, in the **Text messaging preferences** section, choose **Edit**.  
![\[Text messaging preferences section in the Amazon SNS console\]](http://docs.aws.amazon.com/sns/latest/dg/images/daily-usage-report1.png)

1. On the **Edit text messaging preferences** page, in the **Details** section, specify the **Amazon S3 bucket name for usage reports**.  
![\[Details section of the Edit text messaging preferences page in the Amazon SNS console\]](http://docs.aws.amazon.com/sns/latest/dg/images/daily-usage-report2.png)

1. Choose **Save changes**.

### Example bucket policy


The following policy allows the Amazon SNS service principal to perform the `s3:PutObject`, `s3:GetBucketLocation`, and `s3:ListBucket` actions.

AWS provides tools for all services with service principals that have been given access to resources in your account. When the principal in an Amazon S3 bucket policy statement is an [confused deputy problem](https://docs.aws.amazon.com/IAM/latest/UserGuide/confused-deputy.html). To limit which region and account from which the bucket can receive daily usage reports, use `aws:SourceArn` as shown in the example below. If you do not wish to limit which regions can generate these reports, use `aws:SourceAccount` to limit based on which account is generating the reports. If you don't know the ARN of the resource, use `aws:SourceAccount`.

Use the following example that includes confused deputy protection when you create an Amazon S3 bucket to receive daily SMS usage reports from Amazon SNS.

------
#### [ JSON ]

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Sid": "AllowPutObject",
            "Effect": "Allow",
            "Principal": {
                "Service": "sns.amazonaws.com"
            },
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::amzn-s3-demo-bucket/*",
            "Condition": {
                "StringEquals": {
                    "aws:SourceAccount": "account_id"
                },
                "ArnLike": {
                    "aws:SourceArn": "arn:aws:sns:us-west-1:123456789012:*"
                }
            }
        },
        {
            "Sid": "AllowGetBucketLocation",
            "Effect": "Allow",
            "Principal": {
                "Service": "sns.amazonaws.com"
            },
            "Action": "s3:GetBucketLocation",
            "Resource": "arn:aws:s3:::amzn-s3-demo-bucket",
            "Condition": {
                "StringEquals": {
                    "aws:SourceAccount": "account_id"
                },
                "ArnLike": {
                    "aws:SourceArn": "arn:aws:sns:us-west-1:123456789012:*"
                }
            }
        },
        {
            "Sid": "AllowListBucket",
            "Effect": "Allow",
            "Principal": {
                "Service": "sns.amazonaws.com"
            },
            "Action": "s3:ListBucket",
            "Resource": "arn:aws:s3:::amzn-s3-demo-bucket",
            "Condition": {
                "StringEquals": {
                    "aws:SourceAccount": "account_id"
                },
                "ArnLike": {
                    "aws:SourceArn": "arn:aws:sns:us-west-1:123456789012:*"
                }
            }
        }
    ]
}
```

------

**Note**  
You can publish usage reports to Amazon S3 buckets that are owned by the AWS account that's specified in the `Condition` element in the Amazon S3 policy. To publish usage reports to an Amazon S3 bucket that another AWS account owns, see [How can I copy Amazon S3 objects from another AWS account?](https://aws.amazon.com/premiumsupport/knowledge-center/copy-s3-objects-account/). 

### Example daily usage report


After you subscribe to daily usage reports, each day, Amazon SNS puts a CSV file with usage data in the following location:

```
<my-s3-bucket>/SMSUsageReports/<region>/YYYY/MM/DD/00x.csv.gz
```

Each file can contain up to 50,000 records. If the records for a day exceed this quota, Amazon SNS will add multiple files. The following shows an example report:

```
PublishTimeUTC,MessageId,DestinationPhoneNumber,MessageType,DeliveryStatus,PriceInUSD,PartNumber,TotalParts
2016-05-10T03:00:29.476Z,96a298ac-1458-4825-a7eb-7330e0720b72,1XXX5550100,Promotional,Message has been accepted by phone carrier,0.90084,0,1
2016-05-10T03:00:29.561Z,1e29d394-d7f4-4dc9-996e-26412032c344,1XXX5550100,Promotional,Message has been accepted by phone carrier,0.34322,0,1
2016-05-10T03:00:30.769Z,98ba941c-afc7-4c51-ba2c-56c6570a6c08,1XXX5550100,Transactional,Message has been accepted by phone carrier,0.27815,0,1
```

# Requesting support for Amazon SNS SMS messaging
Requesting SMS support

**Important**  
The Amazon SNS SMS Developer Guide has been updated. Amazon SNS has integrated with [AWS End User Messaging SMS](https://docs.aws.amazon.com/sms-voice/latest/userguide/what-is-service.html) for the delivery of SMS messages. This guide contains the latest information on how to create, configure, and manage your Amazon SNS SMS messages.

Certain SMS options with Amazon SNS aren't available for your AWS account until you contact Support. Create a case in the [AWS Support Center](https://console.aws.amazon.com/support/home#/) to request any of the following:
+ An increase to your monthly SMS spending threshold

  By default, the monthly spending threshold is \$11.00 (USD). Your spending threshold determines the volume of messages that you can send with Amazon SNS. You can request a spending threshold that meets the expected monthly message volume for your SMS use case.
+ A move from the [SMS sandbox](sns-sms-sandbox.md) so that you can send SMS messages without restrictions. For more information, see [Moving out of the Amazon SNS SMS sandbox](sns-sms-sandbox-moving-to-production.md).
+ A dedicated [origination number](https://docs.aws.amazon.com/sms-voice/latest/userguide/phone-numbers.html)
+ A dedicated [sender ID](https://docs.aws.amazon.com/sms-voice/latest/userguide/sender-id.html). A sender ID is a custom ID that is shown as the sender on the recipient's device. For example, you can use your business brand to make the message source easier to recognize. Support for sender IDs varies by country or region. For more information, see [Supported countries and regions for SMS messaging with AWS End User Messaging SMS](https://docs.aws.amazon.com/sms-voice/latest/userguide/phone-numbers-sms-by-country.html) in the *AWS End User Messaging SMS User Guide*.

# Requesting increases to your monthly Amazon SNS SMS spending quota
Requesting spending quota increases

Amazon SNS provides spending quotas to help you manage the maximum per-month cost incurred by sending SMS using your account. The spending quota limits your risk in case of malicious attack, and prevents your upstream application from sending more messages than expected. You can configure Amazon SNS to stop publishing SMS messages when it determines that sending an SMS message will incur a cost that exceeds your spending quota for the current month. 

To ensure your operations are not impacted, we recommend requesting a spending quota high enough to support your production workloads. For more information, see [Step 1: Open an Amazon SNS SMS case](#channels-sms-awssupport-spend-threshold-open). Once you have received the quota, you can manage your risk by applying the full quota, or a smaller value, as described in [Step 2: Update your SMS settings](#channels-sms-awssupport-spend-threshold-settings). By applying a smaller value, you can control your monthly spending with the option to scale up if necessary.

**Important**  
Because Amazon SNS is a distributed system, it stops sending SMS messages within minutes if the spending quota is exceeded. During this period, if you continue to send SMS messages, you might incur costs that exceed your quota.

We set the spending quota for all new accounts at \$11.00 (USD) per month. This quota is intended to let you test the message-sending capabilities of Amazon SNS. To request an increase to the SMS spending quota for your account, open a quota increase case in the AWS Support Center.

**Topics**
+ [

## Step 1: Open an Amazon SNS SMS case
](#channels-sms-awssupport-spend-threshold-open)
+ [

## Step 2: Update your SMS settings on the Amazon SNS console
](#channels-sms-awssupport-spend-threshold-settings)

## Step 1: Open an Amazon SNS SMS case
Step 1: Open an SMS case

You can request an increase to your monthly spending quota by opening a quota increase case in the AWS Support Center.

**Note**  
Some of the fields on the request form are marked as "optional." However, Support requires all of the information that's mentioned in the following steps in order to process your request. If you don't provide all of the required information, you may experience delays in processing your request.

1. Sign in to the AWS Management Console at [https://console.aws.amazon.com/](https://console.aws.amazon.com/).

1. On the **Support** menu, choose **Support Center**.

1. On the **Your support cases** pane, choose **Create case**.

1. Choose the **Looking for service limit increases?** link, then complete the following:
   + For **Limit type**, choose **SNS Text Messaging**.
   + (Optional) For **Provide a link to the site or app which will be sending SMS messages**, provide information about the website, application, or service that will send SMS messages.
   + (Optional) For **What type of messages do you plan to send**, choose the type of message that you plan to send using your long code:
     + **One Time Password** – Messages that provide passwords that your customers use to authenticate with your website or application.
     + **Promotional** – Noncritical messages that promote your business or service, such as special offers or announcements.
     + **Transactional** – Important informational messages that support customer transactions, such as order confirmations or account alerts. Transactional messages must not contain promotional or marketing content.
   + (Optional) For **Which AWS Region will you be sending messages from**, choose the region that you'll be sending messages from.
   + (Optional) For **Which countries do you plan to send messages to**, enter the country or region that you want to purchase short codes in.
   + (Optional) In the **How do your customers opt to receive messages from you**, provide details about your opt-in process.
   + (Optional) In the **Please provide the message template that you plan to use to send messages to your customers** field, include the template that you will be using.

1. Under **Requests**, complete the following sections:
   + For the **Region**, choose the Region from which you'll be sending messages. 
**Note**  
The Region is required in the **Requests** section. Even if you provided this information in the **Case details** section you must also include it here.
   + For **Resource Type**, choose** General Limits**.
   + For **Limit**, choose **Account Spend Threshold Increase**.

1. For New limit value, enter the maximum amount (in USD) that you can spend on SMS each calendar month.

1. Under **Case description**, for **Use case description**, provide the following details:
   + The website or app of the company or service that's sending SMS messages.
   + The service that's provided by your website or app, and how your SMS messages contribute to that service.
   + How users sign up to voluntarily receive your SMS messages on your website, app, or other location.

   If your requested spending quota (the value you specified for **New quota value**) exceeds \$110,000 (USD), provide the following additional details for each country that you're messaging:
   + Whether you're using a sender ID or short code. If you're using a sender ID, provide:
     + The sender ID.
     + Whether the sender ID is registered with wireless carriers in the country.
   + The maximum expected transactions-per-second (TPS) for your messaging.
   + The average message size.
   + The template for the messages that you send to the country.
   + (Optional) Character encoding needs, if any.

1. (Optional) If you want to submit any further requests, choose **Add another request**. If you include multiple requests, provide the required information for each. For the required information, see the other sections within [Requesting support for Amazon SNS SMS messaging](channels-sms-awssupport.md).

1. Under **Contact options**, for **Preferred contact language**, choose the language in which you want to receive communications for this case.

1. When you finish, choose **Submit**.

The Support team provides an initial response to your request within 24 hours.

To prevent our systems from being used to send unsolicited or malicious content, we consider each request carefully. If we can, we will grant your request within this 24-hour period. However, if we need additional information from you, it might take longer to resolve your request.

If your use case doesn't align with our policies, we might be unable to grant your request.

## Step 2: Update your SMS settings on the Amazon SNS console
Step 2: Update your SMS settings

After we notify you that your monthly spending quota has been increased, you have to adjust the spending quota for your account on the Amazon SNS console.

**Important**  
You must complete the following steps or your SMS spend limit will not be increased.

**To adjust your spending quota on the console**

1. Sign in to the [Amazon SNS console](https://console.aws.amazon.com/sns/home).

1. Open the left navigation menu, expand **Mobile**, and then choose **Text messaging (SMS)**.

1. On the **Mobile text messaging (SMS)** page, in the **Text messaging preferences** section, choose **Edit**.

1. On the **Edit text messaging preferences** page, in the **Details** section, enter your new SMS spend limit in the **Account spend limit** field.
**Note**  
You might receive a warning that the entered value is larger than the default spend limit. You can ignore this. 

1. Choose **Save** changes.
**Note**  
If you get an "Invalid Parameter" error, check the contact from AWS Support and confirm that you entered the correct new SMS spend limit. If you still experience a problem, open a case in the AWS Support Center. 

When you create your case in the Support Center, be sure to include all the required information for the type of request that you're submitting. Otherwise, Support must contact you to obtain this information before proceeding. By submitting a detailed case, you help ensure that your case is fulfilled without delays. For the required details for specific types of SMS requests, see the following topics.

 For more information on sender IDs, see the following documentation in the *AWS End User Messaging SMS User Guide*:


| AWS End User Messaging SMS Topic | Description | 
| --- | --- | 
|  [Requesting a spending quota increase](https://docs.aws.amazon.com/sms-voice/latest/userguide/awssupport-spend-threshold.html)  |  Your spending quota determines how much money you can spend sending SMS messages through AWS End User Messaging SMS each month.  | 
|  [Open a case in support center for a sender ID](https://docs.aws.amazon.com/sms-voice/latest/userguide/awssupport-sender-id.html)  |  If you plan to send messages to recipients a country where sender IDs are required, you can request a sender ID by creating a new case in the Support Center.  | 

# Best practices for Amazon SNS SMS messaging
Best practices for SMS messaging

**Important**  
The Amazon SNS SMS Developer Guide has been updated. Amazon SNS has integrated with [AWS End User Messaging SMS](https://docs.aws.amazon.com/sms-voice/latest/userguide/what-is-service.html) for the delivery of SMS messages. This guide contains the latest information on how to create, configure, and manage your Amazon SNS SMS messages.

Mobile phone users tend to have a very low tolerance for unsolicited SMS messages. Response rates for unsolicited SMS campaigns will almost always be low, and therefore the return on your investment will be poor.

Additionally, mobile phone carriers continuously audit bulk SMS senders. They throttle or block messages from numbers that they determine to be sending unsolicited messages. 

Sending unsolicited content is also a violation of the [AWS acceptable use policy](https://aws.amazon.com/aup/#No_E-Mail_or_Other_Message_Abuse). The Amazon SNS team routinely audits SMS campaigns, and might throttle or block your ability to send messages if it appears that you're sending unsolicited messages.

Finally, in many countries, regions, and jurisdictions, there are severe penalties for sending unsolicited SMS messages. For example, in the United States, the Telephone Consumer Protection Act (TCPA) states that consumers are entitled to \$1500–\$11,500 in damages (paid by the sender) for each unsolicited message that they receive.

This section describes several best practices that might help you improve your customer engagement and avoid costly penalties. However, note that this section doesn't contain legal advice. Always consult an attorney to obtain legal advice.

## Comply with laws, regulations, and carrier requirements


You can face significant fines and penalties if you violate the laws and regulations of the places where your customers reside. For this reason, it's vital to understand the laws related to SMS messaging in each country or region where you do business.

The following list includes links to key laws that apply to SMS communications in major markets around the world.
+ **United States**: The Telephone Consumer Protection Act of 1991, also known as TCPA, applies to certain types of SMS messages. For more information, see the [rules and regulations](https://www.fcc.gov/document/telephone-consumer-protection-act-1991) at the Federal Communications Commission website.
+ **United Kingdom**: The Privacy and Electronic Communications (EC Directive) Regulations 2003, also known as PECR, applies to certain types of SMS messages. For more information, see [What are PECR?](https://ico.org.uk/for-organisations/direct-marketing-and-privacy-and-electronic-communications/guide-to-pecr/what-are-pecr/) at the website of the UK Information Commissioner's Office.
+ **European Union**: The Privacy and Electronic Communications Directive 2002, sometimes known as the ePrivacy Directive, applies to some types of SMS messages. For more information, see the [full text of the law](http://eur-lex.europa.eu/legal-content/EN/TXT/?uri=CELEX:32002L0058) at the Europa.eu website.
+ **Canada**: The Fighting Internet and Wireless Spam Act, more commonly known as Canada's Anti-Spam Law or CASL, applies to certain types of SMS messages. For more information, see the [full text of the law](http://www.parl.ca/DocumentViewer/en/40-3/bill/C-28/first-reading) at the website of the Parliament of Canada.
+ **Japan**: The Act on Regulation of Transmission of Specific Electronic Mail may apply to certain types of SMS messages. For more information, see [Japan's countermeasures against spam](https://www.japaneselawtranslation.go.jp/en/laws/view/3767/en) at the website of the Japanese Ministry of Internal Affairs and Communications.

As a sender, these laws may apply to you even if your company or organization isn't based in one of these countries. Some of the laws in this list were originally created to address unsolicited email or telephone calls, but have been interpreted or expanded to apply to SMS messages as well. Other countries and regions may have their own laws related to the transmission of SMS messages. Consult an attorney in each country or region where your customers are located to obtain legal advice.

In many countries, the local carriers ultimately have the authority to determine what kind of traffic flows over their networks. This means that the carriers might impose restrictions on SMS content that exceed the minimum requirements of local laws.

## Obtain permission


Never send messages to recipients who haven't explicitly asked to receive the specific types of messages that you plan to send. Don't share opt-in lists, even among organizations within the same company. 

If recipients can sign up to receive your messages by using an online form, add systems that prevent automated scripts from subscribing people without their knowledge. You should also limit the number of times a user can submit a phone number in a single session.

When you receive an SMS opt-in request, send the recipient a message that asks them to confirm that they want to receive messages from you. Don't send that recipient any additional messages until they confirm their subscription. A subscription confirmation message might resemble the following example:

`Text YES to join ExampleCorp alerts. 2 msgs/month. Msg & data rates may apply. Reply HELP for help, STOP to cancel.`

Maintain records that include the date, time, and source of each opt-in request and confirmation. This might be useful if a carrier or regulatory agency requests it, and can also help you perform routine audits of your customer list.

### Opt-in workflow


In some cases (like US Toll-Free or Short Code registration) mobile carriers require you to provide mockups or screen shot of your entire opt-in workflow. The mockups or screen shot must closely resemble the opt-in workflow that your recipients will complete. 

Your mockups or screen shot should include all of the required disclosures listed below to maintain the highest level of compliance. 

**Required disclosures**
+ A description of the messaging use case that you will send through your program.
+ The phrase “Message and data rates may apply.”
+ An indication of how often recipients will get messages from you. For example, a recurring messaging program might say “one message per week.” A one-time password or multi-factor authentication use case might say “message frequency varies” or “one message per login attempt.”
+ Links to your Terms and Conditions and Privacy Policy documents. 

**Common rejection reasons for non compliant opt-ins**
+ If the provided company name does not match what is provided in the mockup or screen shot. Any non obvious relations should be explained in the opt-in workflow description.
+ If it appears that a message will be sent to the recipient, but no consent is explicitly gathered before doing so. Explicit consent is a requirement of all messaging.
+ If it appears that receiving a text message is required to sign up for a service. This is not compliant if the workflow doesn’t provide any alternative to receiving an opt-in message in another form like email or a voice call. 
+ If the opt-in language is presented entirely in the Terms of Service. The disclosures should always be presented to the recipient at time of opt-in rather than housed inside a linked policy document. 
+ If a customer provided consent to receive one type of message from you and you send them other types of text messages. For example they consent to receive one-time passwords but are also sent polling and survey messages.
+ If the required disclosures (listed above) are not presented to the recipients.

The following example complies with the mobile carriers’ requirements for a multi-factor authentication use case.

![\[A step-by-step mockup of the opt-in workflow for enabling multi-factor authentication (MFA) on a user account with ExampleCorp. The process begins with the user providing basic account information such as name and email. Next, the user decides whether to enable MFA for added security. If MFA is enabled, the user selects how they want to receive the MFA token, with options like text message or phone call. If the user selects text message, they receive an SMS with a verification code. The final step requires the user to enter the received code to confirmm their phone number, completing the opt-in process. This mockup ensures all necessary disclosures are provided for SMS compliance.\]](http://docs.aws.amazon.com/sns/latest/dg/images/best-practices-usecase.png)


It contains finalized text and images, and it shows the entire opt-in flow, complete with annotations. In the opt-in flow, the customer has to take distinct, intentional actions to provide their consent to receive text messages and contains all of the required disclosures.

### Other opt-in workflow types


Mobile carriers will also accept opt-in workflows outside of applications and websites like verbal or written opt-in if it complies with what is outlined above. A compliant opt-in workflow and verbal or written script will gather explicit consent from the recipient to receive a specific message type. Examples of this include the verbal script a support agent uses to gather consent before recording into a service database or a phone number listed on a promotional flyer. To provide a mockup of these opt-in workflow types you can provide a screen shot of your opt-in script, marketing material or database where numbers are collected. Mobile carriers may have additional questions around these use cases if an opt-in is not clear or the use case exceed certain volumes.

## Don't send to old lists


People change phone numbers often. A phone number that you gathered consent to contact two years ago might belong to somebody else today. Don't use an old list of phone numbers for a new messaging program; if you do, you're likely to have some messages fail because the number is no longer in service, and some people who opt out because they don't remember giving you their consent in the first place.

## Audit your customer lists


If you send recurring SMS campaigns, audit your customer lists on a regular basis. Auditing your customer lists ensures that the only customers who receive your messages are those who are interested in receiving them. 

When you audit your list, send each opted-in customer a message that reminds them that they're subscribed, and provides them with information about unsubscribing. A reminder message might resemble the following example:

`You're subscribed to ExampleCorp alerts. Msg & data rates may apply. Reply HELP for help, STOP to unsubscribe.`

## Keep records


Keep records that show when each customer requested to receive SMS messages from you, and which messages you sent to each customer. Many countries and regions around the world require SMS senders to maintain these records in a way that can be easily retrieved. Mobile carriers might also request this information from you at any time. The exact information that you have to provide varies by country or region. For more information about record-keeping requirements, review the regulations about commercial SMS messaging in each country or region where your customers are located.

Occasionally, a carrier or regulatory agency asks us to provide proof that a customer opted to receive messages from you. In these situations, Support contacts you with a list of the information that the carrier or agency requires. If you can't provide the necessary information, we may pause your ability to send additional SMS messages.

## Make your messages clear, honest, and concise


SMS is a unique medium. The 160-character-per-message limit means that your messages have to be concise. Techniques that you might use in other communication channels, such as email, might not apply to the SMS channel, and might even seem dishonest or deceptive when used with SMS messages. If the content in your messages doesn't align with best practices, recipients might ignore your messages; in the worst case, the mobile carriers might identify your messages as spam and block future messages from your phone number.

This section provides some tips and ideas for creating an effective SMS message body.

### Identify yourself as the sender


Your recipients should be able to immediately tell that a message is from you. Senders who follow this best practice include an identifying name ("program name") at the beginning of each message.

**Don't do this:**  
`Your account has been accessed from a new device. Reply Y to confirm.`

**Try this instead:**  
`ExampleCorp Financial Alerts: You have logged in to your account from a new device. Reply Y to confirm, or STOP to opt-out.`

### Don't try to make your message look like a person-to-person message


Some marketers are tempted to add a personal touch to their SMS messages by making their messages appear to come from an individual. However, this technique might make your message seem like a phishing attempt.

**Don't do this:**  
`Hi, this is Jane. Did you know that you can save up to 50% at Example.com? Click here for more info: https://www.example.com.`

**Try this instead:**  
`ExampleCorp Offers: Save 25-50% on sale items at Example.com. Click here to browse the sale: https://www.example.com. Text STOP to opt-out.`

### Be careful when talking about money


Scammers often prey upon people's desire to save and receive money. Don't make offers seem too good to be true. Don't use the lure of money to deceive people. Don't use currency symbols to indicate money.

**Don't do this:**  
`Save big $$$ on your next car repair by going to https://www.example.com.`

**Try this instead:**  
`ExampleCorp Offers: Your ExampleCorp insurance policy gets you discounts at 2300+ repair shops nationwide. More info at https://www.example.com. Text STOP to opt-out.`

### Use only the necessary characters


Brands are often inclined to protect their trademarks by including trademark symbols such as ™ or ® in their messages. However, these symbols are not part of the standard set of characters (known as the GSM alphabet) that can be included in a 160-character SMS message. When you send a message that contains one of these characters, your message is automatically sent using a different character encoding system, which only supports 70 characters per message part. As a result, your message could be broken into several parts. Because you're billed for each message part that you send, it could cost you more than you expect to spend to send the entire message. Additionally, your recipients might receive several sequential messages from you, rather than one single message. For more information about SMS character encoding, see [SMS character limits in Amazon SNS](#channels-sms-limitations-characters).

**Don't do this:**  
`ExampleCorp Alerts: Save 20% when you buy a new ExampleCorp Widget® at example.com and use the promo code WIDGET.`

**Try this instead:**  
`ExampleCorp Alerts: Save 20% when you buy a new ExampleCorp Widget(R) at example.com and use the promo code WIDGET.`

**Note**  
The two preceding examples are almost identical, but the first example contains a Registered Trademark symbol (®), which is not part of the GSM alphabet. As a result, the first example is sent as two message parts, while the second example is sent as one message part.

### Use valid, safe links


If your message includes links, double-check the links to make sure that they work. Test your links on a device outside your corporate network to ensure that links resolve properly. Because of the 160-character limit of SMS messages, very long URLs could be split across multiple messages. You should use redirect domains to provide shortened URLs. However, you shouldn't use free link-shortening services such as tinyurl.com or bitly.com, because carriers tend to filter messages that include links on these domains. However, you can use paid link-shortening services as long as your links point to a domain that is dedicated to the exclusive use of your company or organization. 

**Don't do this:**  
`Go to https://tinyurl.com/4585y8mr today for a special offer!`

**Try this instead:**  
`ExampleCorp Offers: Today only, get an exclusive deal on an ExampleCorp Widget. See https://a.co/cFKmaRG for more info. Text STOP to opt-out.`

### Limit the number of abbreviations that you use


The 160-character limitation of the SMS channel leads some senders to believe that they need to use abbreviations extensively in their messages. However, the overuse of abbreviations can seem unprofessional to many readers, and could cause some users to report your message as spam. It's completely possible to write a coherent message without using an excessive number of abbreviations.

**Don't do this:**  
`Get a gr8 deal on ExampleCorp widgets when u buy a 4-pack 2day.`

**Try this instead:**  
`ExampleCorp Alerts: Today only—an exclusive deal on ExampleCorp Widgets at example.com. Text STOP to opt-out.`

## Respond appropriately


When a recipient replies to your messages, make sure that you respond with useful information. For example, when a customer responds to one of your messages with the keyword "HELP", send them information about the program that they're subscribed to, the number of messages you'll send each month, and the ways that they can contact you for more information. A HELP response might resemble the following example:

`HELP: ExampleCorp alerts: email help@example.com or call 425-555-0199. 2 msgs/month. Msg & data rates may apply. Reply STOP to cancel.`

When a customer replies with the keyword "STOP", let them know that they won't receive any further messages. A STOP response might resemble the following example:

`You're unsubscribed from ExampleCorp alerts. No more messages will be sent. Reply HELP, email help@example.com, or call 425-555-0199 for more info.`

## Adjust your sending based on engagement


Your customers' priorities can change over time. If customers no longer find your messages to be useful, they might opt out of your messages entirely, or even report your messages as unsolicited. For these reasons, it's important that you adjust your sending practices based on customer engagement.

For customers who rarely engage with your messages, you should adjust the frequency of your messages. For example, if you send weekly messages to engaged customers, you could create a separate monthly digest for customers who are less engaged. 

Finally, remove customers who are completely unengaged from your customer lists. This step prevents customers from becoming frustrated with your messages. It also saves you money and helps protect your reputation as a sender.

## Send at appropriate times


Only send messages during normal daytime business hours. If you send messages at dinner time or in the middle of the night, there's a good chance that your customers will unsubscribe from your lists in order to avoid being disturbed. Furthermore, it doesn't make sense to send SMS messages when your customers can't respond to them immediately. 

If you send campaigns or journeys to very large audiences, double-check the throughput rates for your origination numbers. Divide the number of recipients by your throughput rate to determine how long it will take to send messages to all of your recipients.

## Avoid cross-channel fatigue


In your campaigns, if you use multiple communication channels (such as email, SMS, and push messages), don't send the same message in every channel. When you send the same message at the same time in more than one channel, your customers will probably perceive your sending behavior to be annoying rather than helpful.

## Use dedicated short codes


If you use short codes, maintain a separate short code for each brand and each type of message. For example, if your company has two brands, use a separate short code for each one. Similarly, if you send both transactional and promotional messages, use a separate short code for each type of message. To learn more about requesting short codes, see [Requesting short codes for SMS messaging with AWS End User Messaging SMS](https://docs.aws.amazon.com/sms-voice/latest/userguide/phone-numbers-request-short-code.html) in the *AWS End User Messaging SMS User Guide*.

## Verify your destination phone numbers


When you send SMS messages through Amazon SNS, you're billed for each message part you send. The price you pay per message part varies on the recipient's country or region. For more information about SMS pricing, see [AWS Worldwide SMS Pricing](https://aws.amazon.com/sns/sms-pricing).

When Amazon SNS accepts a request to send an SMS message (as the result of a call to the [SendMessages](https://docs.aws.amazon.com/pinpoint/latest/apireference/apps-application-id-messages.html#SendMessages) API, or as the result of a campaign or journey being launched), you're charged for sending that message. This statement is true even if the intended recipient doesn't actually receive the message. For example, if the recipient's phone number is no longer in service, or if the number that you sent the message to wasn't a valid mobile phone number, you're still billed for sending the message.

Amazon SNS accepts valid requests to send SMS messages and attempts to deliver them. For this reason, you should validate that the phone numbers that you send messages to are valid mobile numbers. You can use AWS End User Messaging SMS to send a test message to determine if a phone number is valid and what type of number it is (such as mobile, landline, or VoIP). For more information, see [Send a test message with the SMS simulator](https://docs.aws.amazon.com/sms-voice/latest/userguide/getting-started-tutorial.html#getting-started-tutorial-step3) in the *AWS End User Messaging SMS User Guide*.

## Design with redundancy in mind


For mission-critical messaging programs, we recommend that you configure Amazon SNS in more than one AWS Region. Amazon SNS is available in several AWS Regions. For a complete list of Regions where Amazon SNS is available, see the [AWS General Reference](https://docs.aws.amazon.com/general/latest/gr/sns.html). 

The phone numbers that you use for SMS messages—including short codes, long codes, toll-free numbers, and 10DLC numbers—can't be replicated across AWS Regions. As a result, in order to use Amazon SNS in multiple Regions, you must request separate phone numbers in each Region where you want to use Amazon SNS. For example, if you use a short code to send text messages to recipients in the United States, you need to request separate short codes in each AWS Region that you plan to use.

In some countries, you can also use multiple types of phone numbers for added redundancy. For example, in the United States, you can request short codes, 10DLC numbers, and toll-free numbers. Each of these phone number types takes a different route to the recipient. Having multiple phone number types available—either in the same AWS Region or spread across multiple AWS Regions—provides an additional layer of redundancy, which can help improve resiliency.

## SMS limits and restrictions


For SMS limits and restrictions, see [SMS and MMS limits and restrictions](https://docs.aws.amazon.com/sms-voice/latest/userguide/sms-limitations.html) in the *AWS End User Messaging SMS User Guide*.

## Managing opt out keywords


SMS recipients can use their devices to opt out of messages by replying with a keyword. For more information, see [Opting out of receiving SMS messages](sms_manage.md#sms_manage_optout).

## CreatePool


Use the `CreatePool` API action to create a new pool and associate a specified origination identity to the pool. For more information, see [CreatePool](https://docs.aws.amazon.com/pinpoint/latest/apireference_smsvoicev2/API_CreatePool.html) in *AWS End User Messaging SMS API Reference*.

## PutKeyword


Use the `PutKeyword` API action to create or update a keyword configuration on an origination phone number or pool. For more information, see [PutKeyword](https://docs.aws.amazon.com/pinpoint/latest/apireference_smsvoicev2/API_PutKeyword.html) in *AWS End User Messaging SMS API Reference*.

## Managing number settings


To manage settings for the dedicated short codes and long codes that you requested from AWS Support and assigned to your account, see [Change a phone number's capabilities with the AWS CLI](https://docs.aws.amazon.com/sms-voice/latest/userguide/phone-numbers-change-capabilitiy.html) in *AWS End User Messaging SMS*.

## SMS character limits in Amazon SNS
SMS character limits

A single SMS message can contain up to 140 bytes of information. The number of characters you can include in a single SMS message depends on the type of characters the message contains.

If your message only uses [characters in the GSM 03.38 character set](#channels-sms-limitations-characters-gsm-alphabet), also known as the GSM 7-bit alphabet, it can contain up to 160 characters. If your message contains any characters that are outside the GSM 03.38 character set, it can have up to 70 characters. When you send an SMS message, Amazon SNS automatically determines the most efficient encoding to use.

When a message contains more than the maximum number of characters, the message is split into multiple parts. When messages are split into multiple parts, each part contains additional information about the message part that precedes it. When the recipient's device receives message parts that are separated in this way, it uses this additional information to ensure that all of the message parts are displayed in the correct order. Depending on the recipient's mobile carrier and device, multiple messages might be displayed as a single message, or as a sequence of separate messages. As a result the number of characters in each message part is reduced to 153 (for messages that only contain GSM 03.38 characters) or 67 (for messages that contain other characters). You can estimate how many message parts your message contains before you send it by using SMS length calculator tools, several of which are available online. The maximum supported size of any message is 1600 GSM characters or 630 non-GSM characters. For more information about throughput and message size, see [SMS character limits in Amazon Pinpoint](https://docs.aws.amazon.com/pinpoint/latest/userguide/channels-sms-limitations-mps.html) in the *Amazon Pinpoint User Guide*.

To view the number of message parts for each message that you send, you should first enable [Event stream settings](https://docs.aws.amazon.com/pinpoint/latest/userguide/settings-event-streams.html). When you do, Amazon SNS produces an `_SMS.SUCCESS` event when the message is delivered to the recipient's mobile provider. The `_SMS.SUCCESS` event record contains an attribute called `attributes.number_of_message_parts`. This attribute specifies the number of message parts that the message contained.

**Important**  
When you send a message that contains more than one message parts, you're charged for the number of message parts contained in the message.

### GSM 03.38 character set


The following table lists all of the characters that are present in the GSM 03.38 character set. If you send a message that only includes the characters shown in the following table, then the message can contain up to 160 characters. 


| GSM 03.38 standard characters | 
| --- | 
| A | B | C | D | E | F | G | H | I | J | K | L | M | 
| N | O | P | Q | R | S | T | U | V | W | X | Y | Z | 
| a | b | c | d | e | f | g | h | i | j | k | l | m | 
| n | o | p | q | r | s | t | u | v | w | x | y | z | 
| à | Å | å | Ä | ä | Ç | É | é | è | ì | Ñ | ñ | ò | 
| Ø | ø | Ö | ö | ù | Ü | ü | Æ | æ | ß | 0 | 1 | 2 | 
| 3 | 4 | 5 | 6 | 7 | 8 | 9 | & | \$1 | @ | : | , | ¤ | 
| \$1 | = | \$1 | > | \$1 | - | ¡ | ¿ | ( | < | % | . | \$1 | 
| £ | ? | " | ) | § | ; | ' | / | \$1 | ¥ | Δ | Φ | Γ | 
| Λ | Ω | Π | Ψ | Σ | Θ | Ξ |  |  |  |  |  |  | 

The GSM 03.38 character set includes several symbols in addition to those shown in the preceding table. However, each of these characters is counted as two characters because it also includes an invisible escape character:
+ ^
+ \$1
+ \$1
+ \$1
+ [
+ ]
+ \$1
+ \$1
+ €

Finally, the GSM 03.38 character set also includes the following non-printed characters:
+ A space character.
+ A line feed control, which signifies the end of one line of text and the beginning of another.
+ A carriage return control, which moves to the beginning of a line of text (usually following a line feed character).
+ An escape control, which is automatically added to the characters in the preceding list.

### Example messages


This section contains several example SMS messages. For each example, this section shows the total number of characters, as well as the number of message parts for the message.

**Example 1: A long message that only contains characters in the GSM 03.38 alphabet**  
The following message only contains characters that are in the GSM 03.38 alphabet.

`Hello Carlos. Your Example Corp. bill of $100 is now available. Autopay is scheduled for next Thursday, April 9. To view the details of your bill, go to https://example.com/bill1.`

The preceding message contains 180 characters, so it has to be split into multiple message parts. When a message is split into multiple message parts, each part can contain 153 GSM 03.38 characters. As a result, this message is sent as 2 message parts.

**Example 2: A message that contains multi-byte characters**  
The following message contains several Chinese characters, all of which are outside of the GSM 03.38 alphabet. 

`亚马逊公司是一家总部位于美国西雅图的跨国电子商务企业，业务起始于线上书店，不久之后商品走向多元化。杰夫·贝佐斯于1994年7月创建了这家公司。`

The preceding message contains 71 characters. However, because almost all of the characters in the message are outside of the GSM 03.38 alphabet, it's sent as two message parts. Each of these message parts can contain a maximum of 67 characters.

**Example 3: A message that contains a single non-GSM character**  
The following message contains a single character that isn't part of the GSM 03.38 alphabet. In this example, the character is a closing single quote (’), which is a different character from a regular apostrophe ('). Word processing applications such as Microsoft Word often automatically replace apostrophes with closing single quotes. If you draft your SMS messages in Microsoft Word and paste them into Amazon SNS, you should remove these special characters and replace them with apostrophes.

`John: Your appointment with Dr. Salazar’s office is scheduled for next Thursday at 4:30pm. Reply YES to confirm, NO to reschedule.`

The preceding message contains 130 characters. However, because it contains the closing single quote character, which isn't part of the GSM 03.38 alphabet, it's sent as two message parts.

If you replace the closing single quote character in this message with an apostrophe (which is part of the GSM 03.38 alphabet), then the message is sent as a single message part.

# Sending mobile push notifications with Amazon SNS
Sending mobile push notifications

You can use Amazon SNS to send push notification messages directly to apps on mobile devices. Push notification messages sent to a mobile endpoint can appear in the mobile app as message alerts, badge updates, or sound alerts. 

![\[Amazon SNS mobile push notification overview\]](http://docs.aws.amazon.com/sns/latest/dg/images/sns-mobile-push-notifications.png)


**Topics**
+ [

## How Amazon SNS user notifications work
](#sns-how-user-notifications-work)
+ [

## Setting up push notifications with Amazon SNS
](#sns-user-notifications-process-overview)
+ [

# Setting up a mobile app in Amazon SNS
](mobile-push-send.md)
+ [

# Using Amazon SNS for mobile push notifications
](mobile-push-notifications.md)
+ [

# Amazon SNS mobile app attributes
](sns-msg-status.md)
+ [

# Amazon SNS application event notifications for mobile applications
](application-event-notifications.md)
+ [

# Mobile push API actions
](mobile-push-api.md)
+ [

# Common Amazon SNS mobile push API errors
](mobile-push-api-error.md)
+ [

# Using the Amazon SNS time to live message attribute for mobile push notifications
](sns-ttl.md)
+ [

# Amazon SNS mobile application supported Regions
](sns-mobile-push-supported-regions.md)
+ [

# Best practices for managing Amazon SNS mobile push notifications
](mobile-push-notifications-best-practices.md)

## How Amazon SNS user notifications work


You send push notification messages to both mobile devices and desktops using one of the following supported push notification services: 
+ Amazon Device Messaging (ADM)
+ Apple Push Notification Service (APNs) for both iOS and Mac OS X
+ Baidu Cloud Push (Baidu)
+ Firebase Cloud Messaging (FCM)
+ Microsoft Push Notification Service for Windows Phone (MPNS)
+ Windows Push Notification Services (WNS)

Push notification services, such as APNs and FCM, maintain a connection with each app and associated mobile device registered to use their service. When an app and mobile device register, the push notification service returns a device token. Amazon SNS uses the device token to create a mobile endpoint, to which it can send direct push notification messages. In order for Amazon SNS to communicate with the different push notification services, you submit your push notification service credentials to Amazon SNS to be used on your behalf. For more information, see [Setting up push notifications with Amazon SNS](#sns-user-notifications-process-overview). 

 In addition to sending direct push notification messages, you can also use Amazon SNS to send messages to mobile endpoints subscribed to a topic. The concept is the same as subscribing other endpoint types, such as Amazon SQS, HTTP/S, email, and SMS, to a topic, as described in [What is Amazon SNS?](welcome.md). The difference is that Amazon SNS communicates using the push notification services in order for the subscribed mobile endpoints to receive push notification messages sent to the topic.

## Setting up push notifications with Amazon SNS


1. [Obtain the credentials and device token](sns-prerequisites-for-mobile-push-notifications.md) for the mobile platforms that you want to support.

1. Use the credentials to create a platform application object (`PlatformApplicationArn`) using Amazon SNS. For more information, see [Creating an Amazon SNS platform application](mobile-push-send-register.md).

1. Use the returned credentials to request a device token for your mobile app and device from the push notification service. The token you receive represents your mobile app and device.

1. Use the device token and the `PlatformApplicationArn` to create a platform endpoint object (`EndpointArn`) using Amazon SNS. For more information, see [Setting up an Amazon SNS platform endpoint for mobile notifications](mobile-platform-endpoint.md).

1. Use the `EndpointArn` to [publish a message to an app on a mobile device](mobile-push-send.md). For more information, see [Direct Amazon SNS mobile device messaging](mobile-push-notifications.md#mobile-push-send-directmobile) and the [Publish](https://docs.aws.amazon.com/sns/latest/api/API_Publish.html) API in the Amazon Simple Notification Service API Reference.

# Setting up a mobile app in Amazon SNS
Setting up a mobile app

This topic describes how to set up mobile applications in the AWS Management Console using the information described in [Prerequisites for Amazon SNS user notifications](sns-prerequisites-for-mobile-push-notifications.md).

# Prerequisites for Amazon SNS user notifications
Prerequisites

To begin using Amazon SNS mobile push notifications, you'll need the following:
+ A set of credentials for connecting to one of the supported push notification services: ADM, APNs, Baidu, FCM, MPNS, or WNS.
+ A device token or registration ID for the mobile app and device.
+ Amazon SNS configured to send push notification messages to the mobile endpoints.
+ A mobile app that is registered and configured to use one of the supported push notification services.

Registering your application with a push notification service requires several steps. Amazon SNS needs some of the information you provide to the push notification service in order to send direct push notification messages to the mobile endpoint. Generally speaking, you need the required credentials for connecting to the push notification service, a device token or registration ID (representing your mobile device and mobile app) received from the push notification service, and the mobile app registered with the push notification service. 

The exact form the credentials take differs between mobile platforms, but in every case, these credentials must be submitted while making a connection to the platform. One set of credentials is issued for each mobile app, and it must be used to send a message to any instance of that app. 

The specific names will vary depending on which push notification service is being used. For example, when using APNs as the push notification service, you need a *device token*. Alternatively, when using FCM, the device token equivalent is called a *registration ID*. The *device token* or *registration ID* is a string that is sent to the application by the operating system of the mobile device. It uniquely identifies an instance of a mobile app running on a particular mobile device and can be thought of as unique identifiers of this app-device pair. 

Amazon SNS stores the credentials (plus a few other settings) as a platform application resource. The device tokens (again with some extra settings) are represented as objects called *platform endpoints*. Each platform endpoint belongs to one specific platform application, and every platform endpoint can be communicated with using the credentials that are stored in its corresponding platform application.

The following sections include the prerequisites for each of the supported push notification services. Once you've obtained the prerequisite information, you can send a push notification message using the AWS Management Console or the Amazon SNS mobile push APIs. For more information, see [Setting up push notifications with Amazon SNS](sns-mobile-application-as-subscriber.md#sns-user-notifications-process-overview). 

# Creating an Amazon SNS platform application
Creating a platform application

To send notifications from Amazon SNS to mobile endpoints—whether directly or through subscriptions to a topic—you must first create a platform application. After registering the app with AWS, you need to create an endpoint for both the app and the mobile device. This endpoint allows Amazon SNS to send messages to the device.

**To create a platform application**

1. Sign in to the [Amazon SNS console](https://console.aws.amazon.com/sns/home).

1. In the navigation pane, select **Push notifications**.

1. In the **Platform applications** section, choose **Create platform application**.

1. Choose your **AWS Region**. For a list of AWS Regions where you can create mobile applications, see [Amazon SNS mobile application supported Regions](sns-mobile-push-supported-regions.md).

1. Enter the following **application details**:
   + **Application name** – Provide a **name** for your platform application. The name must be between 1 and 256 characters and can contain uppercase and lowercase letters, numbers, underscores, hyphens, and periods.
   + **Push notification platform** – Select the appropriate **notification service** that the app is registered with (For example, Apple Push Notification Service (APNs), Firebase Cloud Messaging (FCM)).

1. Depending on the platform you selected, you’ll need to provide specific credentials:
   + For **APNs** (Apple Push Notification Service) – Choose between **token-based** or **certificate-based** authentication.
     + For token-based authentication, upload a **.p8 file** (generated via Keychain Access).
     + For certificate-based authentication, upload a **.p12 file** (also exported from Keychain Access).
   + For **FCM** (Firebase Cloud Messaging) – Enter the **Server key** from Firebase Console.
   + For **other platforms** (such as ADM or GCM) – Enter the respective **API keys** or **credentials**.

1. After entering the necessary details, choose **Create platform application**. This action registers the app with Amazon SNS and creates the corresponding platform application object.

1. Upon creation, Amazon SNS generates and returns a [https://docs.aws.amazon.com/sns/latest/api/API_PlatformApplication.html](https://docs.aws.amazon.com/sns/latest/api/API_PlatformApplication.html) (Amazon Resource Name). This ARN uniquely identifies your platform application and is used when creating endpoints for mobile devices.

# Setting up an Amazon SNS platform endpoint for mobile notifications
Setting up a platform endpoint

When an app and mobile device register with a push notification service (such as APNs or Firebase Cloud Messaging), the push notification service returns a device token. Amazon SNS uses this device token to create a platform endpoint, which acts as a target for sending direct push notification messages to the app on the device. The platform endpoint serves as a bridge, routing messages sent by Amazon SNS to the push notification service for delivery to the corresponding mobile device. For more information, see [Prerequisites for Amazon SNS user notifications](sns-prerequisites-for-mobile-push-notifications.md) and [Setting up push notifications with Amazon SNS](sns-mobile-application-as-subscriber.md#sns-user-notifications-process-overview).

## Understanding device tokens and platform endpoints


A device token uniquely identifies a mobile device registered with a push notification service (for example, APNs, Firebase Cloud Messaging). When an app registers with the push notification service, it generates a device token specific to that app and device. Amazon SNS uses this device token to create a platform endpoint within the corresponding platform application.

The platform endpoint allows Amazon SNS to send push notification messages to the device through the push notification service, maintaining the connection between your app and the user's device.

## Create a platform endpoint


To push notifications to an app with Amazon SNS, that app's device token must first be registered with Amazon SNS by calling the create platform endpoint action. This action takes the Amazon Resource Name (ARN) of the platform application and the device token as parameters and returns the ARN of the created platform endpoint.

The [https://docs.aws.amazon.com/sns/latest/api/API_CreatePlatformEndpoint.html](https://docs.aws.amazon.com/sns/latest/api/API_CreatePlatformEndpoint.html) action does the following:
+ If the platform endpoint already exists, do not create it again. Return to the caller the ARN of the existing platform endpoint.
+ If the platform endpoint with the same device token but different settings already exists, do not create it again. Throw an exception to the caller.
+ If the platform endpoint does not exist, create it. Return to the caller the ARN of the newly-created platform endpoint.

You should not call the create platform endpoint action immediately every time an app starts, because this approach does not always provide a working endpoint. This can happen, for example, when an app is uninstalled and reinstalled on the same device and the endpoint for it already exists but is disabled. A successful registration process should accomplish the following:

1. Ensure a platform endpoint exists for this app-device combination.

1. Ensure the device token in the platform endpoint is the latest valid device token.

1. Ensure the platform endpoint is enabled and ready to use.

## Pseudo code


The following pseudo code describes a recommended practice for creating a working, current, enabled platform endpoint in a wide variety of starting conditions. This approach works whether this is a first time the app is being registered or not, whether the platform endpoint for this app already exists, and whether the platform endpoint is enabled, has the correct device token, and so on. It is safe to call it multiple times in a row, as it will not create duplicate platform endpoints or change an existing platform endpoint if it is already up to date and enabled.

```
retrieve the latest device token from the mobile operating system
if (the platform endpoint ARN is not stored)
  # this is a first-time registration
  call create platform endpoint
  store the returned platform endpoint ARN
endif

call get endpoint attributes on the platform endpoint ARN 

if (while getting the attributes a not-found exception is thrown)
  # the platform endpoint was deleted 
  call create platform endpoint with the latest device token
  store the returned platform endpoint ARN
else 
  if (the device token in the endpoint does not match the latest one) or 
      (GetEndpointAttributes shows the endpoint as disabled)
    call set endpoint attributes to set the latest device token and then enable the platform endpoint
  endif
endif
```

This approach can be used any time the app wants to register or re-register itself. It can also be used when notifying Amazon SNS of a device token change. In this case, you can just call the action with the latest device token value. Some points to note about this approach are:
+ There are two cases where it may call the create platform endpoint action. It may be called at the very beginning, where the app does not know its own platform endpoint ARN, as happens during a first-time registration. It is also called if the initial `GetEndpointAttributes` action call fails with a not-found exception, as would happen if the application knows its endpoint ARN but it was deleted.
+ The `GetEndpointAttributes` action is called to verify the platform endpoint's state even if the platform endpoint was just created. This happens when the platform endpoint already exists but is disabled. In this case, the create platform endpoint action succeeds but does not enable the platform endpoint, so you must double-check the state of the platform endpoint before returning success.

## AWS SDK example


The following code shows how to implement the previous pseudo code using the Amazon SNS clients that are provided by the AWS SDKs.

To use an AWS SDK, you must configure it with your credentials. For more information, see [The shared config and credentials files](https://docs.aws.amazon.com/sdkref/latest/guide/creds-config-files.html) in the *AWS SDKs and Tools Reference Guide*.

------
#### [ CLI ]

**AWS CLI**  
**To create a platform application endpoint**  
The following `create-platform-endpoint` example creates an endpoint for the specified platform application using the specified token.  

```
aws sns create-platform-endpoint \
    --platform-application-arn arn:aws:sns:us-west-2:123456789012:app/GCM/MyApplication \
    --token EXAMPLE12345...
```
Output:  

```
{
      "EndpointArn": "arn:aws:sns:us-west-2:1234567890:endpoint/GCM/MyApplication/12345678-abcd-9012-efgh-345678901234"
}
```

------
#### [ Java ]

**SDK for Java 2.x**  
 There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/javav2/example_code/sns#code-examples). 

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.sns.SnsClient;
import software.amazon.awssdk.services.sns.model.CreatePlatformEndpointRequest;
import software.amazon.awssdk.services.sns.model.CreatePlatformEndpointResponse;
import software.amazon.awssdk.services.sns.model.SnsException;

/**
 * Before running this Java V2 code example, set up your development
 * environment, including your credentials.
 *
 * For more information, see the following documentation topic:
 *
 * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
 *
 * In addition, create a platform application using the AWS Management Console.
 * See this doc topic:
 *
 * https://docs.aws.amazon.com/sns/latest/dg/mobile-push-send-register.html
 *
 * Without the values created by following the previous link, this code examples
 * does not work.
 */

public class RegistrationExample {
    public static void main(String[] args) {
        final String usage = """

            Usage:     <token> <platformApplicationArn>

            Where:
               token - The device token or registration ID of the mobile device. This is a unique 
               identifier provided by the device platform (e.g., Apple Push Notification Service (APNS) for iOS devices, Firebase Cloud Messaging (FCM) 
               for Android devices) when the mobile app is registered to receive push notifications.

               platformApplicationArn - The ARN value of platform application. You can get this value from the AWS Management Console.\s

            """;

        if (args.length != 2) {
            System.out.println(usage);
            return;
        }

        String token = args[0];
        String platformApplicationArn = args[1];
        SnsClient snsClient = SnsClient.builder()
            .region(Region.US_EAST_1)
            .build();

        createEndpoint(snsClient, token, platformApplicationArn);
    }
    public static void createEndpoint(SnsClient snsClient, String token, String platformApplicationArn) {
        System.out.println("Creating platform endpoint with token " + token);
        try {
            CreatePlatformEndpointRequest endpointRequest = CreatePlatformEndpointRequest.builder()
                .token(token)
                .platformApplicationArn(platformApplicationArn)
                .build();

            CreatePlatformEndpointResponse response = snsClient.createPlatformEndpoint(endpointRequest);
            System.out.println("The ARN of the endpoint is " + response.endpointArn());

        } catch (SnsException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
        }
    }
}
```

------

 For more information, see [Mobile push API actions](mobile-push-api.md).

## Troubleshooting


### Repeatedly calling create platform endpoint with an outdated device token


Especially for FCM endpoints, you may think it is best to store the first device token the application is issued and then call the create platform endpoint with that device token every time on application start-up. This may seem correct since it frees the app from having to manage the state of the device token and Amazon SNS will automatically update the device token to its latest value. However, this solution has a number of serious issues:
+ Amazon SNS relies on feedback from FCM to update expired device tokens to new device tokens. FCM retains information about old device tokens for some time, but not indefinitely. Once FCM forgets about the connection between the old device token and the new device token, Amazon SNS will no longer be able to update the device token stored in the platform endpoint to its correct value; it will just disable the platform endpoint instead.
+ The platform application will contain multiple platform endpoints corresponding to the same device token.
+ Amazon SNS imposes a quota on the number of platform endpoints that can be created starting with the same device token. Eventually, the creation of new endpoints will fail with an invalid parameter exception and the following error message: "This endpoint is already registered with a different token."

For more information on managing FCM endpoints, see [Amazon SNS management of Firebase Cloud Messaging endpoints](sns-fcm-endpoint-management.md).

### Re-enabling a platform endpoint associated with an invalid device token


When a mobile platform (such as APNs or FCM) informs Amazon SNS that the device token used in the publish request was invalid, Amazon SNS disables the platform endpoint associated with that device token. Amazon SNS will then reject subsequent publishes to that device token. While you may think it is best to simply re-enable the platform endpoint and keep publishing, in most situations doing this will not work: the messages that are published do not get delivered and the platform endpoint becomes disabled again soon afterward.

This is because the device token associated with the platform endpoint is genuinely invalid. Deliveries to it cannot succeed because it no longer corresponds to any installed app. The next time it is published to, the mobile platform will again inform Amazon SNS that the device token is invalid, and Amazon SNS will again disable the platform endpoint.

To re-enable a disabled platform endpoint, it needs to be associated with a valid device token (with a set endpoint attributes action call) and then enabled. Only then will deliveries to that platform endpoint become successful. The only time re-enabling a platform endpoint without updating its device token will work is when a device token associated with that endpoint used to be invalid but then became valid again. This can happen, for example, when an app was uninstalled and then re-installed on the same mobile device and receives the same device token. The approach presented above does this, making sure to only re-enable a platform endpoint after verifying that the device token associated with it is the most current one available.

# Integrating device tokens with Amazon SNS for mobile notifications
Integrating device tokens for mobile notifications

When you first register an app and mobile device with a notification service, such as Apple Push Notification Service (APNs) and Firebase Cloud Messaging (FCM), device tokens or registration IDs are returned by the service. These tokens/IDs are added to Amazon SNS to create an endpoint for the app and device, using the [https://docs.aws.amazon.com/sns/latest/api/API_PlatformApplication.html](https://docs.aws.amazon.com/sns/latest/api/API_PlatformApplication.html) API. Once the endpoint is created, an [https://docs.aws.amazon.com/sns/latest/api/API_Endpoint.html](https://docs.aws.amazon.com/sns/latest/api/API_Endpoint.html) is returned, which Amazon SNS uses to direct notifications to the correct app/device.

You can add device tokens or registration IDs to Amazon SNS in the following ways:
+ Manually add a single token via the AWS Management Console
+ Upload several tokens using the [https://docs.aws.amazon.com/sns/latest/api/API_CreatePlatformEndpoint.html](https://docs.aws.amazon.com/sns/latest/api/API_CreatePlatformEndpoint.html) API
+ Register tokens for future devices

****To manually add a device token or registration ID****

1. Sign in to the [Amazon SNS console](https://console.aws.amazon.com/sns/home).

1. In the navigation pane, select **Push Notifications**.

1. In the **Platform applications** section, select your application, and then choose **Edit**. If you haven't already created a platform application, follow the [Creating an Amazon SNS platform application](mobile-push-send-register.md) guide to do so now.

1. Choose **Create Endpoint**.

1. In the **Endpoint Token** box, enter the **token** or **registration ID**, depending on the notification service you're using (for example, FCM registration ID).

1. (Optional) Enter additional data in the **User Data** field. This data must be UTF-8 encoded and less than 2 KB.

1. Choose **Create Endpoint**.

Once the endpoint is created, you can send messages directly to the mobile device or to mobile devices subscribed to an Amazon SNS topic.

****To upload several tokens using the `CreatePlatformEndpoint` API****

The following steps show how to use the sample Java app (`bulkupload` package) provided by AWS to upload several tokens (device tokens or registration IDs) to Amazon SNS. You can use this sample app to help you get started with uploading your existing tokens. 
**Note**  
The following steps use the Eclipse Java IDE. The steps assume you have installed the AWS SDK for Java and you have the AWS security credentials for your AWS account. For more information, see [AWS SDK for Java](http://aws.amazon.com/sdkforjava/). For more information about credentials, see [AWS security credentials](https://docs.aws.amazon.com/general/latest/gr/getting-aws-sec-creds.html) in the *IAM User Guide*. 

1. Download and unzip the [snsmobilepush.zip](samples/snsmobilepush.zip) file. 

1. Create a new **Java project** in Eclipse and import the `SNSSamples` folder to the project. 

1. Download the [OpenCSV library](http://sourceforge.net/projects/opencsv/) and add it to the build path.

1. In the `BulkUpload.properties` file, specify the following: 
   + Your `ApplicationArn` (platform application ARN).
   + The absolute path to your CSV file containing the tokens.
   + Logging filenames for successful and failed tokens. For example, `goodTokens.csv` and `badTokens.csv`.
   + (Optional) A configuration for delimiter, quote character, and number of threads to use.

   Your completed `BulkUpload.properties` should look similar to the following:

   ```
   applicationarn: arn:aws:sns:us-west-2:111122223333:app/FCM/fcmpushapp
   csvfilename: C:\\mytokendirectory\\mytokens.csv
   goodfilename: C:\\mylogfiles\\goodtokens.csv
   badfilename: C:\\mylogfiles\\badtokens.csv
   delimiterchar: ','
   quotechar: '"'
   numofthreads: 5
   ```

1.  Run the **BatchCreatePlatformEndpointSample.java** application to upload the tokens to Amazon SNS. Tokens uploaded successfully will be logged in `goodTokens.csv`, while malformed tokens will be logged in `badTokens.csv`.

**To register tokens from devices for future app installations**

You have two options for this process:

**Use the Amazon Cognito service**  
Your mobile app can use temporary security credentials to create endpoints. Amazon Cognito is recommended to generate temporary credentials. For more information, see the *[Amazon Cognito Developer Guide](https://docs.aws.amazon.com/cognito/latest/developerguide/)*   
To track app [registrations](application-event-notifications.md), use Amazon SNS events to receive notifications when new endpoint ARNs are created.  
Alternatively, you can use the [https://docs.aws.amazon.com/sns/latest/api/API_ListEndpointsByPlatformApplication.html](https://docs.aws.amazon.com/sns/latest/api/API_ListEndpointsByPlatformApplication.html) API to retrieve the list of registered endpoints.

**Use a proxy server**  
If your app infrastructure already supports device registration on installation, you can use your server as a proxy. It will forward device tokens to Amazon SNS via the [https://docs.aws.amazon.com/sns/latest/api/API_CreatePlatformEndpoint.html](https://docs.aws.amazon.com/sns/latest/api/API_CreatePlatformEndpoint.html) API.  
The endpoint ARN created by Amazon SNS will be returned and can be stored by your server for future message publishing.

# Amazon SNS Apple push notification authentication methods
Apple authentication methods

You can authorize Amazon SNS to send push notifications to your iOS or macOS app by providing information that identifies you as the developer of the app. To authenticate, provide either a *key* or a *certificate* [when creating a platform application](https://docs.aws.amazon.com/sns/latest/api/API_SetPlatformApplicationAttributes.html), both of which you can get from your Apple Developer account.

**Token signing key**  
A private signing key that Amazon SNS uses to sign Apple Push Notification Service (APNs) authentication tokens.  
If you provide a signing key, Amazon SNS uses a token to authenticate with APNs for every push notification that you send. With your signing key, you can send push notifications to APNs production and sandbox environments.  
Your signing key doesn't expire, and you can use the same signing key for multiple apps. For more information, see [Communicate with APNs using authentication tokens](https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/establishing_a_token-based_connection_to_apns) in the **Developer Account Help** section of the Apple website.

**Certificate**  
A TLS certificate that Amazon SNS uses to authenticate with APNs when you send push notifications. You obtain the certificate from your Apple Developer account.  
Certificates expire after one year. When this happens, you must create a new certificate and provide it to Amazon SNS. For more information, see [Establishing a Certificate-Based Connection to APNs](https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/establishing_a_certificate-based_connection_to_apns) on the Apple Developer website.

**To manage APNs settings using the AWS Management Console**

1. Sign in to the [Amazon SNS console](https://console.aws.amazon.com/sns/home).

1. In the navigation pane, select **Push notifications**.

1. In the **Platform applications** section, select the **application** whose APNs settings you want to edit, and then choose **Edit**. If you haven't already created a platform application, follow the [Creating an Amazon SNS platform application](mobile-push-send-register.md) guide to do so now.

1. Choose **Edit** to modify the settings for your platform application.

1. In the**Authentication type** section, choose one of the following options:
   + **Token-based authentication** (recommended for modern APNs integrations)
   + **Certificate-based authentication** (older method)

1. Configure your **credentials** based on the authentication type:
   + **For token-based authentication:**
     + Upload the **.p8 file**, which is the authentication token signing key you downloaded from your Apple Developer account.
     + Enter the **Signing Key ID** that you find in your Apple Developer account. Navigate to **Certificates**, **IDs & Profiles**, **Keys**, and select the **key** you want to use.
     + Provide the **Team Identifier** from your Apple Developer account. You can find this on the Membership page.
     + Enter the **Bundle Identifier** assigned to your app. You can find this under Certificates, IDs and Profiles, App IDs.
   + **For certificate-based authentication:**
     + Upload the **.p12 file** for your TLS certificate. This file can be exported from Keychain Access on macOS after downloading the certificate from your Apple Developer account.
     + If you assigned a **password** to your .p12 certificate, enter it here.

1. After entering the necessary credentials, choose **Save changes** to update the settings.

# Amazon SNS integration with Firebase Cloud Messaging authentication setup
FCM authentication methods

This topic describes how to obtain the required FCM API (HTTP v1) credentials from Google to use with the AWS API, AWS CLI and the AWS Management Console.

**Important**  
March 26, 2024 – Amazon SNS supports FCM HTTP v1 API for Apple devices and Webpush destinations. We recommend that you migrate your existing mobile push applications to the latest FCM HTTP v1 API on or before June 1, 2024 to avoid application disruption.  
January 18, 2024 – Amazon SNS introduced support for FCM HTTP v1 API for mobile push notification delivery to Android devices.  
June 20, 2023 – Google deprecated their Firebase Cloud Messaging (FCM) legacy HTTP API. Amazon SNS now supports delivery to all device types using FCM HTTP v1 API. We recommend that you migrate your existing mobile push applications to the latest FCM HTTP v1 API on or before June 1, 2024 to avoid disruption.

You can authorize Amazon SNS to send push notifications to your applications by providing information that identifies you as the developer of the app. To authenticate, provide either an **API key** or a **token** [when creating a platform application](https://docs.aws.amazon.com/sns/latest/api/API_SetPlatformApplicationAttributes.html). You can get the following information from your [Firebase application console](https://firebase.google.com/?gad=1&gclid=CjwKCAiA0syqBhBxEiwAeNx9N27M7zxHjlS74_gp4mAS4QTMQH5J35sTO29od-yauuq259zzX_I2DRoCrbsQAvD_BwE&gclsrc=aw.ds):

**API Key**  
The API key is a credential used when calling Firebase’s Legacy API. The FCM Legacy APIs will be removed by Google June 20, 2024. If you are currently using an API key as your platform credential, you can update the platform credential by selecting **Token** as the option, and uploading the associated JSON file for your Firebase application.

**Token**  
A short lived access token is used when calling the HTTP v1 API. This is Firebase’s suggested API for sending push notifications. In order to generate access tokens, Firebase provides developers a set of credentials in the form of a private key file (also referred to as a service.json file).

## Prerequisite


You must obtain your FCM service.json credentials before you can begin managing FCM settings in Amazon SNS. To obtain your service.json credentials, see [Migrate from legacy FCM APIs to HTTP v1](https://firebase.google.com/docs/cloud-messaging/migrate-v1) in the Google Firebase documentation.

## Managing FCM settings using the CLI


You can create FCM push notifications using the AWS API. The number and size of Amazon SNS resources in an AWS account are limited. For more information, see [Amazon Simple Notification Service endpoints and quotas](https://docs.aws.amazon.com/general/latest/gr/sns.html) in the *AWS General Reference Guide*.

**To create an FCM push notification together with an Amazon SNS topic (AWS API)**  
When using **key** credentials, the `PlatformCredential` is `API key`. When using **token** credentials, the `PlatformCredential` is a JSON formatted private key file:
+ [https://docs.aws.amazon.com/sns/latest/api/API_CreatePlatformApplication.html](https://docs.aws.amazon.com/sns/latest/api/API_CreatePlatformApplication.html)

**To retrieve an FCM credential type for an existing Amazon SNS topic (AWS API)**  
Retrieves the credential type `"AuthenticationMethod": "Token"`, or ` "AuthenticationMethod": "Key"`:
+ [GetPlatformApplicationAttributes](https://docs.aws.amazon.com/sns/latest/api/API_GetPlatformApplicationAttributes.html)

**To set an FCM attribute for an existing Amazon SNS topic (AWS API)**  
Sets the FCM attribute:
+ [SetPlatformApplicationAttributes](https://docs.aws.amazon.com/sns/latest/api/API_SetPlatformApplicationAttributes.html)

## Managing FCM settings using the console


You can create FCM push notifications using the AWS Command Line Interface (CLI). The number and size of Amazon SNS resources in an AWS account are limited. For more information, see [Amazon Simple Notification Service endpoints and quotas](https://docs.aws.amazon.com/general/latest/gr/sns.html). 

**To create an FCM push notification together with an Amazon SNS topic (AWS CLI)**  
When using **key** credentials, the `PlatformCredential` is `API key`. When using **token** credentials, the `PlatformCredential` is a JSON formatted private key file. When using the AWS CLI, the file must be in string format and special characters must be ignored. To format the file correctly,Amazon SNS recommends using the following command: `SERVICE_JSON=`jq @json <<< cat service.json``:
+ [create-platform-application](https://docs.aws.amazon.com/cli/latest/reference/sns/create-platform-application.html)

**To retrieve an FCM credential type for an existing Amazon SNS topic (AWS CLI)**  
Retrieves the credential type `"AuthenticationMethod": "Token"`, or ` "AuthenticationMethod": "Key"`:
+ [get-platform-application-attributes](https://docs.aws.amazon.com/cli/latest/reference/sns/get-platform-application-attributes.html)

**To set an FCM attribute for an existing Amazon SNS topic (AWS CLI)**  
Sets the FCM attribute:
+ [set-platform-application-attributes](https://docs.aws.amazon.com/cli/latest/reference/sns/set-platform-application-attributes.html)

## Managing FCM settings (console)


Use the following steps to enter and manage your Firebase Cloud Messaging (FCM) credentials in Amazon SNS.

1. Sign in to the [Amazon SNS console](https://console.aws.amazon.com/sns/home).

1. In the navigation pane, select **Push Notifications**.

1. In the **Platform applications** section, select the **FCM platform application** whose credentials you want to edit, and then choose **Edit**.

1. In the **Firebase Cloud Messaging Credentials** section, choose one of the following options:
   + **Token-based authentication** (recommended method) – Upload the **private key file** (JSON) that you downloaded from the Firebase Console. This file contains the credentials needed to generate short-lived access tokens for FCM notifications. To get this file:

     1. Go to your [Firebase application console](https://firebase.google.com/?gad=1&gclid=CjwKCAiA0syqBhBxEiwAeNx9N27M7zxHjlS74_gp4mAS4QTMQH5J35sTO29od-yauuq259zzX_I2DRoCrbsQAvD_BwE&gclsrc=aw.ds).

     1. In the **Project Settings**, select **Cloud Messaging**.

     1. Download the **Private key** JSON file (for use in the token-based authentication method).
   + **API key authentication** – If you prefer to use the older API key authentication method, enter the **Google API key** in the provided field. To get this file:

     1. Go to your [Firebase application console](https://firebase.google.com/?gad=1&gclid=CjwKCAiA0syqBhBxEiwAeNx9N27M7zxHjlS74_gp4mAS4QTMQH5J35sTO29od-yauuq259zzX_I2DRoCrbsQAvD_BwE&gclsrc=aw.ds).

     1. In **Project Settings**, select **Cloud Messaging**.

     1. Copy the **Server key** (API key) to use for sending notifications.

1. When you finish, choose **Save changes**.

**Related topics**
+ [Using Google Firebase Cloud Messaging v1 payloads in Amazon SNS](sns-fcm-v1-payloads.md)

# Amazon SNS management of Firebase Cloud Messaging endpoints
FCM endpoint management

## Managing and maintaining device tokens


You can ensure deliverability of your mobile application's push notifications by following these steps:

1. Store all device tokens, corresponding Amazon SNS endpoint ARNs, and timestamps on your application server.

1. Remove all stale tokens and delete the corresponding Amazon SNS endpoint ARNs.

Upon your app's initial start-up, you'll receive a device token (also referred to as registration token) for the device. This device token is minted by the device’s operating system, and is tied to your FCM application. Once you receive this device token, you can register it with Amazon SNS as a platform endpoint. We recommend that you store the device token, the Amazon SNS platform endpoint ARN, and the timestamp by saving the them to your application server, or another persistent store. To set-up your FCM application to retrieve and store device tokens, see [Retrieve and store registration tokens](https://firebase.google.com/docs/cloud-messaging/manage-tokens#retrieve-and-store-registration-tokens) in Google's *Firebase* documentation.

It's important that you maintain up-to-date tokens. Your user’s device tokens can change under the following conditions:

1. The mobile application is restored on a new device.

1. The user uninstalls or updates the application.

1. The user clears application data.

When your device token changes, we recommended that you update the corresponding Amazon SNS endpoint with the new token. This allows Amazon SNS to continue communication to the registered device. You can do this by implementing the following pseudo code within your mobile application. It describes a recommended practice for creating and maintaining enabled platform endpoints. This approach can be executed each time the mobile applications starts, or as a scheduled job in the background.

### Pseudo code


Use the following FCM pseudo code to manage and maintain device tokens.

```
retrieve the latest token from the mobile OS
if (endpoint arn not stored)
    # first time registration
    call CreatePlatformEndpoint
    store returned endpoint arn
endif

call GetEndpointAttributes on the endpoint arn 

if (getting attributes encountered NotFound exception)
    #endpoint was deleted 
    call CreatePlatformEndpoint
    store returned endpoint arn
else 
    if (token in endpoint does not match latest) or 
        (GetEndpointAttributes shows endpoint as disabled)
        call SetEndpointAttributes to set the 
                     latest token and enable the endpoint
    endif
endif
```

To learn more about token update requirements, see [Update Tokens on a Regular Basis](https://firebase.google.com/docs/cloud-messaging/manage-tokens#update-tokens-on-a-regular-basis) in Google's *Firebase* documentation.

## Detecting invalid tokens


When a message is dispatched to an FCM v1 endpoint with an invalid device token, Amazon SNS will receive one of the following exceptions:
+ `UNREGISTERED` (HTTP 404) – When Amazon SNS receives this exception, you will receive a delivery failure event with a `FailureType` of `InvalidPlatformToken`, and a `FailureMessage` of *Platform token associated with the endpoint is not valid*. Amazon SNS will disable your platform endpoint when a delivery fails with this exception.
+ `INVALID_ARGUMENT` (HTTP 400) – When Amazon SNS receives this exception, it means that the device token or the message payload is invalid. For more information, see [ErrorCode](https://firebase.google.com/docs/reference/fcm/rest/v1/ErrorCode) in Google's *Firebase* documentation.

Since `INVALID_ARGUMENT` can be returned in either of these cases, Amazon SNS will return a `FailureType` of `InvalidNotification`, and a `FailureMessage` of *Notification body is invalid*. When you receive this error, verify that your payload is correct. If it is correct, verify that the device token is up-to-date. Amazon SNS will not disable your platform endpoint when a delivery fails with this exception.

Another case where you will experience an `InvalidPlatformToken` delivery failure event is when the registered device token doesn't belong to the application attempting to send that message. In this case, Google will return a *SENDER\$1ID\$1MISMATCH* error. Amazon SNS will disable your platform endpoint when a delivery fails with this exception.

All observed error codes received from the FCM v1 API are available to you in CloudWatch when you set up [delivery status logging](topics-attrib.md) for your application. 

To receive delivery events for your application, see [Available application events](application-event-notifications.md#application-event-notifications-events).

## Removing stale tokens


Tokens are considered stale once message deliveries to the endpoint device start failing. Amazon SNS sets these stale tokens as disabled endpoints for your platform application. When you publish to a disabled endpoint, Amazon SNS will return a `EventDeliveryFailure` event with the `FailureType` of `EndpointDisabled`, and a `FailureMessage` of *Endpoint is disabled*. To receive delivery events for your application, see [Available application events](application-event-notifications.md#application-event-notifications-events).

When you receive this error from Amazon SNS, you need to remove or update the stale token in your platform application.

# Using Amazon SNS for mobile push notifications
Using Amazon SNS for mobile push notifications

 This section describes how to send mobile push notifications.

## Publishing to a topic
Publishing to a topic

You can also use Amazon SNS to send messages to mobile endpoints subscribed to a topic. The concept is the same as subscribing other endpoint types, such as Amazon SQS, HTTP/S, email, and SMS, to a topic, as described in [What is Amazon SNS?](welcome.md). The difference is that Amazon SNS communicates through notification services like Apple Push Notification Service (APNS) and Google Firebase Cloud Messaging (FCM). Through the notifications service, the subscribed mobile endpoints receive notifications sent to the topic. 

## Direct Amazon SNS mobile device messaging
Direct mobile device messaging

You can send Amazon SNS push notification messages directly to an endpoint which represents an application on a mobile device. 

**To send a direct message**

1. Sign in to the [Amazon SNS console](https://console.aws.amazon.com/sns/home).

1. On the navigation panel, choose **Push notifications**.

1. On the **Mobile push notifications** page, in the **Platform applications** section, choose the name of the application, for example ***MyApp***.

1. On the ***MyApp*** page, in the **Endpoints** section, choose an endpoint and then choose **Publish message**.

1. On the **Publish message to endpoint** page, enter the message that will appear in the application on the mobile device and then choose **Publish message**.

   Amazon SNS sends the notification message to the platform notification service which, in turn, sends the message to the application.

# Publishing Amazon SNS notifications with platform-specific payloads
Publishing notifications with platform-specific payloads

You can use the AWS Management Console or Amazon SNS APIs to send custom messages with platform-specific payloads to mobile devices. For information about using the Amazon SNS APIs, see [Mobile push API actions](mobile-push-api.md) and the `SNSMobilePush.java` file in `[snsmobilepush.zip](samples/snsmobilepush.zip)`. 

## Sending JSON-formatted messages


When you send platform-specific payloads, the data must be formatted as JSON key-value pair strings, with the quotation marks escaped.

The following examples show a custom message for the FCM platform.

```
{
"GCM": "{\"fcmV1Message\": {\"message\": {\"notification\": {\"title\": \"Hello\", \"body\": \"This is a test.\"}, \"data\": {\"dataKey\": \"example\"}}}}"
}
```

## Sending platform-specific messages


In addition to sending custom data as key-value pairs, you can send platform-specific key-value pairs.

The following example shows the inclusion of the FCM parameters `time_to_live` and `collapse_key` after the custom data key-value pairs in the FCM `data` parameter.

```
{
"GCM": "{\"fcmV1Message\": {\"message\": {\"notification\": {\"title\": \"TitleTest\", \"body\": \"Sample message for Android or iOS endpoints.\"}, \"data\":{\"time_to_live\": 3600,\"collapse_key\":\"deals\"}}}}"
}
```

For a list of the key-value pairs supported by each of the push notification services supported in Amazon SNS, see the following: 

**Important**  
Amazon SNS now supports Firebase Cloud Messaging (FCM) HTTP v1 API for sending mobile push notifications to Android devices.  
March 26, 2024 – Amazon SNS supports FCM HTTP v1 API for Apple devices and Webpush destinations. We recommend that you migrate your existing mobile push applications to the latest FCM HTTP v1 API on or before June 1, 2024 to avoid application disruption.
+ [Payload Key Reference](https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/PayloadKeyReference.html#/apple_ref/doc/uid/TP40008194-CH17-SW1) in the APNs documentation
+ [Firebase Cloud Messaging HTTP Protocol](https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages) in the FCM documentation
+ [Send a Message](https://developer.amazon.com/sdk/adm/sending-message.html) in the ADM documentation

## Sending messages to an application on multiple platforms


To send a message to an application installed on devices for multiple platforms, such as FCM and APNs, you must first subscribe the mobile endpoints to a topic in Amazon SNS and then publish the message to the topic.

The following example shows a message to send to subscribed mobile endpoints on APNs, FCM, and ADM: 

```
{ 
  "default": "This is the default message which must be present when publishing a message to a topic. The default message will only be used if a message is not present for 
one of the notification platforms.",     
  "APNS": "{\"aps\":{\"alert\": \"Check out these awesome deals!\",\"url\":\"www.amazon.com\"} }",
  "GCM": "{\"data\":{\"message\":\"Check out these awesome deals!\",\"url\":\"www.amazon.com\"}}",
  "ADM": "{\"data\":{\"message\":\"Check out these awesome deals!\",\"url\":\"www.amazon.com\"}}" 
}
```

## Sending messages to APNs as alert or background notifications


Amazon SNS can send messages to APNs as `alert` or `background` notifications (for more information, see [Pushing Background Updates to Your App](https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/pushing_background_updates_to_your_app) in the APNs documentation).
+ An `alert` APNs notification informs the user by displaying an alert message, playing a sound, or adding a badge to your application’s icon.
+ A `background` APNs notification wakes up or instructs your application to act upon the content of the notification, without informing the user.

### Specifying custom APNs header values


We recommend specifying custom values for the `AWS.SNS.MOBILE.APNS.PUSH_TYPE` [reserved message attribute](sns-message-attributes.md#sns-attrib-mobile-reserved) using the Amazon SNS `Publish` API action, AWS SDKs, or the AWS CLI. The following CLI example sets `content-available` to `1` and `apns-push-type` to `background` for the specified topic. 

```
aws sns publish \
--endpoint-url https://sns.us-east-1.amazonaws.com \
--target-arn arn:aws:sns:us-east-1:123456789012:endpoint/APNS_PLATFORM/MYAPP/1234a567-bc89-012d-3e45-6fg7h890123i \
--message '{"APNS_PLATFORM":"{\"aps\":{\"content-available\":1}}"}' \
--message-attributes '{ \
  "AWS.SNS.MOBILE.APNS.TOPIC":{"DataType":"String","StringValue":"com.amazon.mobile.messaging.myapp"}, \
  "AWS.SNS.MOBILE.APNS.PUSH_TYPE":{"DataType":"String","StringValue":"background"}, \
  "AWS.SNS.MOBILE.APNS.PRIORITY":{"DataType":"String","StringValue":"5"}}' \
--message-structure json
```

**Note**  
Ensure that the JSON structure is valid. Add a comma after each key-value pair, except the last one.

### Inferring the APNs push type header from the payload


If you don't set the `apns-push-type` APNs header, Amazon SNS sets header to `alert` or `background` depending on the `content-available` key in the `aps` dictionary of your JSON-formatted APNs payload configuration.

**Note**  
Amazon SNS is able to infer only `alert` or `background` headers, although the `apns-push-type` header can be set to other values.
+ `apns-push-type` is set to `alert`
  + If the `aps` dictionary contains `content-available` set to `1` and *one or more keys* that trigger user interactions.
  + If the `aps` dictionary contains `content-available` set to `0` *or* if the `content-available` key is absent.
  + If the value of the `content-available` key isn’t an integer or a Boolean.
+ `apns-push-type` is set to `background`
  + If the `aps` dictionary *only* contains `content-available` set to `1` and *no other keys* that trigger user interactions.
**Important**  
If Amazon SNS sends a raw configuration object for APNs as a background-only notification, you must include `content-available` set to `1` in the `aps` dictionary. Although you can include custom keys, the `aps` dictionary must not contain any keys that trigger user interactions (for example, alerts, badges, or sounds).

The following is an example raw configuration object.

```
{
  "APNS": "{\"aps\":{\"content-available\":1},\"Foo1\":\"Bar\",\"Foo2\":123}"
}
```

In this example, Amazon SNS sets the `apns-push-type` APNs header for the message to `background`. When Amazon SNS detects that the `apn` dictionary contains the `content-available` key set to `1`—and doesn't contain any other keys that can trigger user interactions—it sets the header to `background`.

# Using Google Firebase Cloud Messaging v1 payloads in Amazon SNS
FCM v1 API payloads

Amazon SNS supports using FCM HTTP v1 API to send notifications to Android, iOS, and Webpush destinations. This topic provides examples of the payload structure when publishing mobile push notifications using the CLI, or the Amazon SNS API.

You can include the following message types in your payload when sending an FCM notification:
+ **Data message** – A data message is handled by your client app and contains custom key-value pairs. When constructing a data message, you must include the `data` key with a JSON object as the value, and then enter your custom key-value pairs.
+ **Notification message** or **display message** – A notification message contains a predefined set of keys handled by the FCM SDK. These keys vary depending on the device type to which you are delivering. For more information on platform-specific notification keys, see the following:
  + [Android notification keys](https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages)
  + [APNS notification keys](https://developer.apple.com/documentation/usernotifications/generating-a-remote-notification)
  + [Webpush notification keys](https://developer.mozilla.org/en-US/docs/Web/API/Notification)

For more information about FCM message types, see [Message types](https://firebase.google.com/docs/cloud-messaging/concept-options#notifications_and_data_messages) in the in Google's *Firebase* documentation.

## Using the FCM v1 payload structure to send messages


If you are creating an FCM application for the first time, or wish to take advantage of FCM v1 features, you can opt-in to send an FCM v1 formatted payload. To do this, you must include the top-level key `fcmV1Message`. For more information about constructing FCM v1 payloads, see [Migrate from legacy FCM APIs to HTTP v1](https://firebase.google.com/docs/cloud-messaging/migrate-v1) and [Customizing a message across platforms](https://firebase.google.com/docs/cloud-messaging/concept-options#customizing-a-message-across-platforms) in Google's *Firebase* documentation.

**FCM v1 example payload sent to Amazon SNS:**

**Note**  
The `GCM` key value used in the following example must be encoded as a String when publishing a notification using Amazon SNS. 

```
{
  "GCM": "{ 
    \"fcmV1Message\": { 
      \"validate_only\": false,
      \"message\": {
        \"notification\": {
          \"title\": \"string\",
          \"body\": \"string\"
        },
        \"data\": {
          \"dataGen\": \"priority message\"
        },
        \"android\": {
          \"priority\": \"high\",
          \"notification\": {
            \"body_loc_args\": [\"string\"],
            \"title_loc_args\": [\"string\"],
            \"sound\": \"string\",
            \"title_loc_key\": \"string\",
            \"title\": \"string\",
            \"body\": \"string\",
            \"click_action\": \"clicky_clacky\",
            \"body_loc_key\": \"string\"
          },
          \"data\": {
            \"dataAndroid\": \"priority message\"
          },
          \"ttl\": \"10023.32s\"
        },
        \"apns\": {
          \"payload\": {
            \"aps\": {
              \"alert\": {
                \"subtitle\": \"string\",
                \"title-loc-args\": [\"string\"],
                \"title-loc-key\": \"string\",
                \"loc-args\": [\"string\"],
                \"loc-key\": \"string\",
                \"title\": \"string\",
                \"body\": \"string\"
              },
              \"category\": \"Click\",
              \"content-available\": 0,
              \"sound\": \"string\",
              \"badge\": 5
            }
          }
        },
        \"webpush\": {
          \"notification\": {
            \"badge\": \"5\",
            \"title\": \"string\",
            \"body\": \"string\"
          },
          \"data\": {
            \"dataWeb\": \"priority message\"
          }
        }
      }
    }
  }"
}
```

When sending a JSON payload, be sure to include the `message-structure` attribute in your request, and set it to `json`.

**CLI example:**

```
aws sns publish --topic $TOPIC_ARN --message '{"GCM": "{\"fcmV1Message\": {\"message\":{\"notification\":{\"title\":\"string\",\"body\":\"string\"},\"android\":{\"priority\":\"high\",\"notification\":{\"title\":\"string\",\"body\":\"string\"},\"data\":{\"customAndroidDataKey\":\"custom key value\"},\"ttl\":\"0s\"},\"apns\":{\"payload\":{\"aps\":{\"alert\":{\"title\":\"string\", \"body\":\"string\"},\"content-available\":1,\"badge\":5}}},\"webpush\":{\"notification\":{\"badge\":\"URL\",\"body\":\"Test\"},\"data\":{\"customWebpushDataKey\":\"priority message\"}},\"data\":{\"customGeneralDataKey\":\"priority message\"}}}}", "default": "{\"notification\": {\"title\": \"test\"}"}' --region $REGION --message-structure json
```

For more information on sending FCM v1 formatted payloads, see the following in Google's *Firebase* documentation:
+ [Migrate from legacy FCM APIs to HTTP v1](https://firebase.google.com/docs/cloud-messaging/migrate-v1)
+ [About FCM messages](https://firebase.google.com/docs/cloud-messaging/concept-options#customizing_a_message_across_platforms)
+ [REST Resource: projects.messages](https://firebase.google.com/docs/reference/fcm/rest/v1/projects.messages)

## Using the legacy payload structure to send messages to the FCM v1 API


When migrating to FCM v1, you don't have to change the payload structure that you were using for your legacy credentials. Amazon SNS transforms your payload into the new FCM v1 payload structure, and sends to Google.

Input message payload format:

```
{
  "GCM": "{\"notification\": {\"title\": \"string\", \"body\": \"string\", \"android_channel_id\": \"string\", \"body_loc_args\": [\"string\"], \"body_loc_key\": \"string\", \"click_action\": \"string\", \"color\": \"string\", \"icon\": \"string\", \"sound\": \"string\", \"tag\": \"string\", \"title_loc_args\": [\"string\"], \"title_loc_key\": \"string\"}, \"data\": {\"message\": \"priority message\"}}"
}
```

Message sent to Google:

```
{
  "message": {
    "token": "***",
    "notification": {
      "title": "string",
      "body": "string"
    },
    "android": {
      "priority": "high",
      "notification": {
        "body_loc_args": [
          "string"
        ],
        "title_loc_args": [
          "string"
        ],
        "color": "string",
        "sound": "string",
        "icon": "string",
        "tag": "string",
        "title_loc_key": "string",
        "title": "string",
        "body": "string",
        "click_action": "string",
        "channel_id": "string",
        "body_loc_key": "string"
      },
      "data": {
        "message": "priority message"
      }
    },
    "apns": {
      "payload": {
        "aps": {
          "alert": {
            "title-loc-args": [
              "string"
            ],
            "title-loc-key": "string",
            "loc-args": [
              "string"
            ],
            "loc-key": "string",
            "title": "string",
            "body": "string"
          },
          "category": "string",
          "sound": "string"
        }
      }
    },
    "webpush": {
      "notification": {
        "icon": "string",
        "tag": "string",
        "body": "string",
        "title": "string"
      },
      "data": {
        "message": "priority message"
      }
    },
    "data": {
      "message": "priority message"
    }
  }
}
```

**Potential risks**
+ Legacy to v1 mapping doesn't support the Apple Push Notification Service (APNS) `headers` or the `fcm_options` keys. If you'd like to use these fields, send an FCM v1 payload.
+ In some cases, message headers are required by FCM v1 to send silent notifications to your APNs devices. If you are currently sending silent notifications to your APNs devices, they will not work with the legacy approach. Instead, we recommend using the FCM v1 payload to avoid unexpected issues. To find a list of APNs headers and what they are used for, see [Communicating with APNs](https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CommunicatingwithAPNs.html) in the *Apple Developer Guide*.
+ If you are using the `TTL` Amazon SNS attribute when sending your notification, it will only be updated in the `android` field. If you'd like to set the `TTL` APNS attribute, use the FCM v1 payload.
+ The `android`, `apns`, and `webpush` keys will be mapped and populated with all relevant keys provided. For example, if you provide `title`, which is a key shared among all three platforms, the FCM v1 mapping will populate all three platforms with the title you provided.
+ Some shared keys among platforms expect different value types. For example, the `badge` key passed to `apns` expects an integer value, while the `badge` key passed to `webpush` expects a String value. In cases where you provide the `badge` key, the FCM v1 mapping will only populate the key for which you provided a valid value.

## FCM delivery failure events


The following table provides the Amazon SNS failure type that corresponds to the error/status codes received from Google for FCM v1 notification requests. All observed error codes received from the FCM v1 API are available to you in CloudWatch when you set-up [delivery status logging](topics-attrib.md) for your application.


| FCM error/status code | Amazon SNS failure type | Failure message | Cause and mitigation | 
| --- | --- | --- | --- | 
|  `UNREGISTERED`  |  `InvalidPlatformToken`  |  Platform token associated with the endpoint is not valid.  |  The device token attached to your endpoint is stale or invalid. Amazon SNS disabled your endpoint. Update the Amazon SNS endpoint to the newest device token.  | 
|  `INVALID_ARGUMENT`  |  `InvalidNotification`  |  Notification body is invalid.  |  The device token or message payload may be invalid. Verify that your message payload is valid. If the message payload is valid, update the Amazon SNS endpoint to the newest device token.  | 
|  `SENDER_ID_MISMATCH`  |  `InvalidPlatformToken`  |  Platform token associated with the endpoint is not valid.  |  The platform application associated with the device token doesn't have permission to send to the device token. Verify that you are using the correct FCM credentials in your Amazon SNS platform application.  | 
|  `UNAVAILABLE`  |  `DependencyUnavailable`  |  Dependency is not available.  |  FCM couldn't process the request in time. All the retries executed by Amazon SNS have failed. You can store these messages in a dead-letter queue (DLQ) and redrive them later.  | 
|  `INTERNAL`  |  `UnexpectedFailure`  |  Unexpected failure; please contact Amazon. Failure phrase [Internal Error].  |  The FCM server encountered an error while trying to process your request. All the retries executed by Amazon SNS have failed. You can store these messages in a dead-letter queue (DLQ) and redrive them later.  | 
|  `THIRD_PARTY_AUTH_ERROR`  |  `InvalidCredentials`  |  Platform application credentials are not valid.  |  A message targeted to an iOS device or a Webpush device could not be sent. Verify that your development and production credentials are valid.  | 
|  `QUOTA_EXCEEDED`  |  `Throttled`  |  Request throttled by [gcm].  |  A message rate quota, device message rate quota, or topic message rate quota has been exceeded. For information on how to resolve this issue, see [ErrorCode](https://firebase.google.com/docs/reference/fcm/rest/v1/ErrorCode) in the in Google's *Firebase* documentation.  | 
|  `PERMISSION_DENIED`  |  `InvalidNotification`  |  Notification body is invalid.  |  In the case of a `PERMISSION_DENIED` exception, the caller (your FCM application) doesn't have permission to execute the specified operation in the payload. Navigate to your FCM console, and verify your credentials have the required API actions enabled.  | 

# Amazon SNS mobile app attributes
Mobile app attributes

Amazon Simple Notification Service (Amazon SNS) provides support to log the delivery status of push notification messages. After you configure application attributes, log entries will be sent to CloudWatch Logs for messages sent from Amazon SNS to mobile endpoints. Logging message delivery status helps provide better operational insight, such as the following: 
+ Know whether a push notification message was delivered from Amazon SNS to the push notification service.
+ Identify the response sent from the push notification service to Amazon SNS.
+ Determine the message dwell time (the time between the publish timestamp and just before handing off to a push notification service).

 To configure application attributes for message delivery status, you can use the AWS Management Console, AWS software development kits (SDKs), or query API. 

## Configuring message delivery status attributes using the AWS Management Console


1. Sign in to the [Amazon SNS console](https://console.aws.amazon.com/sns/home).

1. On the navigation panel, point to **Mobile**, and then choose **Push notifications**.

1. From the **Platform applications** section, choose the application that contains the endpoints for which you want receive CloudWatch Logs.

1. Choose **Application Actions** and then choose **Delivery Status**.

1. On the **Delivery Status** dialog box, choose **Create IAM Roles**.

   You will then be redirected to the IAM console.

1. Choose **Allow** to give Amazon SNS write access to use CloudWatch Logs on your behalf.

1. Now, back on the **Delivery Status** dialog box, enter a number in the **Percentage of Success to Sample (0-100)** field for the percentage of successful messages sent for which you want to receive CloudWatch Logs.
**Note**  
After you configure application attributes for message delivery status, all failed message deliveries generate CloudWatch Logs.

1. Finally, choose **Save Configuration**. You will now be able to view and parse the CloudWatch Logs containing the message delivery status. For more information about using CloudWatch, see the [CloudWatch Documentation](https://aws.amazon.com/documentation/cloudwatch).

## Amazon SNS message delivery status CloudWatch log examples


After you configure message delivery status attributes for an application endpoint, CloudWatch Logs will be generated. Example logs, in JSON format, are shown as follows:

**SUCCESS**

```
{
  "status": "SUCCESS",
  "notification": {
    "timestamp": "2015-01-26 23:07:39.54",
    "messageId": "9655abe4-6ed6-5734-89f7-e6a6a42de02a"
  },
  "delivery": {
    "statusCode": 200,
    "dwellTimeMs": 65,
    "token": "Examplei7fFachkJ1xjlqT64RaBkcGHochmf1VQAr9k-IBJtKjp7fedYPzEwT_Pq3Tu0lroqro1cwWJUvgkcPPYcaXCpPWmG3Bqn-wiqIEzp5zZ7y_jsM0PKPxKhddCzx6paEsyay9Zn3D4wNUJb8m6HXrBf9dqaEw",
    "attempts": 1,
    "providerResponse": "{\"multicast_id\":5138139752481671853,\"success\":1,\"failure\":0,\"canonical_ids\":0,\"results\":[{\"message_id\":\"0:1422313659698010%d6ba8edff9fd7ecd\"}]}",
    "destination": "arn:aws:sns:us-east-2:111122223333:endpoint/FCM/FCMPushApp/c23e42de-3699-3639-84dd-65f84474629d"
  }
}
```

**FAILURE**

```
{
  "status": "FAILURE",
  "notification": {
    "timestamp": "2015-01-26 23:29:35.678",
    "messageId": "c3ad79b0-8996-550a-8bfa-24f05989898f"
  },
  "delivery": {
    "statusCode": 8,
    "dwellTimeMs": 1451,
    "token": "examp1e29z6j5c4df46f80189c4c83fjcgf7f6257e98542d2jt3395kj73",
    "attempts": 1,
    "providerResponse": "NotificationErrorResponse(command=8, status=InvalidToken, id=1, cause=null)",
    "destination": "arn:aws:sns:us-east-2:111122223333:endpoint/APNS_SANDBOX/APNSPushApp/986cb8a1-4f6b-34b1-9a1b-d9e9cb553944"
  }
}
```

For a list of push notification service response codes, see [Platform response codes](#platform-returncodes).

## Configuring message delivery status attributes with the AWS SDKs


The [AWS SDKs](https://aws.amazon.com/tools/) provide APIs in several languages for using message delivery status attributes with Amazon SNS. 

The following Java example shows how to use the `SetPlatformApplicationAttributes` API to configure application attributes for message delivery status of push notification messages. You can use the following attributes for message delivery status: `SuccessFeedbackRoleArn`, `FailureFeedbackRoleArn`, and `SuccessFeedbackSampleRate`. The `SuccessFeedbackRoleArn` and `FailureFeedbackRoleArn` attributes are used to give Amazon SNS write access to use CloudWatch Logs on your behalf. The `SuccessFeedbackSampleRate` attribute is for specifying the sample rate percentage (0-100) of successfully delivered messages. After you configure the `FailureFeedbackRoleArn` attribute, then all failed message deliveries generate CloudWatch Logs. 

```
SetPlatformApplicationAttributesRequest setPlatformApplicationAttributesRequest = new SetPlatformApplicationAttributesRequest();
Map<String, String> attributes = new HashMap<>();
attributes.put("SuccessFeedbackRoleArn", "arn:aws:iam::111122223333:role/SNS_CWlogs");
attributes.put("FailureFeedbackRoleArn", "arn:aws:iam::111122223333:role/SNS_CWlogs");
attributes.put("SuccessFeedbackSampleRate", "5");
setPlatformApplicationAttributesRequest.withAttributes(attributes);
setPlatformApplicationAttributesRequest.setPlatformApplicationArn("arn:aws:sns:us-west-2:111122223333:app/FCM/FCMPushApp");
sns.setPlatformApplicationAttributes(setPlatformApplicationAttributesRequest);
```

For more information about the SDK for Java, see [Getting Started with the AWS SDK for Java](https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html).

## Platform response codes


The following is a list of links for the push notification service response codes:


****  

| Push notification service | Response codes | 
| --- | --- | 
| Amazon Device Messaging (ADM) | See [Response Format](https://developer.amazon.com/docs/adm/send-message.html#response-format) in the ADM documentation. | 
| Apple Push Notification Service (APNs) | See HTTP/2 Response from APNs in [Communicating with APNs](https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CommunicatingwithAPNs.html#/apple_ref/doc/uid/TP40008194-CH11-SW1) in the Local and Remote Notification Programming Guide. | 
| Firebase Cloud Messaging (FCM) | See [Downstream Message Error Response Codes](https://firebase.google.com/docs/cloud-messaging/http-server-ref#error-codes) in the Firebase Cloud Messaging documentation. | 
| Microsoft Push Notification Service for Windows Phone (MPNS) | See [Push Notification Service Response Codes for Windows Phone 8](https://msdn.microsoft.com/en-us/library/windows/apps/ff941100%28v=vs.105%29.aspx#BKMK_PushNotificationServiceResponseCodes) in the Windows 8 Development documentation. | 
| Windows Push Notification Services (WNS) | See "Response codes" in [Push Notification Service Request and Response Headers (Windows Runtime Apps)](https://msdn.microsoft.com/en-us/library/windows/apps/hh465435.aspx) in the Windows 8 Development documentation. | 

# Amazon SNS application event notifications for mobile applications
Mobile app events

Amazon SNS provides support to trigger notifications when certain application events occur. You can then take some programmatic action on that event. Your application must include support for a push notification service such as Apple Push Notification Service (APNs), Firebase Cloud Messaging (FCM), and Windows Push Notification Services (WNS). You set application event notifications using the Amazon SNS console, AWS CLI, or the AWS SDKs.

## Available application events


Application event notifications track when individual platform endpoints are created, deleted, and updated, as well as delivery failures. The following are the attribute names for the application events.


| Attribute name | Notification trigger | 
| --- | --- | 
| EventEndpointCreated | A new platform endpoint is added to your application. | 
| EventEndpointDeleted | Any platform endpoint associated with your application is deleted. | 
| EventEndpointUpdated | Any of the attributes of the platform endpoints associated with your application are changed. | 
| EventDeliveryFailure | A delivery to any of the platform endpoints associated with your application encounters a permanent failure.  To track delivery failures on the platform application side, subscribe to message delivery status events for the application. For more information, see [Using Amazon SNS Application Attributes for Message Delivery Status](https://docs.aws.amazon.com/sns/latest/dg/sns-msg-status.html).  | 

You can associate any attribute with an application which can then receive these event notifications. 

## Sending mobile push notifications


To send application event notifications, you specify a topic to receive the notifications for each type of event. As Amazon SNS sends the notifications, the topic can route them to endpoints that will take programmatic action.

**Important**  
High-volume applications will create a large number of application event notifications (for example, tens of thousands), which will overwhelm endpoints meant for human use, such as email addresses, phone numbers, and mobile applications. Consider the following guidelines when you send application event notifications to a topic:  
Each topic that receives notifications should contain only subscriptions for programmatic endpoints, such as HTTP or HTTPS endpoints, Amazon SQS queues, or AWS Lambda functions.
To reduce the amount of processing that is triggered by the notifications, limit each topic's subscriptions to a small number (for example, five or fewer).

You can send application event notifications using the Amazon SNS console, the AWS Command Line Interface (AWS CLI), or the AWS SDKs. 

### AWS Management Console


1. Sign in to the [Amazon SNS console](https://console.aws.amazon.com/sns/home).

1. On the navigation panel, choose **Mobile**, **Push notifications**.

1. On the **Mobile push notifications** page, in the **Platform applications** section, choose an application and then choose **Edit**.

1. Expand the **Event notifications** section.

1. Choose **Actions**, **Configure events**.

1. Enter the ARNs for topics to be used for the following events:
   + Endpoint Created
   + Endpoint Deleted
   + Endpoint Updated
   + Delivery Failure

1. Choose **Save changes**.

### AWS CLI


Run the [set-platform-application-attributes](https://docs.aws.amazon.com/cli/latest/reference/sns/set-platform-application-attributes.html) command.

The following example sets the same Amazon SNS topic for all four application events:

```
aws sns set-platform-application-attributes
--platform-application-arn arn:aws:sns:us-east-1:12345EXAMPLE:app/FCM/MyFCMPlatformApplication
--attributes EventEndpointCreated="arn:aws:sns:us-east-1:12345EXAMPLE:MyFCMPlatformApplicationEvents",
EventEndpointDeleted="arn:aws:sns:us-east-1:12345EXAMPLE:MyFCMPlatformApplicationEvents",
EventEndpointUpdated="arn:aws:sns:us-east-1:12345EXAMPLE:MyFCMPlatformApplicationEvents",
EventDeliveryFailure="arn:aws:sns:us-east-1:12345EXAMPLE:MyFCMPlatformApplicationEvents"
```

### AWS SDKs


Set application event notifications by submitting a `SetPlatformApplicationAttributes` request with the Amazon SNS API using an AWS SDK.

For a complete list of AWS SDK developer guides and code examples, including help getting started and information about previous versions, see [Using Amazon SNS with an AWS SDK](sdk-general-information-section.md).

# Mobile push API actions
Mobile push API actions

To use the Amazon SNS mobile push APIs, you must first meet the prerequisites for the push notification service, such as Apple Push Notification Service (APNs) and Firebase Cloud Messaging (FCM). For more information about the prerequisites, see [Prerequisites for Amazon SNS user notifications](sns-prerequisites-for-mobile-push-notifications.md). 

 To send a push notification message to a mobile app and device using the APIs, you must first use the `CreatePlatformApplication` action, which returns a `PlatformApplicationArn` attribute. The `PlatformApplicationArn` attribute is then used by `CreatePlatformEndpoint`, which returns an `EndpointArn` attribute. You can then use the `EndpointArn` attribute with the `Publish` action to send a notification message to a mobile app and device, or you could use the `EndpointArn` attribute with the `Subscribe` action for subscription to a topic. For more information, see [Setting up push notifications with Amazon SNS](sns-mobile-application-as-subscriber.md#sns-user-notifications-process-overview).

The Amazon SNS mobile push APIs are as follows: 

`[CreatePlatformApplication](https://docs.aws.amazon.com/sns/latest/api/API_CreatePlatformApplication.html)`  
Creates a platform application object for one of the supported push notification services, such as APNs and FCM, to which devices and mobile apps may register. Returns a `PlatformApplicationArn` attribute, which is used by the `CreatePlatformEndpoint` action.

`[CreatePlatformEndpoint](https://docs.aws.amazon.com/sns/latest/api/API_CreatePlatformEndpoint.html)`  
Creates an endpoint for a device and mobile app on one of the supported push notification services. `CreatePlatformEndpoint` uses the `PlatformApplicationArn` attribute returned from the `CreatePlatformApplication` action. The `EndpointArn` attribute, which is returned when using `CreatePlatformEndpoint`, is then used with the `Publish` action to send a notification message to a mobile app and device. 

`[CreateTopic](https://docs.aws.amazon.com/sns/latest/api/API_CreateTopic.html)`  
Creates a topic to which messages can be published. 

`[DeleteEndpoint](https://docs.aws.amazon.com/sns/latest/api/API_DeleteEndpoint.html)`  
Deletes the endpoint for a device and mobile app on one of the supported push notification services.

`[DeletePlatformApplication](https://docs.aws.amazon.com/sns/latest/api/API_DeletePlatformApplication.html)`  
Deletes a platform application object.

`[DeleteTopic](https://docs.aws.amazon.com/sns/latest/api/API_DeleteTopic.html)`  
Deletes a topic and all its subscriptions.

`[GetEndpointAttributes](https://docs.aws.amazon.com/sns/latest/api/API_GetEndpointAttributes.html)`  
Retrieves the endpoint attributes for a device and mobile app.

`[GetPlatformApplicationAttributes](https://docs.aws.amazon.com/sns/latest/api/API_GetPlatformApplicationAttributes.html)`  
Retrieves the attributes of the platform application object.

`[ListEndpointsByPlatformApplication](https://docs.aws.amazon.com/sns/latest/api/API_ListEndpointsByPlatformApplication.html)`  
Lists the endpoints and endpoint attributes for devices and mobile apps in a supported push notification service.

`[ListPlatformApplications](https://docs.aws.amazon.com/sns/latest/api/API_ListPlatformApplications.html)`  
Lists the platform application objects for the supported push notification services.

`[Publish](https://docs.aws.amazon.com/sns/latest/api/API_Publish.html)`  
Sends a notification message to all of a topic's subscribed endpoints.

`[SetEndpointAttributes](https://docs.aws.amazon.com/sns/latest/api/API_SetEndpointAttributes.html)`  
Sets the attributes for an endpoint for a device and mobile app.

`[SetPlatformApplicationAttributes](https://docs.aws.amazon.com/sns/latest/api/API_SetPlatformApplicationAttributes.html)`  
Sets the attributes of the platform application object.

`[Subscribe](https://docs.aws.amazon.com/sns/latest/api/API_Subscribe.html)`  
Prepares to subscribe an endpoint by sending the endpoint a confirmation message. To actually create a subscription, the endpoint owner must call the ConfirmSubscription action with the token from the confirmation message. 

`[Unsubscribe](https://docs.aws.amazon.com/sns/latest/api/API_Unsubscribe.html)`  
Deletes a subscription.

# Common Amazon SNS mobile push API errors
Common mobile push API errors

Errors that are returned by the Amazon SNS APIs for mobile push are listed in the following table. For more information about the Amazon SNS APIs for mobile push, see [Mobile push API actions](mobile-push-api.md).


| Error | Description | HTTPS status code | API Action | 
| --- | --- | --- | --- | 
| Application Name is null string | The required application name is set to null. | 400 | `CreatePlatformApplication` | 
| Platform Name is null string | The required platform name is set to null. | 400 | `CreatePlatformApplication` | 
| Platform Name is invalid | An invalid or out-of-range value was supplied for the platform name. | 400 | `CreatePlatformApplication` | 
| APNs — Principal is not a valid certificate | An invalid certificate was supplied for the APNs principal, which is the SSL certificate. For more information, see [CreatePlatformApplication](https://docs.aws.amazon.com/sns/latest/api/API_CreatePlatformApplication.html) in the Amazon Simple Notification Service API Reference. | 400 | `CreatePlatformApplication` | 
| APNs — Principal is a valid cert but not in a .pem format | A valid certificate that is not in the .pem format was supplied for the APNs principal, which is the SSL certificate. | 400 | `CreatePlatformApplication` | 
| APNs — Principal is an expired certificate | An expired certificate was supplied for the APNs principal, which is the SSL certificate. | 400 | `CreatePlatformApplication` | 
| APNs — Principal is not an Apple issued certificate | A non-Apple issued certificate was supplied for the APNs principal, which is the SSL certificate. | 400 | `CreatePlatformApplication` | 
| APNs — Principal is not provided | The APNs principal, which is the SSL certificate, was not provided. | 400 | `CreatePlatformApplication` | 
| APNs — Credential is not provided | The APNs credential, which is the private key, was not provided. For more information, see [CreatePlatformApplication](https://docs.aws.amazon.com/sns/latest/api/API_CreatePlatformApplication.html) in the Amazon Simple Notification Service API Reference. | 400 | `CreatePlatformApplication` | 
| APNs — Credential are not in a valid .pem format | The APNs credential, which is the private key, is not in a valid .pem format. | 400 | `CreatePlatformApplication` | 
| FCM — serverAPIKey is not provided | The FCM credential, which is the API key, was not provided. For more information, see [CreatePlatformApplication](https://docs.aws.amazon.com/sns/latest/api/API_CreatePlatformApplication.html) in the Amazon Simple Notification Service API Reference. | 400 | `CreatePlatformApplication` | 
| FCM — serverAPIKey is empty | The FCM credential, which is the API key, is empty. | 400 | `CreatePlatformApplication` | 
| FCM — serverAPIKey is a null string | The FCM credential, which is the API key, is null. | 400 | `CreatePlatformApplication` | 
| FCM — serverAPIKey is invalid | The FCM credential, which is the API key, is invalid. | 400 | `CreatePlatformApplication` | 
| ADM — clientsecret is not provided | The required client secret is not provided. | 400 | `CreatePlatformApplication` | 
| ADM — clientsecret is a null string | The required string for the client secret is null. | 400 | `CreatePlatformApplication` | 
| ADM — client\$1secret is empty string | The required string for the client secret is empty. | 400 | `CreatePlatformApplication` | 
| ADM — client\$1secret is not valid | The required string for the client secret is not valid. | 400 | `CreatePlatformApplication` | 
| ADM — client\$1id is empty string | The required string for the client ID is empty. | 400 | `CreatePlatformApplication` | 
| ADM — clientId is not provided | The required string for the client ID is not provided. | 400 | `CreatePlatformApplication` | 
| ADM — clientid is a null string | The required string for the client ID is null. | 400 | `CreatePlatformApplication` | 
| ADM — client\$1id is not valid | The required string for the client ID is not valid. | 400 | `CreatePlatformApplication` | 
| EventEndpointCreated has invalid ARN format | EventEndpointCreated has invalid ARN format. | 400 | `CreatePlatformApplication` | 
| EventEndpointDeleted has invalid ARN format | EventEndpointDeleted has invalid ARN format. | 400 | `CreatePlatformApplication` | 
| EventEndpointUpdated has invalid ARN format | EventEndpointUpdated has invalid ARN format. | 400 | `CreatePlatformApplication` | 
| EventDeliveryAttemptFailure has invalid ARN format | EventDeliveryAttemptFailure has invalid ARN format. | 400 | `CreatePlatformApplication` | 
| EventDeliveryFailure has invalid ARN format | EventDeliveryFailure has invalid ARN format. | 400 | `CreatePlatformApplication` | 
| EventEndpointCreated is not an existing Topic | EventEndpointCreated is not an existing topic. | 400 | `CreatePlatformApplication` | 
| EventEndpointDeleted is not an existing Topic | EventEndpointDeleted is not an existing topic. | 400 | `CreatePlatformApplication` | 
| EventEndpointUpdated is not an existing Topic | EventEndpointUpdated is not an existing topic. | 400 | `CreatePlatformApplication` | 
| EventDeliveryAttemptFailure is not an existing Topic | EventDeliveryAttemptFailure is not an existing topic. | 400 | `CreatePlatformApplication` | 
| EventDeliveryFailure is not an existing Topic | EventDeliveryFailure is not an existing topic. | 400 | `CreatePlatformApplication` | 
| Platform ARN is invalid | Platform ARN is invalid. | 400 | `SetPlatformAttributes` | 
| Platform ARN is valid but does not belong to the user | Platform ARN is valid but does not belong to the user. | 400 | `SetPlatformAttributes` | 
| APNs — Principal is not a valid certificate | An invalid certificate was supplied for the APNs principal, which is the SSL certificate. For more information, see [CreatePlatformApplication](https://docs.aws.amazon.com/sns/latest/api/API_CreatePlatformApplication.html) in the Amazon Simple Notification Service API Reference. | 400 | `SetPlatformAttributes` | 
| APNs — Principal is a valid cert but not in a .pem format | A valid certificate that is not in the .pem format was supplied for the APNs principal, which is the SSL certificate. | 400 | `SetPlatformAttributes` | 
| APNs — Principal is an expired certificate | An expired certificate was supplied for the APNs principal, which is the SSL certificate. | 400 | `SetPlatformAttributes` | 
| APNs — Principal is not an Apple issued certificate | A non-Apple issued certificate was supplied for the APNs principal, which is the SSL certificate. | 400 | `SetPlatformAttributes` | 
| APNs — Principal is not provided | The APNs principal, which is the SSL certificate, was not provided. | 400 | `SetPlatformAttributes` | 
| APNs — Credential is not provided | The APNs credential, which is the private key, was not provided. For more information, see [CreatePlatformApplication](https://docs.aws.amazon.com/sns/latest/api/API_CreatePlatformApplication.html) in the Amazon Simple Notification Service API Reference. | 400 | `SetPlatformAttributes` | 
| APNs — Credential are not in a valid .pem format | The APNs credential, which is the private key, is not in a valid .pem format. | 400 | `SetPlatformAttributes` | 
| FCM — serverAPIKey is not provided | The FCM credential, which is the API key, was not provided. For more information, see [CreatePlatformApplication](https://docs.aws.amazon.com/sns/latest/api/API_CreatePlatformApplication.html) in the Amazon Simple Notification Service API Reference. | 400 | `SetPlatformAttributes` | 
| FCM — serverAPIKey is a null string | The FCM credential, which is the API key, is null. | 400 | `SetPlatformAttributes` | 
| ADM — clientId is not provided | The required string for the client ID is not provided. | 400 | `SetPlatformAttributes` | 
| ADM — clientid is a null string | The required string for the client ID is null. | 400 | `SetPlatformAttributes` | 
| ADM — clientsecret is not provided | The required client secret is not provided. | 400 | `SetPlatformAttributes` | 
| ADM — clientsecret is a null string | The required string for the client secret is null. | 400 | `SetPlatformAttributes` | 
| EventEndpointUpdated has invalid ARN format | EventEndpointUpdated has invalid ARN format. | 400 | `SetPlatformAttributes` | 
| EventEndpointDeleted has invalid ARN format | EventEndpointDeleted has invalid ARN format. | 400 | `SetPlatformAttributes` | 
| EventEndpointUpdated has invalid ARN format | EventEndpointUpdated has invalid ARN format. | 400 | `SetPlatformAttributes` | 
| EventDeliveryAttemptFailure has invalid ARN format | EventDeliveryAttemptFailure has invalid ARN format. | 400 | `SetPlatformAttributes` | 
| EventDeliveryFailure has invalid ARN format | EventDeliveryFailure has invalid ARN format. | 400 | `SetPlatformAttributes` | 
| EventEndpointCreated is not an existing Topic | EventEndpointCreated is not an existing topic. | 400 | `SetPlatformAttributes` | 
| EventEndpointDeleted is not an existing Topic | EventEndpointDeleted is not an existing topic. | 400 | `SetPlatformAttributes` | 
| EventEndpointUpdated is not an existing Topic | EventEndpointUpdated is not an existing topic. | 400 | `SetPlatformAttributes` | 
| EventDeliveryAttemptFailure is not an existing Topic | EventDeliveryAttemptFailure is not an existing topic. | 400 | `SetPlatformAttributes` | 
| EventDeliveryFailure is not an existing Topic | EventDeliveryFailure is not an existing topic. | 400 | `SetPlatformAttributes` | 
| Platform ARN is invalid | The platform ARN is invalid. | 400 | `GetPlatformApplicationAttributes` | 
| Platform ARN is valid but does not belong to the user | The platform ARN is valid, but does not belong to the user. | 403 | `GetPlatformApplicationAttributes` | 
| Token specified is invalid | The specified token is invalid. | 400 | `ListPlatformApplications` | 
| Platform ARN is invalid | The platform ARN is invalid. | 400 | `ListEndpointsByPlatformApplication` | 
| Platform ARN is valid but does not belong to the user | The platform ARN is valid, but does not belong to the user. | 404 | `ListEndpointsByPlatformApplication` | 
| Token specified is invalid | The specified token is invalid. | 400 | `ListEndpointsByPlatformApplication` | 
| Platform ARN is invalid | The platform ARN is invalid. | 400 | `DeletePlatformApplication` | 
| Platform ARN is valid but does not belong to the user | The platform ARN is valid, but does not belong to the user. | 403 | `DeletePlatformApplication` | 
| Platform ARN is invalid | The platform ARN is invalid. | 400 | `CreatePlatformEndpoint` | 
| Platform ARN is valid but does not belong to the user | The platform ARN is valid, but does not belong to the user. | 404 | `CreatePlatformEndpoint` | 
| Token is not specified | The token is not specified. | 400 | `CreatePlatformEndpoint` | 
| Token is not of correct length | The token is not the correct length. | 400 | `CreatePlatformEndpoint` | 
| Customer User data is too large | The customer user data cannot be more than 2048 bytes long in UTF-8 encoding. | 400 | `CreatePlatformEndpoint` | 
| Endpoint ARN is invalid | The endpoint ARN is invalid. | 400 | `DeleteEndpoint` | 
| Endpoint ARN is valid but does not belong to the user | The endpoint ARN is valid, but does not belong to the user. | 403 | `DeleteEndpoint` | 
| Endpoint ARN is invalid | The endpoint ARN is invalid. | 400 | `SetEndpointAttributes` | 
| Endpoint ARN is valid but does not belong to the user | The endpoint ARN is valid, but does not belong to the user. | 403 | `SetEndpointAttributes` | 
| Token is not specified | The token is not specified. | 400 | `SetEndpointAttributes` | 
| Token is not of correct length | The token is not the correct length. | 400 | `SetEndpointAttributes` | 
| Customer User data is too large | The customer user data cannot be more than 2048 bytes long in UTF-8 encoding. | 400 | `SetEndpointAttributes` | 
| Endpoint ARN is invalid | The endpoint ARN is invalid. | 400 | `GetEndpointAttributes` | 
| Endpoint ARN is valid but does not belong to the user | The endpoint ARN is valid, but does not belong to the user. | 403 | `GetEndpointAttributes` | 
| Target ARN is invalid | The target ARN is invalid. | 400 | `Publish` | 
| Target ARN is valid but does not belong to the user | The target ARN is valid, but does not belong to the user. | 403 | `Publish` | 
| Message format is invalid | The message format is invalid. | 400 | `Publish` | 
| Message size is larger than supported by protocol/end-service | The message size is larger than supported by the protocol/end-service. | 400 | `Publish` | 

# Using the Amazon SNS time to live message attribute for mobile push notifications
Mobile push TTL

Amazon Simple Notification Service (Amazon SNS) provides support for setting a *Time To Live (TTL)* message attribute for mobile push notifications messages. This is in addition to the existing capability of setting TTL within the Amazon SNS message body for the mobile push notification services that support this, such as Amazon Device Messaging (ADM) and Firebase Cloud Messaging (FCM) when sending to Android.

The TTL message attribute is used to specify expiration metadata about a message. This allows you to specify the amount of time that the push notification service, such as Apple Push Notification Service (APNs) or FCM, has to deliver the message to the endpoint. If for some reason (such as the mobile device has been turned off) the message is not deliverable within the specified TTL, then the message will be dropped and no further attempts to deliver it will be made. To specify TTL within message attributes, you can use the AWS Management Console, AWS software development kits (SDKs), or query API. 

## TTL message attributes for push notification services


The following is a list of the TTL message attributes for push notification services that you can use to set when using the AWS SDKs or query API:


****  

| Push notification service | TTL message attribute | 
| --- | --- | 
| Amazon Device Messaging (ADM) | AWS.SNS.MOBILE.ADM.TTL | 
| Apple Push Notification Service (APNs) | AWS.SNS.MOBILE.APNS.TTL | 
| Apple Push Notification Service Sandbox (APNs\$1SANDBOX) | AWS.SNS.MOBILE.APNS\$1SANDBOX.TTL | 
| Baidu Cloud Push (Baidu) | AWS.SNS.MOBILE.BAIDU.TTL | 
| Firebase Cloud Messaging (FCM when sending to Android) | AWS.SNS.MOBILE.FCM.TTL | 
| Windows Push Notification Services (WNS) | AWS.SNS.MOBILE.WNS.TTL | 

Each of the push notification services handle TTL differently. Amazon SNS provides an abstract view of TTL over all the push notification services, which makes it easier to specify TTL. When you use the AWS Management Console to specify TTL (in seconds), you only have to enter the TTL value once and Amazon SNS will then calculate the TTL for each of the selected push notification services when publishing the message. 

 TTL is relative to the publish time. Before handing off a push notification message to a specific push notification service, Amazon SNS computes the dwell time (the time between the publish timestamp and just before handing off to a push notification service) for the push notification and passes the remaining TTL to the specific push notification service. If TTL is shorter than the dwell time, Amazon SNS won't attempt to publish. 

If you specify a TTL for a push notification message, then the TTL value must be a positive integer, unless the value of `0` has a specific meaning for the push notification service—such as with APNs and FCM (when sending to Android). If the TTL value is set to `0` and the push notification service does not have a specific meaning for `0`, then Amazon SNS will drop the message. For more information about the TTL parameter set to `0` when using APNs, see *Table A-3 Item identifiers for remote notifications* in the [Binary Provider API](https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/BinaryProviderAPI.html) documentation.

## Precedence order for determining TTL


The precedence that Amazon SNS uses to determine the TTL for a push notification message is based on the following order, where the lowest number has the highest priority: 

1. Message attribute TTL

1. Message body TTL

1. Push notification service default TTL (varies per service)

1. Amazon SNS default TTL (4 weeks)

If you set different TTL values (one in message attributes and another in the message body) for the same message, then Amazon SNS will modify the TTL in the message body to match the TTL specified in the message attribute.

## Specifying TTL using the AWS Management Console


1. Sign in to the [Amazon SNS console](https://console.aws.amazon.com/sns/home).

1. On the navigation panel, choose **Mobile**, **Push notifications**.

1. On the **Mobile push notifications** page, in the **Platform applications** section, choose an application.

1. On the ***MyApplication*** page, in the **Endpoints** section, choose an application endpoint and then choose **Publish message**.

1. In the **Message details** section, enter the TTL (the number of seconds that the push notification service has to deliver the message to the endpoint).

1. Choose **Publish message**.

# Amazon SNS mobile application supported Regions
Supported Regions

Currently, you can create mobile applications in the following Regions:
+ US East (Ohio)
+ US East (N. Virginia)
+ US West (N. California)
+ US West (Oregon)
+ Africa (Cape Town)
+ Asia Pacific (Hong Kong)
+ Asia Pacific (Jakarta)
+ Asia Pacific (Mumbai)
+ Asia Pacific (Osaka)
+ Asia Pacific (Seoul)
+ Asia Pacific (Singapore)
+ Asia Pacific (Sydney)
+ Asia Pacific (Tokyo)
+ Canada (Central)
+ Europe (Frankfurt)
+ Europe (Ireland)
+ Europe (London)
+ Europe (Milan)
+ Europe (Spain)
+ Europe (Paris)
+ Europe (Stockholm)
+ Middle East (Bahrain)
+ Middle East (UAE)
+ South America (São Paulo)
+ AWS GovCloud (US-West)

# Best practices for managing Amazon SNS mobile push notifications
Best practices for mobile push notifications

This section describes best practices that might help you improve your customer engagement.

## Endpoint management


Delivery issues might occur in situations were device tokens change due to a user’s action on the device (for example, an app is re-installed on the device), or [certificate updates](https://developer.apple.com/documentation/usernotifications/setting_up_a_remote_notification_server/establishing_a_certificate-based_connection_to_apns) affecting devices running on a particular iOS version. It is a recommended best practice by Apple to [register](https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/HandlingRemoteNotifications.html#:~:text=Registering%20to%20Receive%20Remote%20Notifications) with APNs each time your app launches.

Since the device token won’t change each time an app is opened by a user, the idempotent [https://docs.aws.amazon.com/sns/latest/api/API_CreatePlatformEndpoint.html](https://docs.aws.amazon.com/sns/latest/api/API_CreatePlatformEndpoint.html) API can be used. However, this can introduce duplicates for the same device in cases where the token itself is invalid, or if the endpoint is valid but disabled (for example, a mismatch of production and sandbox environments).

A device token management mechanism such as the one in the [pseudo code](mobile-platform-endpoint.md#mobile-platform-endpoint-pseudo-code) can be used.

For information on managing and maintaining FCM v1 device tokens, see [Amazon SNS management of Firebase Cloud Messaging endpoints](sns-fcm-endpoint-management.md).

## Delivery status logging


To monitor push notification delivery status, we recommended you enable delivery status logging for your Amazon SNS platform application. This helps you troubleshoot delivery failures because the logs contain provider [response codes](sns-msg-status.md#platform-returncodes) returned from the push platform service. For details on enabling delivery status logging, see [How do I access Amazon SNS topic delivery logs for push notifications?](https://aws.amazon.com/premiumsupport/knowledge-center/troubleshoot-failed-sns-deliveries/).

## Event notifications


For managing endpoints in an event driven fashion, you can make use of the [event notifications](application-event-notifications.md#application-event-notifications-sdk) functionality. This allows the configured Amazon SNS topic to fanout events to the subscribers such as a Lambda function, for platform application events of endpoint creation, deletion, updates, and delivery failures.

# Amazon SNS email subscription setup and management
Email subscription setup and management

You can subscribe an [email address](#sns-email-notifications) to an Amazon SNS topic using the AWS Management Console, AWS SDK for Java, or AWS SDK for .NET. 

**Notes**  
Customization of the email message body is not supported. The email delivery feature is intended to provide internal system alerts, not marketing messages.
Directly subscribing email endpoints is supported for standard topics only.
Email delivery throughput is throttled. For more information, see [Amazon SNS quotas](https://docs.aws.amazon.com/general/latest/gr/sns.html#limits_sns).

**Important**  
To prevent mailing list recipients from unsubscribing all recipients from Amazon SNS topic emails, see [Set up an email subscription that requires authentication to unsubscribe](https://aws.amazon.com/premiumsupport/knowledge-center/prevent-unsubscribe-all-sns-topic/) from AWS Support.
Exceeding the limit of 10 messages per second (TPS) for an email or email-json endpoint will trigger an automatic suspension of the subscription, placing it in a pending confirmation status. The subscription remains in PendingConfirmation state for 30 days, after which it will be automatically deleted unless action is taken.
If a subscribed email address results in a bounce, the address is suppressed from further deliveries for 7 days. Bounces can occur for various reasons, including invalid addresses or issues with the receiving email server. To remove the address from the suppression list before the 7-day period expires, resolve the underlying issue with the email address and then contact AWS using the Support Center.

## Subscribing an email address to an Amazon SNS topic using the AWS Management Console
AWS Management Console

1. Sign in to the [Amazon SNS console](https://console.aws.amazon.com/sns/home).

1. In the left navigation pane, choose **Subscriptions**.

1. On the **Subscriptions** page, choose **Create subscription**.

1. On the **Create subscription** page, in the **Details** section, do the following:

   1. For **Topic ARN**, choose the Amazon Resource Name (ARN) of a topic.

   1. For **Protocol**, choose **Email**.

   1. For **Endpoint**, enter the email address.

   1. (Optional) To configure a filter policy, expand the **Subscription filter policy** section. For more information, see [Amazon SNS subscription filter policies](sns-subscription-filter-policies.md).

   1. (Optional) To enable payload-based filtering, configure `Filter Policy Scope` to `MessageBody`. For more information, see [Amazon SNS subscription filter policy scope](sns-message-filtering-scope.md).

   1. (Optional) To configure a dead-letter queue for the subscription, expand the **Redrive policy (dead-letter queue)** section. For more information, see [Amazon SNS dead-letter queues](sns-dead-letter-queues.md).

   1. Choose **Create subscription**.

      The console creates the subscription and opens the subscription's **Details** page.

You must confirm the subscription before the email address can start to receive messages.

**To confirm a subscription**

1. Check your email inbox and choose **Confirm subscription** in the email from Amazon SNS.

1. Amazon SNS opens your web browser and displays a subscription confirmation with your subscription ID.

## Subscribing an email address to an Amazon SNS topic using an AWS SDK
AWS SDKs

To use an AWS SDK, you must configure it with your credentials. For more information, see [The shared config and credentials files](https://docs.aws.amazon.com/sdkref/latest/guide/creds-config-files.html) in the *AWS SDKs and Tools Reference Guide*.

The following code examples show how to use `Subscribe`.

------
#### [ .NET ]

**SDK for .NET**  
 There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/dotnetv3/SNS#code-examples). 
Subscribe an email address to a topic.  

```
        /// <summary>
        /// Creates a new subscription to a topic.
        /// </summary>
        /// <param name="client">The initialized Amazon SNS client object, used
        /// to create an Amazon SNS subscription.</param>
        /// <param name="topicArn">The ARN of the topic to subscribe to.</param>
        /// <returns>A SubscribeResponse object which includes the subscription
        /// ARN for the new subscription.</returns>
        public static async Task<SubscribeResponse> TopicSubscribeAsync(
            IAmazonSimpleNotificationService client,
            string topicArn)
        {
            SubscribeRequest request = new SubscribeRequest()
            {
                TopicArn = topicArn,
                ReturnSubscriptionArn = true,
                Protocol = "email",
                Endpoint = "recipient@example.com",
            };

            var response = await client.SubscribeAsync(request);

            return response;
        }
```
Subscribe a queue to a topic with optional filters.  

```
    /// <summary>
    /// Subscribe a queue to a topic with optional filters.
    /// </summary>
    /// <param name="topicArn">The ARN of the topic.</param>
    /// <param name="useFifoTopic">The optional filtering policy for the subscription.</param>
    /// <param name="queueArn">The ARN of the queue.</param>
    /// <returns>The ARN of the new subscription.</returns>
    public async Task<string> SubscribeTopicWithFilter(string topicArn, string? filterPolicy, string queueArn)
    {
        var subscribeRequest = new SubscribeRequest()
        {
            TopicArn = topicArn,
            Protocol = "sqs",
            Endpoint = queueArn
        };

        if (!string.IsNullOrEmpty(filterPolicy))
        {
            subscribeRequest.Attributes = new Dictionary<string, string> { { "FilterPolicy", filterPolicy } };
        }

        var subscribeResponse = await _amazonSNSClient.SubscribeAsync(subscribeRequest);
        return subscribeResponse.SubscriptionArn;
    }
```
+  For API details, see [Subscribe](https://docs.aws.amazon.com/goto/DotNetSDKV3/sns-2010-03-31/Subscribe) in *AWS SDK for .NET API Reference*. 

------
#### [ C\$1\$1 ]

**SDK for C\$1\$1**  
 There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/cpp/example_code/sns#code-examples). 
Subscribe an email address to a topic.  

```
//! Subscribe to an Amazon Simple Notification Service (Amazon SNS) topic with delivery to an email address.
/*!
  \param topicARN: An SNS topic Amazon Resource Name (ARN).
  \param emailAddress: An email address.
  \param clientConfiguration: AWS client configuration.
  \return bool: Function succeeded.
 */
bool AwsDoc::SNS::subscribeEmail(const Aws::String &topicARN,
                                 const Aws::String &emailAddress,
                                 const Aws::Client::ClientConfiguration &clientConfiguration) {
    Aws::SNS::SNSClient snsClient(clientConfiguration);

    Aws::SNS::Model::SubscribeRequest request;
    request.SetTopicArn(topicARN);
    request.SetProtocol("email");
    request.SetEndpoint(emailAddress);

    const Aws::SNS::Model::SubscribeOutcome outcome = snsClient.Subscribe(request);

    if (outcome.IsSuccess()) {
        std::cout << "Subscribed successfully." << std::endl;
        std::cout << "Subscription ARN '" << outcome.GetResult().GetSubscriptionArn()
                  << "'." << std::endl;
    }
    else {
        std::cerr << "Error while subscribing " << outcome.GetError().GetMessage()
                  << std::endl;
    }

    return outcome.IsSuccess();
}
```
Subscribe a mobile application to a topic.  

```
//! Subscribe to an Amazon Simple Notification Service (Amazon SNS) topic with delivery to a mobile app.
/*!
  \param topicARN: The Amazon Resource Name (ARN) for an Amazon SNS topic.
  \param endpointARN: The ARN for a mobile app or device endpoint.
  \param clientConfiguration: AWS client configuration.
  \return bool: Function succeeded.
 */
bool
AwsDoc::SNS::subscribeApp(const Aws::String &topicARN,
                          const Aws::String &endpointARN,
                          const Aws::Client::ClientConfiguration &clientConfiguration) {
    Aws::SNS::SNSClient snsClient(clientConfiguration);

    Aws::SNS::Model::SubscribeRequest request;
    request.SetTopicArn(topicARN);
    request.SetProtocol("application");
    request.SetEndpoint(endpointARN);

    const Aws::SNS::Model::SubscribeOutcome outcome = snsClient.Subscribe(request);

    if (outcome.IsSuccess()) {
        std::cout << "Subscribed successfully." << std::endl;
        std::cout << "Subscription ARN '" << outcome.GetResult().GetSubscriptionArn()
                  << "'." << std::endl;
    }
    else {
        std::cerr << "Error while subscribing " << outcome.GetError().GetMessage()
                  << std::endl;
    }

    return outcome.IsSuccess();
}
```
Subscribe a Lambda function to a topic.  

```
//! Subscribe to an Amazon Simple Notification Service (Amazon SNS) topic with delivery to an AWS Lambda function.
/*!
  \param topicARN: The Amazon Resource Name (ARN) for an Amazon SNS topic.
  \param lambdaFunctionARN: The ARN for an AWS Lambda function.
  \param clientConfiguration: AWS client configuration.
  \return bool: Function succeeded.
 */
bool AwsDoc::SNS::subscribeLambda(const Aws::String &topicARN,
                                  const Aws::String &lambdaFunctionARN,
                                  const Aws::Client::ClientConfiguration &clientConfiguration) {
    Aws::SNS::SNSClient snsClient(clientConfiguration);

    Aws::SNS::Model::SubscribeRequest request;
    request.SetTopicArn(topicARN);
    request.SetProtocol("lambda");
    request.SetEndpoint(lambdaFunctionARN);

    const Aws::SNS::Model::SubscribeOutcome outcome = snsClient.Subscribe(request);

    if (outcome.IsSuccess()) {
        std::cout << "Subscribed successfully." << std::endl;
        std::cout << "Subscription ARN '" << outcome.GetResult().GetSubscriptionArn()
                  << "'." << std::endl;
    }
    else {
        std::cerr << "Error while subscribing " << outcome.GetError().GetMessage()
                  << std::endl;
    }

    return outcome.IsSuccess();
}
```
Subscribe an SQS queue to a topic.  

```
        Aws::Client::ClientConfiguration clientConfig;
        // Optional: Set to the AWS Region (overrides config file).
        // clientConfig.region = "us-east-1";

    Aws::SNS::SNSClient snsClient(clientConfiguration);

            Aws::SNS::Model::SubscribeRequest request;
            request.SetTopicArn(topicARN);
            request.SetProtocol("sqs");
            request.SetEndpoint(queueARN);

            Aws::SNS::Model::SubscribeOutcome outcome = snsClient.Subscribe(request);

            if (outcome.IsSuccess()) {
                Aws::String subscriptionARN = outcome.GetResult().GetSubscriptionArn();
                std::cout << "The queue '" << queueName
                          << "' has been subscribed to the topic '"
                          << "'" << topicName << "'" << std::endl;
                std::cout << "with the subscription ARN '" << subscriptionARN << "."
                          << std::endl;
                subscriptionARNS.push_back(subscriptionARN);
            }
            else {
                std::cerr << "Error with TopicsAndQueues::Subscribe. "
                          << outcome.GetError().GetMessage()
                          << std::endl;

                cleanUp(topicARN,
                        queueURLS,
                        subscriptionARNS,
                        snsClient,
                        sqsClient);

                return false;
            }
```
Subscribe with a filter to a topic.  

```
        static const Aws::String TONE_ATTRIBUTE("tone");
        static const Aws::Vector<Aws::String> TONES = {"cheerful", "funny", "serious",
                                                       "sincere"};

        Aws::Client::ClientConfiguration clientConfig;
        // Optional: Set to the AWS Region (overrides config file).
        // clientConfig.region = "us-east-1";

    Aws::SNS::SNSClient snsClient(clientConfiguration);

            Aws::SNS::Model::SubscribeRequest request;
            request.SetTopicArn(topicARN);
            request.SetProtocol("sqs");
            request.SetEndpoint(queueARN);
            if (isFifoTopic) {
                if (first) {
                    std::cout << "Subscriptions to a FIFO topic can have filters."
                              << std::endl;
                    std::cout
                            << "If you add a filter to this subscription, then only the filtered messages "
                            << "will be received in the queue." << std::endl;
                    std::cout << "For information about message filtering, "
                              << "see https://docs.aws.amazon.com/sns/latest/dg/sns-message-filtering.html"
                              << std::endl;
                    std::cout << "For this example, you can filter messages by a \""
                              << TONE_ATTRIBUTE << "\" attribute." << std::endl;
                }

                std::ostringstream ostringstream;
                ostringstream << "Filter messages for \"" << queueName
                              << "\"'s subscription to the topic \""
                              << topicName << "\"?  (y/n)";

                // Add filter if user answers yes.
                if (askYesNoQuestion(ostringstream.str())) {
                    Aws::String jsonPolicy = getFilterPolicyFromUser();
                    if (!jsonPolicy.empty()) {
                        filteringMessages = true;

                        std::cout << "This is the filter policy for this subscription."
                                  << std::endl;
                        std::cout << jsonPolicy << std::endl;

                        request.AddAttributes("FilterPolicy", jsonPolicy);
                    }
                    else {
                        std::cout
                                << "Because you did not select any attributes, no filter "
                                << "will be added to this subscription." << std::endl;
                    }
                }
            }  // if (isFifoTopic)
            Aws::SNS::Model::SubscribeOutcome outcome = snsClient.Subscribe(request);

            if (outcome.IsSuccess()) {
                Aws::String subscriptionARN = outcome.GetResult().GetSubscriptionArn();
                std::cout << "The queue '" << queueName
                          << "' has been subscribed to the topic '"
                          << "'" << topicName << "'" << std::endl;
                std::cout << "with the subscription ARN '" << subscriptionARN << "."
                          << std::endl;
                subscriptionARNS.push_back(subscriptionARN);
            }
            else {
                std::cerr << "Error with TopicsAndQueues::Subscribe. "
                          << outcome.GetError().GetMessage()
                          << std::endl;

                cleanUp(topicARN,
                        queueURLS,
                        subscriptionARNS,
                        snsClient,
                        sqsClient);

                return false;
            }

//! Routine that lets the user select attributes for a subscription filter policy.
/*!
 \sa getFilterPolicyFromUser()
 \return Aws::String: The filter policy as JSON.
 */
Aws::String AwsDoc::TopicsAndQueues::getFilterPolicyFromUser() {
    std::cout
            << "You can filter messages by one or more of the following \""
            << TONE_ATTRIBUTE << "\" attributes." << std::endl;

    std::vector<Aws::String> filterSelections;
    int selection;
    do {
        for (size_t j = 0; j < TONES.size(); ++j) {
            std::cout << "  " << (j + 1) << ". " << TONES[j]
                      << std::endl;
        }
        selection = askQuestionForIntRange(
                "Enter a number (or enter zero to stop adding more). ",
                0, static_cast<int>(TONES.size()));

        if (selection != 0) {
            const Aws::String &selectedTone(TONES[selection - 1]);
            // Add the tone to the selection if it is not already added.
            if (std::find(filterSelections.begin(),
                          filterSelections.end(),
                          selectedTone)
                == filterSelections.end()) {
                filterSelections.push_back(selectedTone);
            }
        }
    } while (selection != 0);

    Aws::String result;
    if (!filterSelections.empty()) {
        std::ostringstream jsonPolicyStream;
        jsonPolicyStream << "{ \"" << TONE_ATTRIBUTE << "\": [";


        for (size_t j = 0; j < filterSelections.size(); ++j) {
            jsonPolicyStream << "\"" << filterSelections[j] << "\"";
            if (j < filterSelections.size() - 1) {
                jsonPolicyStream << ",";
            }
        }
        jsonPolicyStream << "] }";

        result = jsonPolicyStream.str();
    }

    return result;
}
```
+  For API details, see [Subscribe](https://docs.aws.amazon.com/goto/SdkForCpp/sns-2010-03-31/Subscribe) in *AWS SDK for C\$1\$1 API Reference*. 

------
#### [ CLI ]

**AWS CLI**  
**To subscribe to a topic**  
The following `subscribe` command subscribes an email address to the specified topic.  

```
aws sns subscribe \
    --topic-arn arn:aws:sns:us-west-2:123456789012:my-topic \
    --protocol email \
    --notification-endpoint my-email@example.com
```
Output:  

```
{
    "SubscriptionArn": "pending confirmation"
}
```
+  For API details, see [Subscribe](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/sns/subscribe.html) in *AWS CLI Command Reference*. 

------
#### [ Go ]

**SDK for Go V2**  
 There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/gov2/workflows/topics_and_queues#code-examples). 
Subscribe a queue to a topic with optional filters.  

```
import (
	"context"
	"encoding/json"
	"log"

	"github.com/aws/aws-sdk-go-v2/aws"
	"github.com/aws/aws-sdk-go-v2/service/sns"
	"github.com/aws/aws-sdk-go-v2/service/sns/types"
)

// SnsActions encapsulates the Amazon Simple Notification Service (Amazon SNS) actions
// used in the examples.
type SnsActions struct {
	SnsClient *sns.Client
}



// SubscribeQueue subscribes an Amazon Simple Queue Service (Amazon SQS) queue to an
// Amazon SNS topic. When filterMap is not nil, it is used to specify a filter policy
// so that messages are only sent to the queue when the message has the specified attributes.
func (actor SnsActions) SubscribeQueue(ctx context.Context, topicArn string, queueArn string, filterMap map[string][]string) (string, error) {
	var subscriptionArn string
	var attributes map[string]string
	if filterMap != nil {
		filterBytes, err := json.Marshal(filterMap)
		if err != nil {
			log.Printf("Couldn't create filter policy, here's why: %v\n", err)
			return "", err
		}
		attributes = map[string]string{"FilterPolicy": string(filterBytes)}
	}
	output, err := actor.SnsClient.Subscribe(ctx, &sns.SubscribeInput{
		Protocol:              aws.String("sqs"),
		TopicArn:              aws.String(topicArn),
		Attributes:            attributes,
		Endpoint:              aws.String(queueArn),
		ReturnSubscriptionArn: true,
	})
	if err != nil {
		log.Printf("Couldn't susbscribe queue %v to topic %v. Here's why: %v\n",
			queueArn, topicArn, err)
	} else {
		subscriptionArn = *output.SubscriptionArn
	}

	return subscriptionArn, err
}
```
+  For API details, see [Subscribe](https://pkg.go.dev/github.com/aws/aws-sdk-go-v2/service/sns#Client.Subscribe) in *AWS SDK for Go API Reference*. 

------
#### [ Java ]

**SDK for Java 2.x**  
 There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/javav2/example_code/sns#code-examples). 
Subscribe an email address to a topic.  

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.sns.SnsClient;
import software.amazon.awssdk.services.sns.model.SnsException;
import software.amazon.awssdk.services.sns.model.SubscribeRequest;
import software.amazon.awssdk.services.sns.model.SubscribeResponse;

/**
 * Before running this Java V2 code example, set up your development
 * environment, including your credentials.
 *
 * For more information, see the following documentation topic:
 *
 * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
 */
public class SubscribeEmail {
    public static void main(String[] args) {
        final String usage = """
                Usage:     <topicArn> <email>

                Where:
                   topicArn - The ARN of the topic to subscribe.
                   email - The email address to use.
                """;

        if (args.length != 2) {
            System.out.println(usage);
            System.exit(1);
        }

        String topicArn = args[0];
        String email = args[1];
        SnsClient snsClient = SnsClient.builder()
                .region(Region.US_EAST_1)
                .build();

        subEmail(snsClient, topicArn, email);
        snsClient.close();
    }

    public static void subEmail(SnsClient snsClient, String topicArn, String email) {
        try {
            SubscribeRequest request = SubscribeRequest.builder()
                    .protocol("email")
                    .endpoint(email)
                    .returnSubscriptionArn(true)
                    .topicArn(topicArn)
                    .build();

            SubscribeResponse result = snsClient.subscribe(request);
            System.out.println("Subscription ARN: " + result.subscriptionArn() + "\n\n Status is "
                    + result.sdkHttpResponse().statusCode());

        } catch (SnsException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
    }
}
```
Subscribe an HTTP endpoint to a topic.  

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.sns.SnsClient;
import software.amazon.awssdk.services.sns.model.SnsException;
import software.amazon.awssdk.services.sns.model.SubscribeRequest;
import software.amazon.awssdk.services.sns.model.SubscribeResponse;

/**
 * Before running this Java V2 code example, set up your development
 * environment, including your credentials.
 *
 * For more information, see the following documentation topic:
 *
 * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
 */
public class SubscribeHTTPS {
    public static void main(String[] args) {
        final String usage = """

                Usage:    <topicArn> <url>

                Where:
                   topicArn - The ARN of the topic to subscribe.
                   url - The HTTPS endpoint that you want to receive notifications.
                """;

        if (args.length < 2) {
            System.out.println(usage);
            System.exit(1);
        }

        String topicArn = args[0];
        String url = args[1];
        SnsClient snsClient = SnsClient.builder()
                .region(Region.US_EAST_1)
                .build();

        subHTTPS(snsClient, topicArn, url);
        snsClient.close();
    }

    public static void subHTTPS(SnsClient snsClient, String topicArn, String url) {
        try {
            SubscribeRequest request = SubscribeRequest.builder()
                    .protocol("https")
                    .endpoint(url)
                    .returnSubscriptionArn(true)
                    .topicArn(topicArn)
                    .build();

            SubscribeResponse result = snsClient.subscribe(request);
            System.out.println("Subscription ARN is " + result.subscriptionArn() + "\n\n Status is "
                    + result.sdkHttpResponse().statusCode());

        } catch (SnsException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
    }
}
```
Subscribe a Lambda function to a topic.  

```
import software.amazon.awssdk.regions.Region;
import software.amazon.awssdk.services.sns.SnsClient;
import software.amazon.awssdk.services.sns.model.SnsException;
import software.amazon.awssdk.services.sns.model.SubscribeRequest;
import software.amazon.awssdk.services.sns.model.SubscribeResponse;

/**
 * Before running this Java V2 code example, set up your development
 * environment, including your credentials.
 *
 * For more information, see the following documentation topic:
 *
 * https://docs.aws.amazon.com/sdk-for-java/latest/developer-guide/get-started.html
 */
public class SubscribeLambda {

    public static void main(String[] args) {

        final String usage = """

                Usage:    <topicArn> <lambdaArn>

                Where:
                   topicArn - The ARN of the topic to subscribe.
                   lambdaArn - The ARN of an AWS Lambda function.
                """;

        if (args.length != 2) {
            System.out.println(usage);
            System.exit(1);
        }

        String topicArn = args[0];
        String lambdaArn = args[1];
        SnsClient snsClient = SnsClient.builder()
                .region(Region.US_EAST_1)
                .build();

        String arnValue = subLambda(snsClient, topicArn, lambdaArn);
        System.out.println("Subscription ARN: " + arnValue);
        snsClient.close();
    }

    public static String subLambda(SnsClient snsClient, String topicArn, String lambdaArn) {
        try {
            SubscribeRequest request = SubscribeRequest.builder()
                    .protocol("lambda")
                    .endpoint(lambdaArn)
                    .returnSubscriptionArn(true)
                    .topicArn(topicArn)
                    .build();

            SubscribeResponse result = snsClient.subscribe(request);
            return result.subscriptionArn();

        } catch (SnsException e) {
            System.err.println(e.awsErrorDetails().errorMessage());
            System.exit(1);
        }
        return "";
    }
}
```
+  For API details, see [Subscribe](https://docs.aws.amazon.com/goto/SdkForJavaV2/sns-2010-03-31/Subscribe) in *AWS SDK for Java 2.x API Reference*. 

------
#### [ JavaScript ]

**SDK for JavaScript (v3)**  
 There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/javascriptv3/example_code/sns#code-examples). 
Create the client in a separate module and export it.  

```
import { SNSClient } from "@aws-sdk/client-sns";

// The AWS Region can be provided here using the `region` property. If you leave it blank
// the SDK will default to the region set in your AWS config.
export const snsClient = new SNSClient({});
```
Import the SDK and client modules and call the API.  

```
import { SubscribeCommand } from "@aws-sdk/client-sns";
import { snsClient } from "../libs/snsClient.js";

/**
 * @param {string} topicArn - The ARN of the topic for which you wish to confirm a subscription.
 * @param {string} emailAddress - The email address that is subscribed to the topic.
 */
export const subscribeEmail = async (
  topicArn = "TOPIC_ARN",
  emailAddress = "usern@me.com",
) => {
  const response = await snsClient.send(
    new SubscribeCommand({
      Protocol: "email",
      TopicArn: topicArn,
      Endpoint: emailAddress,
    }),
  );
  console.log(response);
  // {
  //   '$metadata': {
  //     httpStatusCode: 200,
  //     requestId: 'c8e35bcd-b3c0-5940-9f66-06f6fcc108f0',
  //     extendedRequestId: undefined,
  //     cfId: undefined,
  //     attempts: 1,
  //     totalRetryDelay: 0
  //   },
  //   SubscriptionArn: 'pending confirmation'
  // }
};
```
Subscribe a mobile application to a topic.  

```
import { SubscribeCommand } from "@aws-sdk/client-sns";
import { snsClient } from "../libs/snsClient.js";

/**
 * @param {string} topicArn - The ARN of the topic the subscriber is subscribing to.
 * @param {string} endpoint - The Endpoint ARN of an application. This endpoint is created
 *                            when an application registers for notifications.
 */
export const subscribeApp = async (
  topicArn = "TOPIC_ARN",
  endpoint = "ENDPOINT",
) => {
  const response = await snsClient.send(
    new SubscribeCommand({
      Protocol: "application",
      TopicArn: topicArn,
      Endpoint: endpoint,
    }),
  );
  console.log(response);
  // {
  //   '$metadata': {
  //     httpStatusCode: 200,
  //     requestId: 'c8e35bcd-b3c0-5940-9f66-06f6fcc108f0',
  //     extendedRequestId: undefined,
  //     cfId: undefined,
  //     attempts: 1,
  //     totalRetryDelay: 0
  //   },
  //   SubscriptionArn: 'pending confirmation'
  // }
  return response;
};
```
Subscribe a Lambda function to a topic.  

```
import { SubscribeCommand } from "@aws-sdk/client-sns";
import { snsClient } from "../libs/snsClient.js";

/**
 * @param {string} topicArn - The ARN of the topic the subscriber is subscribing to.
 * @param {string} endpoint - The Endpoint ARN of and AWS Lambda function.
 */
export const subscribeLambda = async (
  topicArn = "TOPIC_ARN",
  endpoint = "ENDPOINT",
) => {
  const response = await snsClient.send(
    new SubscribeCommand({
      Protocol: "lambda",
      TopicArn: topicArn,
      Endpoint: endpoint,
    }),
  );
  console.log(response);
  // {
  //   '$metadata': {
  //     httpStatusCode: 200,
  //     requestId: 'c8e35bcd-b3c0-5940-9f66-06f6fcc108f0',
  //     extendedRequestId: undefined,
  //     cfId: undefined,
  //     attempts: 1,
  //     totalRetryDelay: 0
  //   },
  //   SubscriptionArn: 'pending confirmation'
  // }
  return response;
};
```
Subscribe an SQS queue to a topic.  

```
import { SubscribeCommand, SNSClient } from "@aws-sdk/client-sns";

const client = new SNSClient({});

export const subscribeQueue = async (
  topicArn = "TOPIC_ARN",
  queueArn = "QUEUE_ARN",
) => {
  const command = new SubscribeCommand({
    TopicArn: topicArn,
    Protocol: "sqs",
    Endpoint: queueArn,
  });

  const response = await client.send(command);
  console.log(response);
  // {
  //   '$metadata': {
  //     httpStatusCode: 200,
  //     requestId: '931e13d9-5e2b-543f-8781-4e9e494c5ff2',
  //     extendedRequestId: undefined,
  //     cfId: undefined,
  //     attempts: 1,
  //     totalRetryDelay: 0
  //   },
  //   SubscriptionArn: 'arn:aws:sns:us-east-1:xxxxxxxxxxxx:subscribe-queue-test-430895:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
  // }
  return response;
};
```
Subscribe with a filter to a topic.  

```
import { SubscribeCommand, SNSClient } from "@aws-sdk/client-sns";

const client = new SNSClient({});

export const subscribeQueueFiltered = async (
  topicArn = "TOPIC_ARN",
  queueArn = "QUEUE_ARN",
) => {
  const command = new SubscribeCommand({
    TopicArn: topicArn,
    Protocol: "sqs",
    Endpoint: queueArn,
    Attributes: {
      // This subscription will only receive messages with the 'event' attribute set to 'order_placed'.
      FilterPolicyScope: "MessageAttributes",
      FilterPolicy: JSON.stringify({
        event: ["order_placed"],
      }),
    },
  });

  const response = await client.send(command);
  console.log(response);
  // {
  //   '$metadata': {
  //     httpStatusCode: 200,
  //     requestId: '931e13d9-5e2b-543f-8781-4e9e494c5ff2',
  //     extendedRequestId: undefined,
  //     cfId: undefined,
  //     attempts: 1,
  //     totalRetryDelay: 0
  //   },
  //   SubscriptionArn: 'arn:aws:sns:us-east-1:xxxxxxxxxxxx:subscribe-queue-test-430895:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx'
  // }
  return response;
};
```
+  For more information, see [AWS SDK for JavaScript Developer Guide](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/sns-examples-managing-topics.html#sns-examples-subscribing-email). 
+  For API details, see [Subscribe](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/sns/command/SubscribeCommand) in *AWS SDK for JavaScript API Reference*. 

------
#### [ Kotlin ]

**SDK for Kotlin**  
 There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/kotlin/services/sns#code-examples). 
Subscribe an email address to a topic.  

```
suspend fun subEmail(
    topicArnVal: String,
    email: String,
): String {
    val request =
        SubscribeRequest {
            protocol = "email"
            endpoint = email
            returnSubscriptionArn = true
            topicArn = topicArnVal
        }

    SnsClient.fromEnvironment { region = "us-east-1" }.use { snsClient ->
        val result = snsClient.subscribe(request)
        return result.subscriptionArn.toString()
    }
}
```
Subscribe a Lambda function to a topic.  

```
suspend fun subLambda(
    topicArnVal: String?,
    lambdaArn: String?,
) {
    val request =
        SubscribeRequest {
            protocol = "lambda"
            endpoint = lambdaArn
            returnSubscriptionArn = true
            topicArn = topicArnVal
        }

    SnsClient.fromEnvironment { region = "us-east-1" }.use { snsClient ->
        val result = snsClient.subscribe(request)
        println(" The subscription Arn is ${result.subscriptionArn}")
    }
}
```
+  For API details, see [Subscribe](https://sdk.amazonaws.com/kotlin/api/latest/index.html) in *AWS SDK for Kotlin API reference*. 

------
#### [ PHP ]

**SDK for PHP**  
 There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/php/example_code/sns#code-examples). 
Subscribe an email address to a topic.  

```
require 'vendor/autoload.php';

use Aws\Exception\AwsException;
use Aws\Sns\SnsClient;


/**
 * Prepares to subscribe an endpoint by sending the endpoint a confirmation message.
 *
 * This code expects that you have AWS credentials set up per:
 * https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/guide_credentials.html
 */

$SnSclient = new SnsClient([
    'profile' => 'default',
    'region' => 'us-east-1',
    'version' => '2010-03-31'
]);

$protocol = 'email';
$endpoint = 'sample@example.com';
$topic = 'arn:aws:sns:us-east-1:111122223333:MyTopic';

try {
    $result = $SnSclient->subscribe([
        'Protocol' => $protocol,
        'Endpoint' => $endpoint,
        'ReturnSubscriptionArn' => true,
        'TopicArn' => $topic,
    ]);
    var_dump($result);
} catch (AwsException $e) {
    // output error message if fails
    error_log($e->getMessage());
}
```
Subscribe an HTTP endpoint to a topic.  

```
require 'vendor/autoload.php';

use Aws\Exception\AwsException;
use Aws\Sns\SnsClient;


/**
 * Prepares to subscribe an endpoint by sending the endpoint a confirmation message.
 *
 * This code expects that you have AWS credentials set up per:
 * https://docs.aws.amazon.com/sdk-for-php/v3/developer-guide/guide_credentials.html
 */

$SnSclient = new SnsClient([
    'profile' => 'default',
    'region' => 'us-east-1',
    'version' => '2010-03-31'
]);

$protocol = 'https';
$endpoint = 'https://';
$topic = 'arn:aws:sns:us-east-1:111122223333:MyTopic';

try {
    $result = $SnSclient->subscribe([
        'Protocol' => $protocol,
        'Endpoint' => $endpoint,
        'ReturnSubscriptionArn' => true,
        'TopicArn' => $topic,
    ]);
    var_dump($result);
} catch (AwsException $e) {
    // output error message if fails
    error_log($e->getMessage());
}
```
+  For API details, see [Subscribe](https://docs.aws.amazon.com/goto/SdkForPHPV3/sns-2010-03-31/Subscribe) in *AWS SDK for PHP API Reference*. 

------
#### [ Python ]

**SDK for Python (Boto3)**  
 There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/python/example_code/sns#code-examples). 
Subscribe an email address to a topic.  

```
class SnsWrapper:
    """Encapsulates Amazon SNS topic and subscription functions."""

    def __init__(self, sns_resource):
        """
        :param sns_resource: A Boto3 Amazon SNS resource.
        """
        self.sns_resource = sns_resource


    @staticmethod
    def subscribe(topic, protocol, endpoint):
        """
        Subscribes an endpoint to the topic. Some endpoint types, such as email,
        must be confirmed before their subscriptions are active. When a subscription
        is not confirmed, its Amazon Resource Number (ARN) is set to
        'PendingConfirmation'.

        :param topic: The topic to subscribe to.
        :param protocol: The protocol of the endpoint, such as 'sms' or 'email'.
        :param endpoint: The endpoint that receives messages, such as a phone number
                         (in E.164 format) for SMS messages, or an email address for
                         email messages.
        :return: The newly added subscription.
        """
        try:
            subscription = topic.subscribe(
                Protocol=protocol, Endpoint=endpoint, ReturnSubscriptionArn=True
            )
            logger.info("Subscribed %s %s to topic %s.", protocol, endpoint, topic.arn)
        except ClientError:
            logger.exception(
                "Couldn't subscribe %s %s to topic %s.", protocol, endpoint, topic.arn
            )
            raise
        else:
            return subscription
```
Subscribe a queue to a topic with optional filters.  

```
class SnsWrapper:
    """Wrapper class for managing Amazon SNS operations."""

    def __init__(self, sns_client: Any) -> None:
        """
        Initialize the SnsWrapper.

        :param sns_client: A Boto3 Amazon SNS client.
        """
        self.sns_client = sns_client

    @classmethod
    def from_client(cls) -> 'SnsWrapper':
        """
        Create an SnsWrapper instance using a default boto3 client.

        :return: An instance of this class.
        """
        sns_client = boto3.client('sns')
        return cls(sns_client)


    def subscribe_queue_to_topic(
        self, 
        topic_arn: str, 
        queue_arn: str, 
        filter_policy: Optional[str] = None
    ) -> str:
        """
        Subscribe an SQS queue to an SNS topic.

        :param topic_arn: The ARN of the SNS topic.
        :param queue_arn: The ARN of the SQS queue.
        :param filter_policy: Optional JSON filter policy for message filtering.
        :return: The ARN of the subscription.
        :raises ClientError: If the subscription fails.
        """
        try:
            attributes = {}
            if filter_policy:
                attributes['FilterPolicy'] = filter_policy

            response = self.sns_client.subscribe(
                TopicArn=topic_arn,
                Protocol='sqs',
                Endpoint=queue_arn,
                Attributes=attributes
            )

            subscription_arn = response['SubscriptionArn']
            logger.info(f"Subscribed queue {queue_arn} to topic {topic_arn}")
            return subscription_arn

        except ClientError as e:
            error_code = e.response.get('Error', {}).get('Code', 'Unknown')
            logger.error(f"Error subscribing queue to topic: {error_code} - {e}")
            raise
```
+  For API details, see [Subscribe](https://docs.aws.amazon.com/goto/boto3/sns-2010-03-31/Subscribe) in *AWS SDK for Python (Boto3) API Reference*. 

------
#### [ Ruby ]

**SDK for Ruby**  
 There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/ruby/example_code/sns#code-examples). 
Subscribe an email address to a topic.  

```
require 'aws-sdk-sns'
require 'logger'

# Represents a service for creating subscriptions in Amazon Simple Notification Service (SNS)
class SubscriptionService
  # Initializes the SubscriptionService with an SNS client
  #
  # @param sns_client [Aws::SNS::Client] The SNS client
  def initialize(sns_client)
    @sns_client = sns_client
    @logger = Logger.new($stdout)
  end

  # Attempts to create a subscription to a topic
  #
  # @param topic_arn [String] The ARN of the SNS topic
  # @param protocol [String] The subscription protocol (e.g., email)
  # @param endpoint [String] The endpoint that receives the notifications (email address)
  # @return [Boolean] true if subscription was successfully created, false otherwise
  def create_subscription(topic_arn, protocol, endpoint)
    @sns_client.subscribe(topic_arn: topic_arn, protocol: protocol, endpoint: endpoint)
    @logger.info('Subscription created successfully.')
    true
  rescue Aws::SNS::Errors::ServiceError => e
    @logger.error("Error while creating the subscription: #{e.message}")
    false
  end
end

# Main execution if the script is run directly
if $PROGRAM_NAME == __FILE__
  protocol = 'email'
  endpoint = 'EMAIL_ADDRESS' # Should be replaced with a real email address
  topic_arn = 'TOPIC_ARN'    # Should be replaced with a real topic ARN

  sns_client = Aws::SNS::Client.new
  subscription_service = SubscriptionService.new(sns_client)

  @logger.info('Creating the subscription.')
  unless subscription_service.create_subscription(topic_arn, protocol, endpoint)
    @logger.error('Subscription creation failed. Stopping program.')
    exit 1
  end
end
```
+  For more information, see [AWS SDK for Ruby Developer Guide](https://docs.aws.amazon.com/sdk-for-ruby/v3/developer-guide/sns-example-create-subscription.html). 
+  For API details, see [Subscribe](https://docs.aws.amazon.com/goto/SdkForRubyV3/sns-2010-03-31/Subscribe) in *AWS SDK for Ruby API Reference*. 

------
#### [ Rust ]

**SDK for Rust**  
 There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/rustv1/examples/sns#code-examples). 
Subscribe an email address to a topic.  

```
async fn subscribe_and_publish(
    client: &Client,
    topic_arn: &str,
    email_address: &str,
) -> Result<(), Error> {
    println!("Receiving on topic with ARN: `{}`", topic_arn);

    let rsp = client
        .subscribe()
        .topic_arn(topic_arn)
        .protocol("email")
        .endpoint(email_address)
        .send()
        .await?;

    println!("Added a subscription: {:?}", rsp);

    let rsp = client
        .publish()
        .topic_arn(topic_arn)
        .message("hello sns!")
        .send()
        .await?;

    println!("Published message: {:?}", rsp);

    Ok(())
}
```
+  For API details, see [Subscribe](https://docs.rs/aws-sdk-sns/latest/aws_sdk_sns/client/struct.Client.html#method.subscribe) in *AWS SDK for Rust API reference*. 

------
#### [ SAP ABAP ]

**SDK for SAP ABAP**  
 There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/sap-abap/services/sns#code-examples). 
Subscribe an email address to a topic.  

```
    TRY.
        oo_result = lo_sns->subscribe(                      "oo_result is returned for testing purposes."
                iv_topicarn = iv_topic_arn
                iv_protocol = 'email'
                iv_endpoint = iv_email_address
                iv_returnsubscriptionarn = abap_true ).
        MESSAGE 'Email address subscribed to SNS topic.' TYPE 'I'.
      CATCH /aws1/cx_snsnotfoundexception.
        MESSAGE 'Topic does not exist.' TYPE 'E'.
      CATCH /aws1/cx_snssubscriptionlmte00.
        MESSAGE 'Unable to create subscriptions. You have reached the maximum number of subscriptions allowed.' TYPE 'E'.
    ENDTRY.
```
+  For API details, see [Subscribe](https://docs.aws.amazon.com/sdk-for-sap-abap/v1/api/latest/index.html) in *AWS SDK for SAP ABAP API reference*. 

------
#### [ Swift ]

**SDK for Swift**  
 There's more on GitHub. Find the complete example and learn how to set up and run in the [AWS Code Examples Repository](https://github.com/awsdocs/aws-doc-sdk-examples/tree/main/swift/example_code/sns#code-examples). 
Subscribe an email address to a topic.  

```
import AWSSNS

        let config = try await SNSClient.SNSClientConfiguration(region: region)
        let snsClient = SNSClient(config: config)

        let output = try await snsClient.subscribe(
            input: SubscribeInput(
                endpoint: email,
                protocol: "email",
                returnSubscriptionArn: true,
                topicArn: arn
            )
        )

        guard let subscriptionArn = output.subscriptionArn else {
            print("No subscription ARN received from Amazon SNS.")
            return
        }
        
        print("Subscription \(subscriptionArn) created.")
```
Subscribe a phone number to a topic to receive notifications by SMS.  

```
import AWSSNS

        let config = try await SNSClient.SNSClientConfiguration(region: region)
        let snsClient = SNSClient(config: config)

        let output = try await snsClient.subscribe(
            input: SubscribeInput(
                endpoint: phone,
                protocol: "sms",
                returnSubscriptionArn: true,
                topicArn: arn
            )
        )

        guard let subscriptionArn = output.subscriptionArn else {
            print("No subscription ARN received from Amazon SNS.")
            return
        }
        
        print("Subscription \(subscriptionArn) created.")
```
+  For API details, see [Subscribe](https://sdk.amazonaws.com/swift/api/awssns/latest/documentation/awssns/snsclient/subscribe(input:)) in *AWS SDK for Swift API reference*. 

------