---
title: "Schedule campaign"
method: POST
path: "/campaigns/{campaignId}/schedule"
tags: ["Campaigns"]
---

# Schedule campaign

`POST /campaigns/{campaignId}/schedule`

Schedules a draft or already scheduled campaign for a future send time. Requires a verified sending domain. Campaigns that require safety review are held in waiting_approval and scheduled after a reviewer approves them. A waiting_approval result is a normal 200 outcome and is most common on new accounts and recently registered sending domains; retrying the schedule call does not clear the hold, so branch on campaign.status and poll GET /campaigns/{campaignId} instead. See https://docs.sequenzy.com/concepts/campaigns#safety-review

## Path parameters

- `campaignId` string, required

## Request body

- object
  - `scheduledAt` string, date-time, required — Future send time.
  - `targetLists` object — Optional targeting object. Omit to reuse saved targeting - or, when none is saved, ALL active subscribers. The object is a union discriminated on type: {"type":"all"}, {"type":"lists","listIds":["list_123"]}, {"type":"segment","segmentId":"seg_123"}, {"type":"filtered","filters":[],"filterJoinOperator":"and"}, {"type":"rules","include":[],"exclude":[]}. Mutually exclusive with listIds.
  - `listIds` string[] — Shorthand for sending to one or more lists. Equivalent to `targetLists` `{"type":"lists","listIds":["list_123"]}`. Mutually exclusive with targetLists.
  - `sendTimeOptimization` boolean — Whether to use send-time optimization.
  - `spreadOverHours` number, nullable — Spread delivery over this many hours. When set, spread delivery takes precedence over send-time optimization.
  - `sendInRecipientTimezone` boolean — Deliver at scheduledAt's wall-clock time in each recipient's own timezone. Requires scheduledTimezone. Contacts without a stored timezone receive the campaign at scheduledAt itself. Not combinable with recurringInterval or spreadOverHours. Omitting it on a reschedule preserves the campaign's existing setting; send false to turn it off.
  - `scheduledTimezone` string, nullable — IANA timezone the scheduledAt wall-clock time refers to, for example America/New_York. Required with sendInRecipientTimezone.
  - `recurringInterval` 'weekly' | 'monthly', nullable — Repeat the campaign on a cadence starting at scheduledAt. The campaign becomes a recurring template - each run is duplicated and sent automatically, re-evaluating audience membership every time. Omit or send null for a one-shot send; scheduling again without it stops the recurrence.

## Response `200`

Campaign scheduled successfully

- object
  - `success` boolean, required
  - `message` string — Scheduling result message. If the campaign requires review, it is held in waiting_approval instead of queueing a send job.
  - `scheduledAt` string, date-time, required
  - `jobId` string, nullable
  - `previewUrl` string, uri, required
  - `campaign` object, required
    - `id` string
    - `name` string
    - `subject` string
    - `status` 'scheduled' | 'waiting_approval' — `scheduled` when the send job was queued. `waiting_approval` when the campaign was held for safety review - common on new accounts and recently registered sending domains - in which case no send job is queued and jobId is omitted.
    - `labels` string[]
    - `scheduledAt` string, date-time
    - `sendInRecipientTimezone` boolean — Whether delivery follows each recipient's local wall clock.
    - `scheduledTimezone` string, nullable — IANA timezone that anchors scheduledAt's wall-clock time.
    - `url` string, uri
    - `previewUrl` string, uri

## Other responses

- `400` — Validation error, invalid schedule time, or unverified sending domain
- `401` — Unauthorized
- `404` — Campaign or sender profile not found
- `409` — Campaign is no longer editable

---

[API](https://skmtc.net/sequenzy/apis/sequenzy-api.md) · [All operations](https://skmtc.net/sequenzy/apis/sequenzy-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/sequenzy/sequenzy-api/revisions/8fbabe82a04d/schema)
