> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sequenzy.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Recurring Schedule

> Re-enroll an audience into a sequence every day, week or month

Make a manual-trigger sequence recurring. A recurring schedule enrolls an audience again and again: daily, on chosen weekdays, or on chosen days of the month, at a time in your timezone. Use it for sends that are not tied to an event, such as end-of-month updates, balance reminders or a daily digest.

* Each run is an [audience enrollment run](https://docs.sequenzy.com/api-reference/sequences/audience-enrollments.md) with `source: "recurring"`. The audience is evaluated again at every run.
* Contacts who finished an earlier run enter again. Contacts still in the sequence from an earlier run are skipped. Sequences with `enrollmentMode: "one_time"` never enroll anyone twice.
* Unsubscribed and bounced contacts are never enrolled.
* Nothing is enrolled until the first scheduled time.
* Runs only happen while the sequence is enabled and accepting entrants. Occurrences while it is paused, disabled or closed to new entrants are skipped.
* A run waits while another audience enrollment is in progress. A run that cannot start within 6 hours of its time is skipped.
* Only sequences with `trigger: "manual"` accept a schedule, and not while `audienceAutoEnroll` (keep enrolling later joiners) is on. Changing the trigger away from manual switches the schedule off.

Saving replaces any existing schedule. Saving the same schedule again keeps the pending next run.

## Request

**sequenceId** `string` *required*

Sequence ID.

**audience** `object` *required*

Who to enroll at each run. Same shape as the `audience` of [Enroll Audience](https://docs.sequenzy.com/api-reference/sequences/enroll-audience.md): `{ "type": "all" }`, `{ "type": "lists", "listIds": [...] }`, `{ "type": "segment", "segmentId": "..." }`, `filtered` or `rules`.

**schedule** `object` *required*

When to run.

**Schedule fields**

**frequency** `string` *required*

`daily`, `weekly` or `monthly`.

**weekdays** `integer[]`

Required for `weekly`. Days to run, from `0` (Sunday) to `6` (Saturday). `[1, 2, 3, 4, 5]` is every weekday.

**monthDays** `(integer | string)[]`

Required for `monthly`. Days `1` to `31` and/or `"last"` for the last day of the month. A day past the end of a shorter month runs on its last day, so `31` runs on February 28 (or 29).

**time** `string` *required*

24-hour time, `"HH:MM"`. A time skipped by a daylight saving change runs just after the gap.

**timezone** `string` *required*

IANA timezone such as `Europe/London` or `UTC`. Runs stay at the same local time when daylight saving starts or ends. Offsets like `+02:00` are rejected.

**enabled** `boolean` (default: true)

Pass `false` to keep the schedule but stop its runs.

**endsAt** `string | null`

ISO 8601 date-time after which no run starts, such as the end of the last day in the schedule's timezone. Omitted or `null` means no end date; since saving replaces the schedule, leaving it out removes an earlier end date. Rejected when no run would happen before it. Once the last run before it has started, `nextRunAt` becomes `null`.

**enrollmentMode** `string`

Who enters at each run, saved as the sequence's enrollment mode: `unlimited` (everyone who matches; people still in the sequence are skipped) or `one_time` (only people who never entered). The mode also applies to enrollments you start by hand. Omit to keep the current mode.

```bash theme={null}
curl -X PUT "https://api.sequenzy.com/api/v1/sequences/seq_abc123/recurring-enrollment" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "audience": { "type": "segment", "segmentId": "seg_members" },
    "schedule": {
      "frequency": "monthly",
      "monthDays": [1, "last"],
      "time": "10:00",
      "timezone": "Europe/London"
    },
    "endsAt": "2027-06-30T23:59:00+01:00",
    "enrollmentMode": "unlimited"
  }'
```

Read the schedule:

```bash theme={null}
curl "https://api.sequenzy.com/api/v1/sequences/seq_abc123/recurring-enrollment" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

Remove it. Runs already started and contacts already enrolled are not affected, and removing a schedule that does not exist succeeds:

```bash theme={null}
curl -X DELETE "https://api.sequenzy.com/api/v1/sequences/seq_abc123/recurring-enrollment" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

`GET` needs the `sequences:read` scope; `PUT` and `DELETE` need `sequences:write`.

## Response fields

`recurringEnrollment` is the stored schedule, or `null` when there is none:

* `enabled`, `audience`, and `schedule` (with `weekdays` and `monthDays` sorted, and empty for frequencies that do not use them)
* `enabledAt`: when the schedule was last switched on or changed
* `nextRunAt`: the next occurrence, or `null` while switched off
* `lastRunAt` and `lastRunId`: the most recent run that started and its audience enrollment run ID
* `lastSkippedAt` and `lastSkipReason`: the most recent skipped occurrence, with `not_accepting` (the sequence was paused, disabled or closed to new entrants) or `missed` (the run could not start within 6 hours)
* `endsAt`: no run starts after it, or `null`

`enrollmentMode` is the sequence's enrollment mode, which decides who enters at each run.

`description` is a readable summary such as `Monthly on the 1st and the last day at 10:00 (Europe/London)`. `upcomingRuns` lists the next five run times, and is empty while the schedule is off. Writes also return a `message`.

The schedule is also returned as `recurringEnrollment` by [Get Sequence](https://docs.sequenzy.com/api-reference/sequences/get.md) and [List Sequences](https://docs.sequenzy.com/api-reference/sequences/list.md).

## Responses

```json 200 theme={null}
{
  "success": true,
  "recurringEnrollment": {
    "enabled": true,
    "audience": { "type": "segment", "segmentId": "seg_members" },
    "schedule": {
      "frequency": "monthly",
      "weekdays": [],
      "monthDays": [1, "last"],
      "time": "10:00",
      "timezone": "Europe/London"
    },
    "enabledAt": "2026-11-04T09:00:00.000Z",
    "nextRunAt": "2026-11-30T10:00:00.000Z",
    "lastRunAt": null,
    "lastRunId": null,
    "lastSkippedAt": null,
    "lastSkipReason": null,
    "endsAt": "2027-06-30T22:59:00.000Z"
  },
  "enrollmentMode": "unlimited",
  "description": "Monthly on the 1st and the last day at 10:00 (Europe/London)",
  "upcomingRuns": [
    "2026-11-30T10:00:00.000Z",
    "2026-12-01T10:00:00.000Z",
    "2026-12-31T10:00:00.000Z",
    "2027-01-01T10:00:00.000Z",
    "2027-01-31T10:00:00.000Z"
  ],
  "message": "Monthly on the 1st and the last day at 10:00 (Europe/London). First run: 2026-11-30T10:00:00.000Z. Each run enrolls the audience again; contacts still in the sequence from an earlier run are skipped."
}
```

```json 400 theme={null}
{
  "error": "Recurring enrollment is only available for manual-trigger sequences; other triggers already enroll contacts on their own."
}
```

```json 400 (invalid schedule) theme={null}
{
  "error": "Monthly schedules need monthDays: a non-empty array of days 1 to 31 and/or \"last\""
}
```

```json 401 theme={null}
{
  "error": "Invalid API key"
}
```

```json 404 theme={null}
{
  "error": "Sequence not found"
}
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.