Skip to main content

Campaigns

A campaign is an email you send to a selection of contacts in your account.

Overview

Each campaign has a name, a status that tracks where it is in its lifecycle, and the details of the message to send — its subject, preview text, sender, and audience. A campaign starts as a draft and is built up incrementally across update calls.

Endpoints

MethodEndpointDescription
GET/campaignsList campaigns
POST/campaignsCreate a campaign
GET/campaigns/{uuid}Get a campaign
PATCH/campaigns/{uuid}Update a campaign
DELETE/campaigns/{uuid}Delete a campaign
POST/campaigns/{uuid}/sendSend a campaign now
POST/campaigns/{uuid}/testSend a test email
POST/campaigns/{uuid}/scheduleSchedule a campaign
POST/campaigns/{uuid}/unscheduleUnschedule a campaign
POST/campaigns/{uuid}/cancelCancel a campaign
GET/campaigns/{uuid}/contactsList a campaign's live audience
GET/campaigns/{uuid}/recipientsList who a campaign was sent to
GET/campaigns/{uuid}/link-clicksList a campaign's link clicks

Statuses

A campaign's status tracks where it is in its lifecycle:

StatusMeaning
draftBeing edited. Not scheduled or sent.
scheduledScheduled to send at a future time.
queuedQueued for sending.
sendingCurrently being sent.
sentFully sent.
failedSending did not complete successfully.
canceledCanceled before it finished sending.

Editing and deleting by status

Which write operations a campaign allows depends on its status:

  • A campaign can be updated only while its status is draft, scheduled, or failed. Updating a campaign in any other status returns 409 CAMPAIGN_NOT_EDITABLE.
  • A campaign can be deleted only while its status is draft, sent, failed, or canceled. Deleting a campaign in any other status returns 409 CAMPAIGN_NOT_DELETABLE.

Sending lifecycle

Which lifecycle transition a campaign allows also depends on its status:

  • A campaign can be sent (Send Campaign) or scheduled (Schedule Campaign) only while its status is draft, failed, or scheduled, and only once it is ready (see Readiness). Any other status returns 409 CAMPAIGN_NOT_SENDABLE, and a campaign that is not ready returns 422 CAMPAIGN_NOT_READY.
  • A scheduled campaign can be unscheduled (Unschedule Campaign), returning it to draft. Any other status returns 409 CAMPAIGN_NOT_UNSCHEDULABLE.
  • A queued or sending campaign can be canceled (Cancel Campaign). Any other status returns 409 CAMPAIGN_NOT_CANCELABLE. A scheduled campaign is unscheduled, not canceled.

While one of these transitions is being processed for a campaign, a concurrent transition on the same campaign returns 409 CAMPAIGN_TRANSITION_IN_PROGRESS; retry after a moment.

To see who a campaign would send to right now, list its live audience with List Campaign Contacts. To see who a sent campaign was actually sent to and how each recipient engaged, use List Campaign Recipients.

Sending a test

Send a Test Email sends a one-off preview to a single address without changing the campaign's status, reaching its audience, or recording recipients, so it works from any status. It needs only a subject, a body, and a sender identity.

Audience

A campaign's audience is a contact list, a contact segment, or both. You set it with the list_uuid and segment_uuid fields on Create Campaign and Update Campaign, and read it back in the audience object:

FieldTypeDescription
list_uuidstring|nullUUID of the contact list the campaign sends to. null when not set.
segment_uuidstring|nullUUID of the contact segment the campaign sends to. null when not set.

A list_uuid or segment_uuid that does not belong to your account is rejected with 422 VALIDATION_ERROR.

Readiness

Every single-campaign response carries a readiness object describing whether the campaign is ready to send:

FieldTypeDescription
can_sendbooleantrue only when every requirement is met (missing is empty).
missingarrayThe requirements not yet met.

Each entry in missing names a requirement and how to satisfy it:

RequirementHow to satisfy
from_nameSet from_name on the campaign.
sender_emailSet from_identity to an enabled sender identity.
subjectSet subject on the campaign.
contentSet the email body with the content field (Markdown) on Create Campaign or Update Campaign, or build it in the dashboard. See Campaign body.
audienceSet list_uuid and/or segment_uuid.

A campaign with no body lists content in missing, and can_send reports false until the body is set. Once a body is set, content drops out of missing.

Campaign object

Create, Get, and Update return the full campaign object:

FieldTypeDescription
uuidstringUnique identifier for the campaign
namestringCampaign name
statusstringCurrent status (see Statuses)
subjectstring|nullEmail subject line. null until set.
preheaderstring|nullPreview text shown after the subject in the inbox. null until set.
from_namestring|nullSender display name. null until set.
reply_tostring|nullReply-to email address. null until set.
from_identitystring|nullUUID of the sending identity the campaign sends from. null until set.
from_emailstring|nullEmail address of the selected sending identity. null when no identity is set.
contentstring|nullThe email body as Markdown, or null — either no body is set, or the body uses layout with no Markdown form (distinguish via content_editable_via_api). See Campaign body.
content_editable_via_apibooleanfalse when the body uses layout the API can't author (see Campaign body).
content_overwrite_requiredbooleantrue when replacing the body with content requires overwrite: true (see Campaign body).
audienceobjectThe campaign's recipients (see Audience).
readinessobjectWhether the campaign is ready to send (see Readiness).
created_atstringISO 8601 timestamp (UTC)
updated_atstringISO 8601 timestamp (UTC)
last_updated_atstring|nullISO 8601 timestamp (UTC) the campaign was last edited.

The List Campaigns endpoint returns a condensed version of each campaign: it omits preheader, reply_to, from_identity, from_email, content, content_editable_via_api, content_overwrite_required, audience, readiness, and last_updated_at, and instead includes language, scheduled_at, and recipients_count.

Campaign body

The campaign body is the email's content. Set it with the content field on Create Campaign and Update Campaign, read it back in the content field, and send content: null to clear it. The body can also be edited in the dashboard.

Writing the body

content is a Markdown string, up to 65000 characters. Supported:

  • Headings (levels 1–6)
  • Bold and italic text
  • Links
  • Bullet and numbered lists
  • Blockquotes
  • Fenced and indented code blocks
  • Images
  • Horizontal rules (---)
  • Hard line breaks

Tables, strikethrough, task lists, inline `code`, and raw HTML are not supported — they are silently dropped or flattened to plain text, so stick to the supported subset.

Reading the body back

content returns the stored body as Markdown, or null when no body is set or the body uses layout that has no Markdown form. Two flags describe whether that body can be rewritten through the API:

FieldTypeDescription
content_editable_via_apibooleanfalse when the body uses layout the API can't author (multi-column layouts, social-icon rows, countdown timers); the returned content is then a lossy approximation.
content_overwrite_requiredbooleantrue when the existing body carries formatting Markdown can't preserve — the layout above, or styling such as custom colors, fonts, buttons, or styled images.

When both flags are false, the body is plain enough to overwrite freely.

Overwriting a richer body

To replace a body that reports content_overwrite_required: true, set overwrite: true on your Update Campaign call — this permanently discards the existing styling or layout. Without it, the write is rejected with 409 CONTENT_OVERWRITE_REQUIRED. A body that is content_editable_via_api: false can only be changed by editing it in the dashboard, or by passing overwrite: true to replace it with Markdown.