A campaign is one newsletter send: content, a subject, a template, and the lists it goes to.
campaign.create { title, description?, organizationId }— starts inDRAFT.campaign.update— setsubject,content,templateId,listIds,openTracking,scheduledAt. OnlyDRAFTcampaigns can be updated; anything else returnsBAD_REQUEST.campaign.sendTestEmail { campaignId, organizationId, email }— sends one copy with a[Test]subject prefix. Placeholders are not substituted in a test email.campaign.start { id, organizationId }.
campaign.start refuses unless all of these hold:
- status is
DRAFT - SMTP settings exist for the organization
- email delivery settings exist
subjectis setcontentis not empty- at least one list is attached, with at least one subscribed recipient
baseURLis set in general settings
| Status | Meaning |
|---|---|
DRAFT |
Editable. The only status you can start from |
SCHEDULED |
start was called with a future scheduledAt |
CREATING |
Messages are being generated, 100 subscribers per pass |
SENDING |
Every message exists; the sender cron is working through them |
COMPLETED |
No message is left queued or retrying |
CANCELLED |
Cancelled by hand |
start picks SCHEDULED when scheduledAt is in the future and CREATING otherwise. A SCHEDULED campaign moves to CREATING within a second of scheduledAt passing. A CREATING campaign with no recipients left to build moves to SENDING. Message generation and delivery are covered in sending.md.
campaign.cancel works from CREATING, SENDING or SCHEDULED. It marks the campaign CANCELLED and flips every QUEUED, PENDING or RETRYING message to CANCELLED. No further messages are built or sent for it, including messages from a build batch still in flight. Messages already handed to SMTP are not recalled.
campaign.duplicate copies title (prefixed Copy of ), description, subject, content, template, lists and openTracking into a new DRAFT. Messages and stats are not copied.
campaign.delete deletes the campaign's messages and then the campaign, in one transaction.
campaign.list paginates with search across title, description and subject. campaign.get returns the campaign plus per-list active subscriber counts, a deduplicated uniqueRecipientCount, and stats: total, queued, pending, sent, failed, processed, opened, clicked, plus open and click rate as percentages of sent.
Content is HTML written in the campaign editor. It can use every placeholder in placeholders.md and the @TRACK link suffix from tracking.md. openTracking (default true) controls the open pixel.