PlunkPlunk
Concepts

Campaigns

One-off broadcast emails sent to a defined audience

Campaigns are one-off email sends to a defined audience — newsletters, announcements, product launches, promotions. Unlike workflows, a campaign sends once at a single point in time (immediately or at a scheduled time) and is then frozen.

Anatomy of a campaign

A campaign captures everything needed to render and deliver one batch of emails:

Prop

Type

The campaign also keeps denormalised stats once it sends: totalRecipients, sentCount, deliveredCount, openedCount, clickedCount, bouncedCount. Fetch them via GET /campaigns/:id/stats.

Targeting an audience

Campaigns support three audience types:

  • ALL — every subscribed contact in the project. Quick way to broadcast to your full list.
  • SEGMENT — every contact that's currently a member of a specific segment. Reuses logic you've already built.
  • FILTERED — an inline filter condition (same JSON shape as segment filters). Lets you hand-craft an audience for a one-off send without saving a reusable segment.

MARKETING and HEADLESS campaigns automatically skip unsubscribed contacts. TRANSACTIONAL campaigns deliver to everyone matching the audience regardless of subscription state — use it sparingly and only for genuine transactional content.

Sender domain verification

The from address must be on a domain you've verified for sending. Creating or updating a campaign with an unverified from returns 403. See Verifying domains.

Lifecycle

StatusMeaning
DRAFTCreated but not yet scheduled or sent. Editable.
SCHEDULEDScheduled for a future time via scheduledFor. Cancellable.
SENDINGSend is in progress — the queue is processing recipients.
SENTSend is complete. Stats are final.
CANCELLEDCancelled before completion. Terminal state from DRAFT, SCHEDULED, or SENDING.

Once a campaign is SENT or CANCELLED it can't be edited or resent — duplicate it instead with POST /campaigns/:id/duplicate to create an editable copy.

Sending and scheduling

Trigger a send with POST /campaigns/:id/send. The campaign is queued and sent in the background; depending on the audience size, this can take seconds for small lists to longer for very large ones. You can monitor progress on the campaign detail page in the dashboard.

To cancel a SCHEDULED or SENDING campaign, call POST /campaigns/:id/cancel. Cancellation stops further sending but cannot recall emails that have already been handed off to the recipient's mail server.

Stats

GET /campaigns/:id/stats reports the counts and rates the dashboard shows: recipients, sent, delivered, opened, clicked, bounced, complained, and unsubscribed, plus the matching rates. Counts are recomputed from the underlying emails and events on every call, so they are authoritative rather than eventually consistent. Every rate is a percentage of sentCount.

What a campaign cost you

Three columns describe recipients you lost, and each one counts a given recipient exactly once:

FieldMeansTraced by
bouncedCountMail that could not be delivered. Hard bounces suppress the contact.Email.bouncedAt, set by the SES bounce webhook
complainedCountRecipients who reported the campaign as spam. Suppresses the contact.Email.complainedAt, set by the SES complaint webhook
unsubscribedCountRecipients who deliberately opted out.The ?e= parameter on the unsubscribe link

Bounces and complaints flip the contact to unsubscribed as well, but they are reported in their own column and never in unsubscribedCount — the same lost recipient counted twice would overstate both.

unsubscribedCount also excludes opt-outs it cannot attribute: a dashboard toggle, a CSV import, PATCH /contacts/:id, or a link from mail sent before the parameter existed belongs to no campaign, so it is counted against none. See Unsubscribe pages.

Complaint rate deserves attention out of proportion to its size: mailbox providers measure it in fractions of a percent, and a sustained rate above roughly 0.1% puts sending at risk. A handful of complaints on one campaign is a signal worth acting on, which is why the dashboard leads that card with the count rather than the percentage.

Test sends

Send a single test email with POST /campaigns/:id/test. Body: { email: "you@example.com" } — a single address, not an array. Test sends use the same template variable resolution as the real send but always send to the address you specify, so they're useful for previewing personalisation against your own contact data.

Duplicating

POST /campaigns/:id/duplicate creates a new DRAFT campaign with the same content, audience, and settings as the source. Useful for A/B variants and recurring sends.

API reference

See the API overview for the full set of campaign endpoints — list, get, create, update, delete, send, cancel, duplicate, test, and stats.

What's next