# Create a schedule in the Unity Dashboard

> Create scheduled events that fire once, on a recurring cadence, or on a fixed interval using the graphical interface of the Unity Dashboard.

The [Unity Dashboard](https://cloud.unity.com) provides a graphical interface for creating schedules. To open the schedules list, select **Triggers** > **Schedules** and choose an [environment](/services/service-environments.md).

A schedule emits a custom event on a set date or a recurring cadence. Any trigger that listens for that event receives the schedule's payload and can filter on it the same way it filters any other event. To view, inspect, or delete schedules after you create them, refer to [Manage your schedules](./manage-schedules.md).

> **Note:**
>
> To create and manage schedules in the Unity Dashboard, you need one of the following [roles](/cloud/organizations/members-groups-roles.md#assign-roles):
>
> * **Scheduler Configuration Viewer**: View the schedules list and schedule details (`scheduler.configs.get`, `scheduler.configs.list`). Every create and delete control is disabled for this role.
> * **Scheduler Configuration Editor**: Also create and delete schedules (`scheduler.configs.create`, `scheduler.configs.delete`).

## Create a schedule

You can't change a schedule after you create it. The schedule is live as soon as you create it, but only fires according to the cadence and firing window you configure.

To create a schedule, select **New schedule** in the schedules list, or **Create your first schedule** if the environment has none. Without create access, both buttons are disabled. The create dialog is a two-step wizard: complete the **Details** step, then the **Payload** step. Use **Back** and **Next** to move between steps, select **Documentation** to open the Triggers documentation, and select the **X** in the title bar to close the dialog without creating a schedule.

### Details

The **Details** step names the schedule and defines how it fires. To define the schedule, follow these steps:

1. In **Name**, enter a name for the schedule. The name must be unique among existing schedules and can't exceed 255 characters. If a schedule with the same name already exists, an error blocks you from continuing.
2. In **Event name**, enter the identifier that triggers listen for. This field autofills from the schedule name as a slug (for example, `Weekly Sale` becomes `weekly-sale`) and mirrors the name until you edit it directly. If you reuse an event name that other schedules already use, this schedule emits the same event, so the same triggers fire for it. For more information, refer to [Payload versioning](#payload-versioning).
3. Under **Select the type of schedule**, select one of the following options:
   * **Recurring**: Fires repeatedly on a schedule you define.
   * **Interval**: Fires on a fixed period like every 2 weeks.
   * **One-time**: Fires once, at a specific date and time.
4. In the setup card that appears, configure the schedule for the type you selected:
   * For a recurring schedule, refer to [Configure a recurring schedule](#configure-a-recurring-schedule).
   * For an interval schedule, refer to [Configure an interval schedule](#configure-an-interval-schedule).
   * For a one-time schedule, refer to [Configure a one-time schedule](#configure-a-one-time-schedule).
5. Check the [Summary](#review-the-summary) card at the bottom of the step, then select **Next**.

#### Configure a recurring schedule

A recurring schedule fires on a cadence that you define either with simple controls or with a cron expression. Selecting **Recurring** reveals the **Setup repeat** card, which holds the cadence fields and the firing window.

To set the cadence, follow these steps:

1. In the card header, select **Builder** to define the cadence with simple controls, or **Expression** to write your own cron schedule for full control. The card confirms the mode you selected below the toggle.
2. Set the cadence for the mode you selected:
   * **Builder**: Set **Frequency** to **Hourly**, **Daily**, **Weekly**, or **Monthly**. For a weekly frequency, select a **Day of week**. For a monthly frequency, enter a **Day of month** between 1 and 31; if you choose day 29, 30, or 31, the schedule skips months that don't have that day, such as February. For any non-hourly frequency, set a **Time (UTC)**. An hourly frequency hides the day and time fields.
   * **Expression**: Enter a five-part cron expression, evaluated in UTC. Use the [crontab.guru](https://crontab.guru) link for help with cron syntax.
3. Optionally, set a firing window below the cadence. Refer to [Set the firing window](#set-the-firing-window).

#### Configure an interval schedule

An interval schedule fires on a fixed period, such as every 6 hours or every 2 weeks. Use it when the time between fires matters more than the time of day, or to express a cadence that a recurring schedule can't, such as every 2 weeks.

Interval fires happen on UTC-aligned boundaries: exact multiples of the interval measured from a fixed epoch (January 1, 1970 at 12:00 AM UTC), not from when you create the schedule or from its start date. For example, a 1-week interval fires on Thursdays at 12:00 AM UTC, because the epoch fell on a Thursday, and a 6-hour interval fires at 12:00 AM, 6:00 AM, 12:00 PM, and 6:00 PM UTC.

Selecting **Interval** reveals the **Setup repeat** card. To set the interval, follow these steps:

1. In **Every**, enter the number of units in one interval. The minimum is 1, and invalid input resets to 1 when you leave the field. If the field is empty or below 1, creation fails with `Enter how often this should fire (at least 1)`.
2. In **Unit**, select the unit of time between fires: **Hours**, **Days**, or **Weeks**. The field's tooltip restates the boundary behavior: **The unit of time between fires. Fires land on UTC-aligned boundaries, not a time you pick — the summary below shows the next fire.**
3. Optionally, set a firing window below the interval. Refer to [Set the firing window](#set-the-firing-window). A start date doesn't change the rhythm; it only delays the first fire to the first UTC-aligned boundary at or after it.

> **Note:**
>
> An interval schedule has no time-of-day, day-of-week, or day-of-month picker, because fires align to the epoch rather than to clock times you choose. A start date doesn't set the phase: a 1-week interval that starts on a Monday at 9:00 AM still fires on the next Thursday at 12:00 AM UTC, not on Mondays. To fire on a specific weekday or time, use a recurring schedule instead.

#### Configure a one-time schedule

A one-time schedule fires once and has no firing window. Selecting **One-time** reveals the **No repeat** card, which holds a single **Start date** field.

**Start date** reads **Start immediately** until you change it. If you leave it on that preset, the schedule fires within about a minute of creation. To fire at a moment you choose instead, follow these steps:

1. Open the **Start date** dropdown.
2. Select **On a specific date…** to open a date-time picker.
3. Pick a future date and time. To return the field to **Start immediately**, clear the picked date.

The field's helper text reads **Target a start date**, and its tooltip explains both options: **The UTC date and time this schedule fires, once. Start immediately fires right after creation.** The date you pick is in your local time; refer to [Understand time zones](#understand-time-zones).

#### Set the firing window

A firing window limits when a recurring or interval schedule is active. One-time schedules don't have one.

The window fields sit below the cadence in the **Setup repeat** card, under the note **Time window permitted for schedule to work. Leave blank for an unlimited time window.** Both fields start on a preset: **Start date** reads **Start immediately**, and **End date** reads **Run indefinitely**.

To set a bound, follow these steps:

1. Open the **Start date** or **End date** dropdown.
2. Select **On a specific date…** to open a date-time picker.
3. Pick a date and time. To return the field to its preset, clear the picked date.

Each bound is independent and only needs to be in the future when you set it. The following table describes how the bounds control when the schedule is active:

| Bounds          | Behavior                                           |
| --------------- | -------------------------------------------------- |
| Neither         | Active immediately, until you delete the schedule. |
| Start date only | Active from the start date, until you delete it.   |
| End date only   | Active immediately, until the end date.            |
| Both            | Active only within the range.                      |

When you set both bounds, the end must be after the start, or creation fails with `End date must be after the start date`. For a recurring schedule, the window must also close after the schedule's first fire, or creation fails with `End date is before this schedule's first fire, so it would never run`.

That second check applies only to recurring schedules, because the service rejects such a configuration. An interval schedule whose window closes before its first fire is valid to save, so the [Summary](#review-the-summary) card warns you about it instead of blocking creation.

#### Understand time zones

Date-time pickers display and accept your local time, but the Scheduler service stores every schedule in UTC. When you pick a date, the field's helper text shows the stored value, for example **Shown in your local time. Saves as Oct 31, 2026, 12:00 AM UTC.**

The recurring **Time (UTC)** field is the exception: it's an explicit UTC time of day rather than a local time, because cron expressions run on UTC days. The field label states this.

#### Review the summary

A **Summary** card at the bottom of the **Details** step describes the configuration in plain language and updates as you edit the fields. For example, a daily recurring schedule with an end date reads **This schedule starts now and runs until Oct 31, 2026, 12:00 AM UTC (80 days). It fires every day at 09:00 AM.**

If the cadence and the firing window barely intersect, or never intersect, the card border turns orange and the summary appends one of the following sentences:

* **With this cadence it fires only once within the window.**
* **With this cadence it never fires within the window.**

This warning is advisory and doesn't block creation, because both configurations are valid to save.

### Payload

To define the event payload, follow these steps:

1. Optionally, in **Payload**, enter a JSON payload to send with the event. The payload must be a JSON object and can't exceed 1 KB. The Dashboard rejects a top-level array or bare value with the error `Payload must be a JSON object, not an array or a single value`. To pretty-print valid JSON, select **Format JSON**, aligned to the right of the **Payload** label. This button is available only when the content is valid JSON.
2. Select **Create**.

A success message confirms the schedule is created, and the schedule appears in the list.

## Payload versioning

Versioning is automatic and hidden from you. There's no version field, and the `v1` suffix stays hidden wherever versions appear.

Each event name has a single payload version, its `v1` contract, which defines the shape of the payload that triggers receive:

* A new event name starts at `v1`.
* Reusing an existing event name makes the new schedule emit that same event, rather than creating a new version. Every schedule that shares an event name feeds the triggers that listen for it, so one trigger can receive events from many schedules.

When you reuse an event name, an informational note on the **Details** step tells you the event is already in use by other schedules and that triggers listening for it fire for this schedule too.

To publish a different payload shape, use a different event name. Each name has its own `v1` contract.

> **Note:**
>
> Each schedule name must be unique, even when several schedules share an event name.

## Additional resources

* [Manage your schedules](./manage-schedules.md)
* [Schedule events with the CLI](./cli.md)
* [Schedule events with the REST API](./rest-api.md)
* [Define triggers](/triggers/tutorials/define-triggers.md)
* [Timers in Stateful Cloud Code](/cloud-code/stateful-cloud-code/timers.md)
