

# Managing a schedule in EventBridge Scheduler
<a name="managing-schedule"></a>

 A *schedule* is the main resource you create, configure, and manage using Amazon EventBridge Scheduler. 

 Every schedule has a *schedule expression* that determines when, and with what frequency, the schedule runs. EventBridge Scheduler supports three types of schedules: rate, cron, and one-time schedules. For more information about different schedule types, see [Schedule types in EventBridge Scheduler](schedule-types.md). 

 When you create a schedule, you configure a target for the schedule to invoke. A target is an API operation that EventBridge Scheduler calls on your behalf every time your schedule runs. EventBridge Scheduler supports two types of targets: *templated* targets call common API operations across a core groups of services, and the *universal target parameter (UTP)* that you can use to call more than 6,000 operations across over 270 services. For more information about configuring targets, see [Managing targets in EventBridge Scheduler](managing-targets.md). 

 You configure how your schedule handles failures, when EventBridge Scheduler is unable to deliver an event successfully to a target, by using two primary mechanisms: a *retry policy*, and a *dead-letter queue (DLQ)*. A retry policy determines the number of times EventBridge Scheduler must retry a failed event, and how long to keep an unprocessed event. A DLQ is a standard Amazon SQS queue EventBridge Scheduler uses to deliver failed events to, after the retry policy has been exhausted. You can use a DLQ to troubleshoot issues with your schedule or its downstream target. For more information about, see [Configuring a schedule's dead-letter queue in EventBridge Scheduler](configuring-schedule-dlq.md). 

 In this section, you can find examples for managing your EventBridge Scheduler schedules using the console, the AWS CLI and the EventBridge Scheduler SDKs. 

**Topics**
+ [Changing the schedule state in EventBridge Scheduler](managing-schedule-state.md)
+ [Configuring flexible time windows in EventBridge Scheduler](managing-schedule-flexible-time-windows.md)
+ [Configuring a schedule's dead-letter queue in EventBridge Scheduler](configuring-schedule-dlq.md)
+ [Deleting a schedule in EventBridge Scheduler](managing-schedule-delete.md)
+ [What's next?](#managing-schedule-whats-next)

# Changing the schedule state in EventBridge Scheduler
<a name="managing-schedule-state"></a>

 An EventBridge Scheduler schedule has two states: *enabled* and *disabled*. The following example uses `UpdateSchedule` to disable a schedule that fires every five minutes and invokes a Lambda target. 

 When you use `UpdateSchedule`, you must provide all required parameters. EventBridge Scheduler replaces your schedule with the information you provide. If you do not specify a parameter that you've previously set, it defaults to `null`. 

**Example AWS CLI**  

```
$ aws scheduler update-schedule --name lambda-universal --schedule-expression 'rate(5 minutes)' \
--target '{"RoleArn": "ROLE_ARN", "Arn":"arn:aws:scheduler:::aws-sdk:lambda:invoke" "Input": "{\"FunctionName\":\"arn:aws:lambda:REGION:123456789012:function:HelloWorld\",\"InvocationType\":\"Event\",\"Payload\":\"{\\\"message\\\":\\\"testing function\\\"}\"}" }' \
--flexible-time-window '{ "Mode": "OFF"}' \
--state DISABLED
```

```
{
    "ScheduleArn": "arn:aws:scheduler:us-west-2:123456789012:schedule/default/lambda-universal"
}
```

 The following example uses the Python SDK and the `UpdateSchedule` operation to disable a schedule that targets Amazon SQS using a templated target. 

**Example Python SDK**  

```
import boto3
scheduler = boto3.client('scheduler')

sqs_templated = {
    "RoleArn": "<ROLE_ARN>",
    "Arn": "<QUEUE_ARN>",
    "Input": "{}"}

flex_window = { "Mode": "OFF" }

scheduler.update_schedule(Name="your-schedule",
    ScheduleExpression="rate(5 minutes)",
    Target=sqs_templated,
    FlexibleTimeWindow=flex_window,
    State='DISABLED')
```

# Configuring flexible time windows in EventBridge Scheduler
<a name="managing-schedule-flexible-time-windows"></a>

 When you configure your schedule with a flexible time window, EventBridge Scheduler invokes the target within the time window you set. This is useful in cases that do not require precise scheduled invocation of targets. Setting a flexible time window improves the reliability of your schedule by dispersing your target invocations. 

 For example, if you configure a 15 minute flexible time window for a schedule that runs every hour, it invokes the target within 15 minutes after the scheduled time. The following AWS CLI, and EventBridge Scheduler SDK examples use `UpdateSchedule` to set a 15 minute flexible time window for a schedule that runs once every hour. 

**Note**  
 You must specify whether you want to set a flexible time window or not. If you do not want to set this option, specify `OFF`. If you do set the value to `FLEXIBLE`, you must then specify a maximum window of time during which you schedule will run. 

**Example AWS CLI**  

```
$ aws scheduler update-schedule --name lambda-universal --schedule-expression 'rate(1 hour)' \
--target '{"RoleArn": "ROLE_ARN", "Arn":"arn:aws:scheduler:::aws-sdk:lambda:invoke" "Input": "{\"FunctionName\":\"arn:aws:lambda:REGION:123456789012:function:HelloWorld\",\"InvocationType\":\"Event\",\"Payload\":\"{\\\"message\\\":\\\"testing function\\\"}\"}" }' \
--flexible-time-window '{ "Mode": "FLEXIBLE", "MaximumWindowInMinutes": 15} \
```

```
{
    "ScheduleArn": "arn:aws:scheduler:us-west-2:123456789012:schedule/lambda-universal"
}
```

**Example Python SDK**  

```
import boto3
scheduler = boto3.client('scheduler')

sqs_templated = {
    "RoleArn": "<ROLE_ARN>",
    "Arn": "<QUEUE_ARN>",
    "Input": "{}"}

flex_window = { "Mode": "FLEXIBLE", "MaximumWindowInMinutes": 15}

scheduler.update_schedule(Name="your-schedule",
    ScheduleExpression="rate(1 hour)",
    Target=sqs_templated,
    FlexibleTimeWindow=flex_window)
```

# Configuring a schedule's dead-letter queue in EventBridge Scheduler
<a name="configuring-schedule-dlq"></a>

 Amazon EventBridge Scheduler supports dead-letter queues (DLQ) using Amazon Simple Queue Service. When a schedule fails to invoke its target, EventBridge Scheduler delivers a JSON payload containing invocation details and any response received from the target to an Amazon SQS standard queue that you specify. 

 The following topic refers to this JSON as a *dead-letter event*. A dead-letter event lets you troubleshoot issues with your schedule or targets. If you configure a retry policy for your schedule, EventBridge Scheduler delivers the dead-letter event it has exhausting the maximum number of retries you set. 

 The following topics describe how you can configure an Amazon SQS queue as a DLQ for your schedule, set up the permissions EventBridge Scheduler needs to deliver messages to Amazon SQS, and receive dead-letter events from the DLQ. 

**Topics**
+ [Create an Amazon SQS queue](#configuring-schedule-dlq-create-queue)
+ [Set up execution role permissions](#configuring-schedule-dlq-permissions)
+ [Specify a dead-letter queue](#configuring-schedule-dlq-console)
+ [Retrieve the dead-letter event](#configuring-schedule-dlq-dead-letter-event)

## Create an Amazon SQS queue
<a name="configuring-schedule-dlq-create-queue"></a>

 Before you configure a DLQ for your schedule, you must create a standard Amazon SQS queue. For instructions on creating a queue using the Amazon SQS console, see [Creating an Amazon SQS queue](https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/step-create-queue.html) in the *Amazon Simple Queue Service Developer Guide*. 

**Note**  
 EventBridge Scheduler does not support using a FIFO queue as your schedule's DLQ. 

 Use the following AWS CLI command to create a standard queue. 

```
$ aws sqs create-queue --queue-name queue-name
```

If successful, you'll see the `QueueURL` in the output.

```
{
    "QueueUrl": "https://sqs.us-west-2.amazonaws.com/123456789012/scheduler-dlq-test"
}
```

 After you've created the queue, note the queue ARN. You'll need the ARN when you specify a DLQ for your EventBridge Scheduler schedule. You can find your queue ARN in the Amazon SQS console, or by using the [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/sqs/get-queue-attributes.html#get-queue-attributes](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/sqs/get-queue-attributes.html#get-queue-attributes) AWS CLI command. 

```
$ aws sqs get-queue-attributes --queue-url your-dlq-url --attribute-names QueueArn
```

 If successful, you will see the queue ARN in the output. 

```
{
    "Attributes": {
        "QueueArn": "arn:aws:sqs:us-west-2:123456789012:scheduler-dlq-test"
    }
}
```

 In the next section, you will add the required permissions to your schedule execution role to allow EventBridge Scheduler to deliver dead-letter events to Amazon SQS. 

## Set up execution role permissions
<a name="configuring-schedule-dlq-permissions"></a>

 To let EventBridge Scheduler to deliver dead-letter events to Amazon SQS, your schedule execution role needs the following permission policy. For more information on attaching a new permission policy to your schedule execution role, see [Setting up the execution role](setting-up.md#setting-up-execution-role). 

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

****  

```
{
    "Version":"2012-10-17",		 	 	 
    "Statement": [
        {
            "Action": [
                "sqs:SendMessage"
            ],
            "Effect": "Allow",
            "Resource": "*"
        }
    ]
}
```

------

**Note**  
 Your schedule execution role might already have the required permissions attached if you use EventBridge Scheduler to invoke an Amazon SQS API target. 

 In the next section, you'll use the EventBridge Scheduler console and specify a DLQ for your schedule. 

## Specify a dead-letter queue
<a name="configuring-schedule-dlq-console"></a>

 To specify a DLQ, use the EventBridge Scheduler console or the AWS CLI to update an existing schedule, or create a new one. 

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

**To specify a DLQ using the console**

1. Sign in to the AWS Management Console, then choose the following link to open the EventBridge Scheduler section of the EventBridge conosle: [https://console.aws.amazon.com/scheduler/home](https://console.aws.amazon.com/scheduler/home) 

1.  On the EventBridge Scheduler console, create a new schedule, or choose an existing schedule from your list of schedules to edit. 

1.  On the **Settings** page, for **Dead-letter queue (DLQ)**, do one of the following: 
   +  Choose **Select an Amazon SQS queue in my AWS account as a DLQ**, then choose the queue ARN for your DLQ from the dropdown list. 
   +  Choose **Specify an Amazon SQS queue in other AWS accounts as a DLQ**, then enter the queue ARN for your DLQ. If you choose a queue in another AWS account, the EventBridge Scheduler console will not be able to display the queue ARNs in a dropdown list. 

1.  Review your selections, then choose **Create schedule** or **Save schedule** to finish configuring a DLQ. 

1.  (Optional) To view a schedule's DLQ details, choose the name of the schedule from the list, then choose the **Dead-letter queue** tab on the **Schedule detail** page. 

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

**To update an existing schedule using the AWS CLI**
+  Use the [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/scheduler/update-schedule.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/scheduler/update-schedule.html) command to update your schedule. Specify the Amazon SQS queue you created previously as the DLQ. Specify the IAM role ARN to which you attached the required Amazon SQS permissions as the execution role. Replace all other placeholder values with your information. 

  ```
  $ aws scheduler update-schedule --name existing-schedule \
      --schedule-expression 'rate(5 minutes)' \
      --target '{"DeadLetterConfig": {"Arn": "DLQ_ARN"}, "RoleArn": "ROLE_ARN", "Arn":"QUEUE_ARN", "Input": "Hello world!" }' \
      --flexible-time-window '{ "Mode": "OFF"}'
  ```

**To create a new schedule with a DLQ using the AWS CLI**
+  Use the [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/scheduler/create-schedule.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/scheduler/create-schedule.html) command to create a schedule. Replace all placeholder values with your information. 

  ```
  $ aws scheduler create-schedule --name new-schedule \
      --schedule-expression 'rate(5 minutes)' \
      --target '{"DeadLetterConfig": {"Arn": "DLQ_ARN"}, "RoleArn": "ROLE_ARN", "Arn":"QUEUE_ARN", "Input": "Hello world!" }' \
      --flexible-time-window '{ "Mode": "OFF"}'
  ```

------

 In the next section, you'll use the AWS CLI to receive a dead-letter event from the DLQ. 

## Retrieve the dead-letter event
<a name="configuring-schedule-dlq-dead-letter-event"></a>

 Use the [https://awscli.amazonaws.com/v2/documentation/api/latest/reference/sqs/receive-message.html](https://awscli.amazonaws.com/v2/documentation/api/latest/reference/sqs/receive-message.html) command, as shown in the following, to retrieve a dead-letter event from the DLQ. You can set the number of messages to retrieve using the `--max-number-of-messages` attribute. 

```
$ aws sqs receive-message --queue-url your-dlq-url --attribute-names All --message-attribute-names All --max-number-of-messages 1
```

 If successful, you will see output similar to the following. 

```
{
    "Messages": [
        {
            "MessageId": "2aeg3510-fe3a-4f5a-ab6a-6906560eaf7e",
            "ReceiptHandle": "AQEBkNKTdOMrWgHKPoITRBwrPoK3eCSZIcZwVqCY0BZ+FfTcORFpopJbtCqj36VbBTlHreM8+qM/m5jcwqSlAlGmIJO/hYmMgn/+dwIty9izE7HnpvRhhEyHxbeTZ5V05RbeasYaBdNyi9WLcnAHviDh6MebLXXNWoFyYNsxdwJuG0f/w3htX6r3dxpXvvFNPGoQb8ihY37+u0gtsbuIwhLtUSmE8rbldEEwiUfi3IJ1zEZpUS77n/k1GWrMrnYg0Gx/BuaLzOrFi2F738XI/Hnh45uv3ca6OYwS1ojPQ1LtX2URg1haV5884FYlaRvY8jRlpCZabTkYRTZKSXG5KNgYZnHpmsspii6JNkjitYVFKPo0H91w5zkHlSx3REAuWk7m3r7PmOMvTNPMhctbD3CkTw==",
            "MD5OfBody": "07adc3fc889d6107d8bb8fda42fe0573",
            "Body": "{\"MessageBody\":\"Hello, world!",\"QueueUrl\":\"https://sqs.us-west-2.amazonaws.com/123456789012/does-not-exist\"}",
            "Attributes": {
                "SenderId": "AROA2DZE3W4CTL5ZR7EIN:ff00212d8c453aaaae644bc6846d4723",
                "ApproximateFirstReceiveTimestamp": "1652499058144",
                "ApproximateReceiveCount": "2",
                "SentTimestamp": "1652490733042"
            },
            "MD5OfMessageAttributes": "f72c1d78100860e00403d849831d4895",
            "MessageAttributes": {
                "ERROR_CODE": {
                    "StringValue": "AWS.SimpleQueueService.NonExistentQueue",
                    "DataType": "String"
                },
                "ERROR_MESSAGE": {
                    "StringValue": "The specified queue does not exist for this wsdl version.",
                    "DataType": "String"
                },
                "EXECUTION_ID": {
                    "StringValue": "ad06616e51cdf74a",
                    "DataType": "String"
                },
                "EXHAUSTED_RETRY_CONDITION": {
                    "StringValue": "MaximumEventAgeInSeconds",
                    "DataType": "String"
                }
                "IS_PAYLOAD_TRUNCATED": {
                    "StringValue": "false",
                    "DataType": "String"
                },
                "RETRY_ATTEMPTS": {
                    "StringValue": "0",
                    "DataType": "String"
                },
                "SCHEDULED_TIME": {
                    "StringValue": "2022-05-14T01:12:00Z",
                    "DataType": "String"
                },
                "SCHEDULE_ARN": {
                    "StringValue": "arn:aws:scheduler:us-west-2:123456789012:schedule/DLQ-test",
                    "DataType": "String"
                },
                "TARGET_ARN": {
                    "StringValue": "arn:aws:scheduler:::aws-sdk:sqs:sendMessage",
                    "DataType": "String"
                }
            }
        }
    ]
}
```

 Note the following attributes in the dead-letter event to help you identify and troubleshoot possible reasons why target inovcation has failed. 
+  **`ERROR_CODE`** – Contains the error code that EventBridge Scheduler receives from the target's service API. In the preceding example, the error code returned by Amazon SQS is `AWS.SimpleQueueService.NonExistentQueue`. If the schedule fails to invoke a target due to an issue with EventBridge Scheduler, you'll see the following error code instead: `AWS.Scheduler.InternalServerError`. 
+  **`ERROR_MESSAGE`** – Contains the error message that EventBridge Scheduler receives from the target's service API. In the preceding example, the error message returned by Amazon SQS is `The specified queue does not exist for this wsdl version`. If the schedule fails due to an issue with EventBridge Scheduler, you'll see the following error message instead: `Unexpected error occurred while processing the request`. 
+  **`TARGET_ARN`** – The ARN of the target that your schedule invokes, in the following service ARN format: `arn:aws:scheduler:::aws-sdk:service:apiAction`. 
+  **`EXHAUSTED_RETRY_CONDITION`** – Indicates why the event was delivered to the DLQ. This attribute will be present if the error from the target API is a retryable error, and not a permanent error. The attribute can contain the values `MaximumRetryAttempts` if EventBridge Scheduler sent it to the DLQ after it exceeded the maximum retry attempts you configured for the schedule, or `MaximumEventAgeInSeconds`, if the event is older than the maximum age you configured on the schedule and is still failing to deliver. 

 In the preceding example, we can determine, based on the error code, and the error message, that the target queue we specified for the schedule does not exist. 

**Note**  
If you use [universal targets](managing-targets-universal.md), be aware that EventBridge Scheduler does not validate the contents of the `Input` field at schedule creation time. A schedule with invalid input parameters will be created successfully but will fail on every invocation. The DLQ message will contain the error code and message from the target service, which can help you identify the invalid parameter. For more information, see [Invalid universal target input configurations](troubleshooting.md#troubleshooting-usi-target-input).

# Deleting a schedule in EventBridge Scheduler
<a name="managing-schedule-delete"></a>

You can delete a schedule by either configuring automatic deletion, or by manually deleting an individual schedule. Use the following topics to learn how to delete a schedule using both methods, and why you might choose one method over the other.

**Topics**
+ [Deletion after schedule completion](#managing-schedule-automatic-deletion)
+ [Manual deletion](#managing-schedule-manual-deletion)

## Deletion after schedule completion
<a name="managing-schedule-automatic-deletion"></a>

Configure automatic deletion after schedule completion if you want to avoid having to individually manage your schedule resources on EventBridge Scheduler. In applications where you create thousands of schedules at a time and need flexibility to scale up the number of your schedules on demand, automatic deletion can ensure that you do not reach your account quota for the [number of schedules](scheduler-quotas.md) in a specified Region.

When you configure automatic deletion for a schedule, EventBridge Scheduler deletes the schedule after its last target invocation. For one-time schedules, this occurs after the schedule has invoked its target once. For recurring schedules you set up with rate, or cron, expressions, your schedule is deleted after its last invocation. A recurring schedule's last invocation is the invocation that occurs closest to the [https://docs.aws.amazon.com/scheduler/latest/APIReference/API_CreateSchedule.html#scheduler-CreateSchedule-request-EndDate](https://docs.aws.amazon.com/scheduler/latest/APIReference/API_CreateSchedule.html#scheduler-CreateSchedule-request-EndDate) you specify. If you configure a schedule with automatic deletion but do not specify a value for `EndDate`, EventBridge Scheduler does not automatically delete the schedule.

You can set up automatic deletion when you first create a schedule, or update preferences for an existing schedule. The following steps describe how to configure automatic deletion for an existing schedule.

------
#### [ AWS Management Console ]

1. Open the EventBridge Scheduler console at [https://console.aws.amazon.com/scheduler/](https://console.aws.amazon.com/scheduler/).

1.  From the list of schedules, select the schedule you want to edit, then choose **Edit**. 

1.  From the navigation list on the left, choose **Settings**. 

1.  In the **Action after schedule completion** section, select **DELETE** from the drop down list, then save your changes. 

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

1.  Open a new prompt window. 

1.  Use the [update-schedule]() AWS CLI command to update an existing schedule a shown in the following. The command sets the `--action-after-completion` to `DELETE`. This example assumes that you have defined your target configuration locally in a JSON file. To update a schedule, you must provide the target, as well as any other schedule parameters you want to configure for your existing schedule. 

    This is a recurring schedule with a rate of one invocation per hour. Therefore, you specify an end date when setting the `--action-after-completion` parameter. 

   ```
   $ aws scheduler update-schedule --name schedule-name \
   --action-after-completion 'DELETE' \
   --schedule-expression 'rate(1 hour)' \
   --end-date '2024-01-01T00:00:00'
   --target file://target-configuration.json \
   --flexible-time-window '{ "Mode": "OFF"}' \
   ```

------

## Manual deletion
<a name="managing-schedule-manual-deletion"></a>

 When you no longer need a schedule, you can delete it using the [https://docs.aws.amazon.com/scheduler/latest/APIReference/API_DeleteSchedule.html](https://docs.aws.amazon.com/scheduler/latest/APIReference/API_DeleteSchedule.html) operation. 

**Example AWS CLI**  

```
$ aws scheduler delete-schedule --name your-schedule
```

**Example Python SDK**  

```
import boto3
scheduler = boto3.client('scheduler')
    
scheduler.delete_schedule(Name="your-schedule")
```

## What's next?
<a name="managing-schedule-whats-next"></a>
+  For more information on how you can configure templated targets for Lambda and Step Functions, and to learn about using the universal target parameter, see [Managing targets in EventBridge Scheduler](managing-targets.md). 
+  For more information about the EventBridge Scheduler data types and API operations, see the [EventBridge Scheduler API Reference](https://docs.aws.amazon.com/scheduler/latest/APIReference/). 