

End of support notice: On May 20, 2026, AWS will end support for AWS IoT Events. After May 20, 2026, you will no longer be able to access the AWS IoT Events console or AWS IoT Events resources. For more information, see [AWS IoT Events end of support](https://docs.aws.amazon.com/iotevents/latest/developerguide/iotevents-end-of-support.html).

# Monitoring with alarms in AWS IoT Events
<a name="iotevents-alarms"></a>

AWS IoT Events alarms help you monitor your data for changes. The data can be metrics that you measure for your equipment and processes. You can create alarms that send notifications when a threshold is breached. Alarms help you detect issues, streamline maintenance, and optimize performance of your equipment and processes.

Alarms are instances of alarm models. The alarm model specifies what to detect, when to send notifications, who gets notified, and more. You can also specify one or more [supported actions](https://docs.aws.amazon.com/iotevents/latest/developerguide/iotevents-supported-actions.html) that occur when the alarm state changes. AWS IoT Events routes [input attributes](https://docs.aws.amazon.com/iotevents/latest/developerguide/iotevents-detector-input.html) derived from your data to the appropriate alarms. If the data that you're monitoring is outside the specified range, the alarm is invoked. You can also acknowledge the alarms or set them to the snooze mode.

## Working with AWS IoT SiteWise
<a name="alarms-collaborations.title"></a>

You can use AWS IoT Events alarms to monitor asset properties in AWS IoT SiteWise. AWS IoT SiteWise sends asset property values to AWS IoT Events alarms. AWS IoT Events sends the alarm state to AWS IoT SiteWise.

AWS IoT SiteWise also supports external alarms. You might choose external alarms if you use alarms outside of AWS IoT SiteWise and have a solution that returns alarm state data. The external alarm contains a measurement property that ingests the alarm state data.

AWS IoT SiteWise doesn't evaluate the state of external alarms. Additionally, you can't acknowledge or snooze an external alarm when the alarm state changes.

You can use the SiteWise Monitor feature to view the state of external alarms in SiteWise Monitor portals.

For more information, see [Monitoring data with alarms](https://docs.aws.amazon.com/iot-sitewise/latest/userguide/industrial-alarms.html) in the *AWS IoT SiteWise User Guide* and [Monitoring with alarms](https://docs.aws.amazon.com//iot-sitewise/latest/appguide/monitor-alarms.html) in the *SiteWise Monitor Application Guide*.

## Acknowledge flow
<a name="acknowledge-flow"></a>

When you create an alarm model, you choose whether to enable acknowledge flow. If you enable acknowledge flow, your team gets notified when the alarm state changes. Your team can acknowledge the alarm and leave a note. For example, you can include the information of the alarm and the actions that you're going to take to address the issue. If the data that you're monitoring is outside the specified range, the alarm is invoked.

Alarms have the following states:

`DISABLED`  
When the alarm is in the `DISABLED` state, it isn't ready to evaluate data. To enable the alarm, you must change the alarm to the `NORMAL` state.

`NORMAL`  
When the alarm is in the `NORMAL` state, it's ready to evaluate data.

`ACTIVE`  
If the alarm is in the `ACTIVE` state, the alarm is invoked. The data that you're monitoring is outside the specified range.

`ACKNOWLEDGED`  
When the alarm is in the `ACKNOWLEDGED` state, the alarm was invoked and you acknowledged the alarm.

`LATCHED`  
The alarm was invoked, but you didn't acknowledge the alarm after a period of time. The alarm automatically changes to the `NORMAL` state.

`SNOOZE_DISABLED`  
When the alarm is in the `SNOOZE_DISABLED` state, the alarm is disabled for a specified period of time. After the snooze time, the alarm automatically changes to the `NORMAL` state.

# Creating an alarm model in AWS IoT Events
<a name="create-alarm-model"></a>

You can use AWS IoT Events alarms to monitor your data and get notified when a threshold is breached. Alarms provide parameters that you use to create or configure an alarm model. You can use the AWS IoT Events console or AWS IoT Events API to create or configure the alarm model. When you configure the alarm model, changes take effect as new data arrives.

## Requirements
<a name="create-alarm-model-requirements"></a>

The following requirements apply when you create an alarm model.
+ You can create an alarm model to monitor an input attribute in AWS IoT Events or an asset property in AWS IoT SiteWise.
  + If you choose to monitor an input attribute in AWS IoT Events, [Create an input for models in AWS IoT Events](create-input-overview.md) before you create the alarm model.
  + If you choose to monitor an asset property, you must [create an asset model](https://docs.aws.amazon.com/iot-sitewise/latest/userguide/create-asset-models.html) in AWS IoT SiteWise before you create the alarm model.
+ You must have an IAM role that allows your alarm to perform actions and access AWS resources. For more information, see [Setting up permissions for AWS IoT Events](https://docs.aws.amazon.com/iotevents/latest/developerguide/iotevents-start.html).
+ All the AWS resources that this tutorial uses must be in the same AWS Region.

## Creating an alarm model (console)
<a name="create-alarm-model-console"></a>

The following shows you how to create an alarm model to monitor an AWS IoT Events attribute in the AWS IoT Events console.

1. Sign in to the [AWS IoT Events console](https://console.aws.amazon.com/iotevents/).

1. In the navigation pane, choose **Alarm models**.

1. On the **Alarm models** page, choose **Create alarm model**.

1. In the **Alarm model details** section, do the following:

   1. Enter a unique name.

   1. (Optional) Enter a description.

1. In the **Alarm target** section, do the following:
**Important**  
If you choose **AWS IoT SiteWise asset property**, you must have created an asset model in AWS IoT SiteWise.

   1. Choose **AWS IoT Events input attribute**.

   1. Choose the input.

   1. Choose the input attribute key. This input attribute is used as a key to create the alarm. AWS IoT Events routes inputs associated with this key to the alarm.
**Important**  
If the input message payload does not contain this input attribute key, or if the key is not in the same JSON path specified in the key, then the message will fail the ingestion in AWS IoT Events.

1. In the **Threshold definitions** section, you define the input attribute, threshold value, and comparison operator that AWS IoT Events uses to change the state of the alarm.

   1. For **Input attribute**, choose the attribute that you want to monitor.

      Each time that this input attribute receives new data, it's evaluated to determine the state of the alarm.

   1. For **Operator**, choose the comparison operator. The operator compares your input attribute with the threshold value for your attribute.

      You can choose from these options: 
      + **> greater than**
      + **>= greater than or equal to**
      + **< less than**
      + **<= less than or equal to**
      + **= equal to**
      + **\$1= not equal to**

   1. For threshold **Value**, enter a number or choose an attribute in AWS IoT Events inputs. AWS IoT Events compares this value with the value of the input attribute you choose. 

   1. (Optional) For **Severity**, Use a number that your team understands to reflect the severity of this alarm.

1. (Optional) In the **Notification settings** section, configure notification settings for the alarm.

   You can add up to 10 notifications. For **Notification 1**, do the following:

   1. For **Protocol**, choose from the following options:
      + **Email & text** - The alarm sends an SMS notification and an email notification.
      + **Email** - The alarm sends an email notification.
      + **Text** - The alarm sends an SMS notification.

   1. For **Sender**, specify the email address that can send notifications about this alarm.

      To add more email addresses to your sender list, choose **Add sender**. 

   1. (Optional) For **Recipient**, choose the recipient.

      To add more users to your recipient list, choose **Add new user**. You must add new users to your IAM Identity Center store before you can add them to your alarm model. For more information, see [Manage IAM Identity Center access of alarm recipients in AWS IoT Events](sso-authorization-recipients.md).

   1. (Optional) For **Additional custom message**, enter a message that describes what the alarm detects and what actions the recipients should take.

1. In the **Instance** section, you can enable or disable all alarm instances that are created based on this alarm model.

1. In the **Advanced settings** section, do the following:

   1. For **Acknowledge flow**, you can enable or disable notifications.
      + If you choose **Enabled**, you receive a notification when the alarm state changes. You must acknowledge the notification before the alarm state can return to normal.
      + If you choose **Disabled**, no action is required. The alarm automatically changes to the normal state when the measurement returns to the specified range.

      For more information, see [Acknowledge flow](iotevents-alarms.md#acknowledge-flow).

   1. For **Permissions**, choose one of the following options:
      + You can **Create a new role from AWS policy templates** and AWS IoT Events automatically creates an IAM role for you. 
      + You can **Use an existing IAM role** that allows this alarm model to perform actions and access other AWS resources.

      For more information, see [Identity and access management for AWS IoT Events](https://docs.aws.amazon.com/iotevents/latest/developerguide/security-iam.html).

   1. For **Additional notification settings**, you can edit your AWS Lambda function to manage alarm notifications. Choose one of the following options for your AWS Lambda function:
      + **Create a new AWS Lambda function** - AWS IoT Events creates a new AWS Lambda function for you.
      + **Use an existing AWS Lambda function** - Use an existing AWS Lambda function by choosing an AWS Lambda function name. 

      For more information about the possible actions, see [AWS IoT Events working with other AWS services](iotevents-other-aws-services.md).

   1. (Optional) For **Set state action**, you can add one or more AWS IoT Events actions to take when the alarm state changes.

1. (Optional) You can add **Tags** to manage your alarms. For more information, see [Tagging your AWS IoT Events resources](https://docs.aws.amazon.com/iotevents/latest/developerguide/tagging-iotevents.html).

1. Choose **Create**.

# Responding to alarms in AWS IoT Events
<a name="respond-to-alarms"></a>

Responding to alarms effectively is an important aspect of managing IoT systems with AWS IoT Events. Explore various ways to configure and handle alarms, including: setting up notification channels, defining escalation procedures, and implementing automated response actions. Learn to create nuanced alarm conditions, prioritize alerts, and integrate with other AWS services to build a responsive alarm management system for your IoT applications.

If you enabled [acknowledge flow](https://docs.aws.amazon.com/iotevents/latest/developerguide/iotevents-alarms.html#acknowledge-flow), you receive notifications when the alarm state changes. To respond to the alarm, you can acknowledge, disable, enable, reset, or snooze the alarm.

------
#### [ Console ]

The following shows you how to respond to an alarm in the AWS IoT Events console.

1. Sign in to the [AWS IoT Events console](https://console.aws.amazon.com/iotevents/).

1. In the navigation pane, choose **Alarm models**.

1. Choose the target alarm model.

1. In the **List of alarms** section, choose the target alarm.

1. You can choose one of the following options from **Actions**:
   + **Acknowledge** - The alarm changes to the `ACKNOWLEDGED` state.
   + **Disable** - The alarm changes to the `DISABLED` state.
   + **Enable** - The alarm changes to the `NORMAL` state.
   + **Reset** - The alarm changes to the `NORMAL` state.
   + **Snooze**, and then do the following:

     1. Choose the **Snooze length** or enter a **Custom snooze length**.

     1. Choose **Save**.

     The alarm changes to the `SNOOZE_DISABLED` state

   For more information about the alarm states, see [Acknowledge flow](iotevents-alarms.md#acknowledge-flow).

------
#### [ API ]

To respond to one or more alarms, you can use the following AWS IoT Events API operations:
+ [BatchAcknowledgeAlarm](https://docs.aws.amazon.com/iotevents/latest/apireference/API_iotevents-data_BatchAcknowledgeAlarm.html)
+ [BatchDisableAlarm](https://docs.aws.amazon.com/iotevents/latest/apireference/API_iotevents-data_BatchDisableAlarm.html)
+ [BatchEnableAlarm](https://docs.aws.amazon.com/iotevents/latest/apireference/API_iotevents-data_BatchEnableAlarm.html)
+ [BatchResetAlarm](https://docs.aws.amazon.com/iotevents/latest/apireference/API_iotevents-data_BatchResetAlarm.html)
+ [BatchSnoozeAlarm](https://docs.aws.amazon.com/iotevents/latest/apireference/API_iotevents-data_BatchSnoozeAlarm.html)

------

# Managing alarm notifications in AWS IoT Events
<a name="lambda-support"></a>

AWS IoT Events integrates with Lambda, offering custom event processing capabilities. This section explores how to use Lambda functions within your AWS IoT Events detector models, allowing you to execute complex logic, interact with external services, and implement sophisticated event handling.

AWS IoT Events uses a Lambda function to manage alarm notifications. You can use the Lambda function provided by AWS IoT Events or create a new one.

**Topics**
+ [Creating a Lambda function in AWS IoT Events](alarms-create-lambda.md)
+ [Using the Lambda function provided by AWS IoT Events](use-alarm-notifications.md)
+ [Manage IAM Identity Center access of alarm recipients in AWS IoT Events](sso-authorization-recipients.md)

# Creating a Lambda function in AWS IoT Events
<a name="alarms-create-lambda"></a>

AWS IoT Events provides a Lambda function that enables alarms to send and receive email and SMS notifications.

## Requirements
<a name="alarms-lambda-requirements"></a>

The following requirements apply when you create a Lambda function for alarms:
+ If your alarm sends SMS notifications, ensure Amazon SNS is configured to deliver SMS messages.
  + For more information, see the following documentation:
    + [Mobile text messaging with Amazon SNS](https://docs.aws.amazon.com/sns/latest/dg/sns-mobile-phone-number-as-subscriber.html) and [Origination identities for Amazon SNS SMS messages](https://docs.aws.amazon.com/sns/latest/dg/channels-sms-originating-identities.html) in the *Amazon Simple Notification Service Developer Guide*.
    + [What is AWS End User Messaging SMS?](https://docs.aws.amazon.com/sms-voice/latest/userguide/what-is-sms-mms.html) in the *AWS SMS User Guide*.
+ If your alarm sends email or SMS notifications, you must have an IAM role that allows AWS Lambda to work with Amazon SES and Amazon SNS.

  

  Example policy:

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

****  

  ```
  {
      "Version":"2012-10-17",		 	 	 
      "Statement": [
          {
              "Effect": "Allow",
              "Action": [
                  "ses:GetIdentityVerificationAttributes",
                  "ses:SendEmail",
                  "ses:VerifyEmailIdentity"
              ],
              "Resource": "*"
          },
          {
              "Effect": "Allow",
              "Action": [
                  "sns:Publish",
                  "sns:OptInPhoneNumber",
                  "sns:CheckIfPhoneNumberIsOptedOut",
                  "sms-voice:DescribeOptedOutNumbers"
              ],
              "Resource": "*"
          },
          {
              "Effect": "Deny",
              "Action": "sns:Publish",
              "Resource": "arn:aws:sns:*:*:*"
          },
          {
            "Effect" : "Allow",
            "Action" : [
              "logs:CreateLogGroup",
              "logs:CreateLogStream",
              "logs:PutLogEvents"
            ],
            "Resource" : "*"
          }
      ]
  }
  ```

------
+ You must choose the same AWS Region for both AWS IoT Events and AWS Lambda. For the list of supported Regions, see [AWS IoT Events endpoints and quotas](https://docs.aws.amazon.com/general/latest/gr/iot-events.html) and [AWS Lambda endpoints and quotas](https://docs.aws.amazon.com/general/latest/gr/lambda-service.html) in the *Amazon Web Services General Reference*.

# Deploy a Lambda function for AWS IoT Events using CloudFormation
<a name="alarms-create-lambda-cfn"></a>

This tutorial uses an CloudFormation template to deploy a Lambda function. This template automatically creates an IAM role that allows the Lambda function to work with Amazon SES and Amazon SNS.

The following shows you how to use the AWS Command Line Interface (AWS CLI) to create a CloudFormation stack.

1. <a name="install-cli"></a>In your device's terminal, run `aws --version` to check if you installed the AWS CLI. For more information, see [Installing or updating to the latest version of the AWS CLI](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html) in the *AWS Command Line Interface User Guide*.

1. <a name="configure-cli"></a>Run `aws configure list` to check if you configured the AWS CLI in the AWS Region that has all your AWS resources for this tutorial. For more information, see [Set and view configuration settings using commands](https://docs.aws.amazon.com/cli/latest/userguide/cli-configure-files.html#cli-configure-files-methods) in the *AWS Command Line Interface User Guide*

1. Download the CloudFormation template, [notificationLambda.template.yaml.zip](samples/notificationLambda.template.yaml.zip).
**Note**  
If you have difficulty downloading the file, the template is also available in the [CloudFormation template](alarms-create-lambda.md#cfn-template).

1. Unzip the content and save it locally as `notificationLambda.template.yaml`.

1. Open a terminal on your device and navigate to the directory where you downloaded the `notificationLambda.template.yaml` file.

1. To create a CloudFormation stack, run the following command:

   ```
   aws cloudformation create-stack --stack-name notificationLambda-stack --template-body file://notificationLambda.template.yaml --capabilities CAPABILITY_IAM
   ```

You might modify this CloudFormation template to customize the Lambda function and its behavior.

**Note**  
AWS Lambda retries function errors twice. If the function doesn't have enough capacity to handle all incoming requests, events might wait in the queue for hours or days to be sent to the function. You can configure an undelivered-message queue (DLQ) on the function to capture events that weren't successfully processed. For more information, see [Asynchronous invocation](https://docs.aws.amazon.com/lambda/latest/dg/invocation-async.html) in the *AWS Lambda Developer Guide*.

You can also create or configure the stack in the CloudFormation console. For more information, see [Working with stacks](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/stacks.html), in the *AWS CloudFormation User Guide*.

# Creating a custom Lambda function for AWS IoT Events
<a name="alarms-create-custom-lambda"></a>

You can create a Lambda function or modify the one provided by AWS IoT Events.

The following requirements apply when you create a custom Lambda function.
+ Add permissions that allow your Lambda function to perform specified actions and access AWS resources.
+ If you use the Lambda function provided by AWS IoT Events, make sure that you choose the Python 3.7 runtime.

Example Lambda function:

```
import boto3
import json
import logging
import datetime
logger = logging.getLogger()
logger.setLevel(logging.INFO)
ses = boto3.client('ses')
sns = boto3.client('sns')
def check_value(target):
  if target:
    return True
  return False

# Check whether email is verified. Only verified emails are allowed to send emails to or from.
def check_email(email):
  if not check_value(email):
    return False
  result = ses.get_identity_verification_attributes(Identities=[email])
  attr = result['VerificationAttributes']
  if (email not in attr or attr[email]['VerificationStatus'] != 'Success'):
      logging.info('Verification email for {} sent. You must have all the emails verified before sending email.'.format(email))
      ses.verify_email_identity(EmailAddress=email)
      return False
  return True

# Check whether the phone holder has opted out of receiving SMS messages from your account
def check_phone_number(phone_number):
  try:
    result = sns.check_if_phone_number_is_opted_out(phoneNumber=phone_number)
    if (result['isOptedOut']):
        logger.info('phoneNumber {} is not opt in of receiving SMS messages. Phone number must be opt in first.'.format(phone_number))
        return False
    return True
  except Exception as e:
    logging.error('Your phone number {} must be in E.164 format in SSO. Exception thrown: {}'.format(phone_number, e))
    return False

def check_emails(emails):
  result = True
  for email in emails:
      if not check_email(email):
          result = False
  return result

def lambda_handler(event, context):
  logging.info('Received event: ' + json.dumps(event))
  nep = json.loads(event.get('notificationEventPayload'))
  alarm_state = nep['alarmState']
  default_msg = 'Alarm ' + alarm_state['stateName'] + '\n'
  timestamp = datetime.datetime.utcfromtimestamp(float(nep['stateUpdateTime'])/1000).strftime('%Y-%m-%d %H:%M:%S')
  alarm_msg = "{} {} {} at {} UTC ".format(nep['alarmModelName'], nep.get('keyValue', 'Singleton'), alarm_state['stateName'], timestamp)
  default_msg += 'Sev: ' + str(nep['severity']) + '\n'
  if (alarm_state['ruleEvaluation']):
    property = alarm_state['ruleEvaluation']['simpleRule']['inputProperty']
    default_msg += 'Current Value: ' + str(property) + '\n'
    operator = alarm_state['ruleEvaluation']['simpleRule']['operator']
    threshold = alarm_state['ruleEvaluation']['simpleRule']['threshold']
    alarm_msg += '({} {} {})'.format(str(property), operator, str(threshold))
  default_msg += alarm_msg + '\n'

  emails = event.get('emailConfigurations', [])
  logger.info('Start Sending Emails')
  for email in emails:
    from_adr = email.get('from')
    to_adrs = email.get('to', [])
    cc_adrs = email.get('cc', [])
    bcc_adrs = email.get('bcc', [])
    msg = default_msg + '\n' + email.get('additionalMessage', '')
    subject = email.get('subject', alarm_msg)
    fa_ver = check_email(from_adr)
    tas_ver = check_emails(to_adrs)
    ccas_ver = check_emails(cc_adrs)
    bccas_ver = check_emails(bcc_adrs)
    if (fa_ver and tas_ver and ccas_ver and bccas_ver):
      ses.send_email(Source=from_adr,
                     Destination={'ToAddresses': to_adrs, 'CcAddresses': cc_adrs, 'BccAddresses': bcc_adrs},
                     Message={'Subject': {'Data': subject}, 'Body': {'Text': {'Data': msg}}})
      logger.info('Emails have been sent')

  logger.info('Start Sending SNS message to SMS')
  sns_configs = event.get('smsConfigurations', [])
  for sns_config in sns_configs:
    sns_msg = default_msg + '\n' + sns_config.get('additionalMessage', '')
    phone_numbers = sns_config.get('phoneNumbers', [])
    sender_id = sns_config.get('senderId')
    for phone_number in phone_numbers:
        if check_phone_number(phone_number):
          if check_value(sender_id):
            sns.publish(PhoneNumber=phone_number, Message=sns_msg, MessageAttributes={'AWS.SNS.SMS.SenderID':{'DataType': 'String','StringValue': sender_id}})
          else:
            sns.publish(PhoneNumber=phone_number, Message=sns_msg)
          logger.info('SNS messages have been sent')
```

For more information, see [What is AWS Lambda?](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html) in the *AWS Lambda Developer Guide*.

## CloudFormation template
<a name="cfn-template"></a>

Use the following CloudFormation template to create your Lambda function.

```
AWSTemplateFormatVersion: '2010-09-09'
Description: 'Notification Lambda for Alarm Model'
Resources:
  NotificationLambdaRole:
    Type: AWS::IAM::Role
    Properties:
      AssumeRolePolicyDocument:
        Statement:
          - Effect: Allow
            Principal:
              Service: lambda.amazonaws.com
            Action: sts:AssumeRole
      Path: "/"
      ManagedPolicyArns:
        - 'arn:aws:iam::aws:policy/AWSLambdaExecute'
      Policies:
        - PolicyName: "NotificationLambda"
          PolicyDocument:
            Version: "2012-10-17"		 	 	 
            Statement:
              - Effect: "Allow"
                Action:
                  - "ses:GetIdentityVerificationAttributes"
                  - "ses:SendEmail"
                  - "ses:VerifyEmailIdentity"
                Resource: "*"
              - Effect: "Allow"
                Action:
                  - "sns:Publish"
                  - "sns:OptInPhoneNumber"
                  - "sns:CheckIfPhoneNumberIsOptedOut"
                  - "sms-voice:DescribeOptedOutNumbers"
                Resource: "*"
              - Effect: "Deny"
                Action:
                  - "sns:Publish"
                Resource: "arn:aws:sns:*:*:*"
  NotificationLambdaFunction:              
    Type: AWS::Lambda::Function
    Properties:
      Role: !GetAtt NotificationLambdaRole.Arn
      Runtime: python3.7
      Handler: index.lambda_handler
      Timeout: 300
      MemorySize: 3008
      Code:
        ZipFile: |
          import boto3
          import json
          import logging
          import datetime
          logger = logging.getLogger()
          logger.setLevel(logging.INFO)
          ses = boto3.client('ses')
          sns = boto3.client('sns')
          def check_value(target):
            if target:
              return True
            return False

          # Check whether email is verified. Only verified emails are allowed to send emails to or from.
          def check_email(email):
            if not check_value(email):
              return False
            result = ses.get_identity_verification_attributes(Identities=[email])
            attr = result['VerificationAttributes']
            if (email not in attr or attr[email]['VerificationStatus'] != 'Success'):
                logging.info('Verification email for {} sent. You must have all the emails verified before sending email.'.format(email))
                ses.verify_email_identity(EmailAddress=email)
                return False
            return True

          # Check whether the phone holder has opted out of receiving SMS messages from your account
          def check_phone_number(phone_number):
            try:
              result = sns.check_if_phone_number_is_opted_out(phoneNumber=phone_number)
              if (result['isOptedOut']):
                  logger.info('phoneNumber {} is not opt in of receiving SMS messages. Phone number must be opt in first.'.format(phone_number))
                  return False
              return True
            except Exception as e:
              logging.error('Your phone number {} must be in E.164 format in SSO. Exception thrown: {}'.format(phone_number, e))
              return False

          def check_emails(emails):
            result = True
            for email in emails:
                if not check_email(email):
                    result = False
            return result

          def lambda_handler(event, context):
            logging.info('Received event: ' + json.dumps(event))
            nep = json.loads(event.get('notificationEventPayload'))
            alarm_state = nep['alarmState']
            default_msg = 'Alarm ' + alarm_state['stateName'] + '\n'
            timestamp = datetime.datetime.utcfromtimestamp(float(nep['stateUpdateTime'])/1000).strftime('%Y-%m-%d %H:%M:%S')
            alarm_msg = "{} {} {} at {} UTC ".format(nep['alarmModelName'], nep.get('keyValue', 'Singleton'), alarm_state['stateName'], timestamp)
            default_msg += 'Sev: ' + str(nep['severity']) + '\n'
            if (alarm_state['ruleEvaluation']):
              property = alarm_state['ruleEvaluation']['simpleRule']['inputProperty']
              default_msg += 'Current Value: ' + str(property) + '\n'
              operator = alarm_state['ruleEvaluation']['simpleRule']['operator']
              threshold = alarm_state['ruleEvaluation']['simpleRule']['threshold']
              alarm_msg += '({} {} {})'.format(str(property), operator, str(threshold))
            default_msg += alarm_msg + '\n'

            emails = event.get('emailConfigurations', [])
            logger.info('Start Sending Emails')
            for email in emails:
              from_adr = email.get('from')
              to_adrs = email.get('to', [])
              cc_adrs = email.get('cc', [])
              bcc_adrs = email.get('bcc', [])
              msg = default_msg + '\n' + email.get('additionalMessage', '')
              subject = email.get('subject', alarm_msg)
              fa_ver = check_email(from_adr)
              tas_ver = check_emails(to_adrs)
              ccas_ver = check_emails(cc_adrs)
              bccas_ver = check_emails(bcc_adrs)
              if (fa_ver and tas_ver and ccas_ver and bccas_ver):
                ses.send_email(Source=from_adr,
                               Destination={'ToAddresses': to_adrs, 'CcAddresses': cc_adrs, 'BccAddresses': bcc_adrs},
                               Message={'Subject': {'Data': subject}, 'Body': {'Text': {'Data': msg}}})
                logger.info('Emails have been sent')

            logger.info('Start Sending SNS message to SMS')
            sns_configs = event.get('smsConfigurations', [])
            for sns_config in sns_configs:
              sns_msg = default_msg + '\n' + sns_config.get('additionalMessage', '')
              phone_numbers = sns_config.get('phoneNumbers', [])
              sender_id = sns_config.get('senderId')
              for phone_number in phone_numbers:
                  if check_phone_number(phone_number):
                    if check_value(sender_id):
                      sns.publish(PhoneNumber=phone_number, Message=sns_msg, MessageAttributes={'AWS.SNS.SMS.SenderID':{'DataType': 'String','StringValue': sender_id}})
                    else:
                      sns.publish(PhoneNumber=phone_number, Message=sns_msg)
                    logger.info('SNS messages have been sent')
```

# Using the Lambda function provided by AWS IoT Events
<a name="use-alarm-notifications"></a>

With alarm notifications, you can use the Lambda function provided by AWS IoT Events for managing alarm notifications.

The following requirements apply when you use the Lambda function provided by AWS IoT Events to manage your alarm notifications:
+ You must verify the email address that sends the email notifications in Amazon Simple Email Service (Amazon SES). For more information, see [Verifying an email address identity](https://docs.aws.amazon.com/ses/latest/dg/creating-identities.html#just-verify-email-proc), in the *Amazon Simple Email Service Developer Guide*.

  If you receive a verification link, click the link to verify your email address. You might also check your spam folder for a verification email.
+ If your alarm sends SMS notifications, you must use E.164 international phone number formatting for phone numbers. This format contains `+<country-calling-code><area-code><phone-number>`.

  Example phone numbers:    
[\[See the AWS documentation website for more details\]](http://docs.aws.amazon.com/iotevents/latest/developerguide/use-alarm-notifications.html)

  To find a country calling code, go to [countrycode.org](https://countrycode.org/).

  The Lambda function provided by AWS IoT Events checks if you use E.164 formatted phone numbers. However, it doesn't verify the phone numbers. If you ensure that you entered accurate phone numbers but didn't receive SMS notifications, you might contact the phone carriers. The carriers may block the messages.

# Manage IAM Identity Center access of alarm recipients in AWS IoT Events
<a name="sso-authorization-recipients"></a>

AWS IoT Events uses AWS IAM Identity Center to manage the SSO access of alarms recipients. Implementing IAM Identity Center for AWS IoT Events notification recipients can enhance security and user experience. To enable the alarm to send notifications to the recipients, you must enable IAM Identity Center and add recipients to your IAM Identity Center store. For more information, see [Add Users](https://docs.aws.amazon.com/singlesignon/latest/userguide/addusers.html) in *AWS IAM Identity Center User Guide*.

**Important**  
You must choose the same AWS Region for AWS IoT Events, AWS Lambda, and IAM Identity Center.
AWS Organizations only supports one IAM Identity Center Region at a time. If you want to make IAM Identity Center available in a different Region, you must first delete your current IAM Identity Center configuration. For more information, see [IAM Identity Center Region Data](https://docs.aws.amazon.com/singlesignon/latest/userguide/regions.html#region-data) in *AWS IAM Identity Center User Guide*.