Campaigns

One off broadcast emails to a list, segment or tag. Draft, test, send now or schedule, pause and cancel, all from the API.

The campaign object

FieldTypeDescription
idstringStarts with cmp_.
name, subject, preheaderstringName is internal. Subject and preheader are what recipients see.
from_address, reply_tostringA sender on a verified domain, such as Acme <hello@acme.com>. Each at most 200 characters.
documentobjectThe email document. A campaign needs at least one block.
audienceobject | null{ "kind": "list", "id" }, { "kind": "segment", "id" } or { "kind": "tag", "name" }.
statusstringdraft, scheduled, sending, paused, sent or canceled.
scheduled_at, started_at, finished_atstring | nullISO 8601.
recipients_total, sent_count, suppressed_count, deferred_count, unsubscribed_count, failed_countintegerCounters while and after sending.

Create, test and send

# 1. Draft from a design (or {"kind":"blank"}, or {"kind":"copy","campaign_id":"cmp_..."}).
curl -X POST https://api.runearc.com/v1/campaigns \
  -H "Authorization: Bearer $RUNEARC_API_KEY" -H "Content-Type: application/json" \
  -d '{ "name": "November update", "start": { "kind": "design", "slug": "product-update" } }'

# 2. Fill in what is missing.
curl -X PATCH https://api.runearc.com/v1/campaigns/$ID \
  -H "Authorization: Bearer $RUNEARC_API_KEY" -H "Content-Type: application/json" \
  -d '{ "subject": "What shipped in November", "from_address": "Acme <hello@acme.com>",
        "audience": { "kind": "segment", "id": "seg_..." } }'

# 3. Test, then send now ({}) or later.
curl -X POST https://api.runearc.com/v1/campaigns/$ID/test \
  -H "Authorization: Bearer $RUNEARC_API_KEY" -H "Content-Type: application/json" \
  -d '{ "to": ["you@example.com"] }'
curl -X POST https://api.runearc.com/v1/campaigns/$ID/send \
  -H "Authorization: Bearer $RUNEARC_API_KEY" -H "Content-Type: application/json" \
  -d '{ "scheduled_at": "2026-12-01T09:00:00Z" }'

Only a draft can be edited or sent. Sending needs a subject, a from address, at least one block and an audience, otherwise campaign_incomplete names the missing part (subject, sender, content or audience). A scheduled send must be in the future and within 30 days; sending again with a new scheduled_at reschedules a scheduled campaign. Tests go to 1 to 5 addresses, with a [Test] subject prefix and sample variables.

Recipients are the audience's contacts that are active. Each goes through the marketing send path: the unsubscribe link and header, suppressions, the frequency cap and tracking all apply (see Tracking), and plan limits and an automatic sending pause stop the send. Sent mail carries a campaign id, so Analytics can break results down by campaign. Mail already handed to the transport is not recalled by pause or cancel.

RequestBodyReturns
GET /v1/campaigns?status=Campaigns.
GET /v1/campaign-designsnoneEight starting designs: product-update, newsletter, announcement, launch, event-invite, promo, changelog, plain-note.
POST /v1/campaignsname, start: {kind: blank | design | copy, ...}201 and the draft.
GET /v1/campaigns/{id}noneThe campaign with counters.
PATCH /v1/campaigns/{id}name, subject, preheader, from_address, reply_to, document, audienceThe draft.
DELETE /v1/campaigns/{id}none204. Drafts and canceled campaigns only.
POST /v1/campaigns/{id}/testto: 1 to 5 addressesdata: the test emails, with ids.
POST /v1/campaigns/{id}/send{} or scheduled_atThe campaign, now sending or scheduled.
POST /v1/campaigns/{id}/pause, resume, cancelnoneThe campaign.
Campaigns need a key or role that can send, so a key limited to one inbox cannot use them. The sender must be on a domain you verified; see Domains.

CLI and MCP

runearc campaign designs
runearc campaign new "November update" --design product-update      # or --copy cmp_...
runearc campaign edit cmp_... --subject "What shipped" --from "Acme <hello@acme.com>" --segment seg_...
runearc campaign test cmp_... --to you@example.com
runearc campaign send cmp_...                                         # --at 2026-12-01T09:00:00Z
runearc campaign pause | resume | cancel | delete cmp_...
runearc campaign list --status sending
runearc campaign show cmp_...

MCP tools: list_campaigns, list_campaign_designs, create_campaign, update_campaign, send_campaign_test, send_campaign, pause_campaign, resume_campaign and cancel_campaign.

Errors

CodeStatusMeaning and fix
campaign_incomplete400Set the subject, a from address, content and an audience.
campaign_not_editable, campaign_not_deletable, campaign_not_sendable409Only drafts are edited and sent; only drafts and canceled campaigns are deleted. Copy it into a new draft.
campaign_not_pausable, campaign_not_resumable, campaign_not_cancelable, campaign_canceled409The campaign is not in a state where that applies.
postal_address_required400Marketing mail needs the business mailing address; see Onboarding.
invalid_schedule400Pick a time between now and 30 days ahead.
invalid_test_recipients400Send 1 to 5 valid addresses.
unknown_design400Use a slug from GET /v1/campaign-designs.
invalid_name, invalid_field400Names and lines are at most 120 and 200 characters.
sending_paused, daily_send_limit_reached, monthly_send_limit_reached, transport_unavailablevariesSame as for any send; see Sending.

Something unclear or wrong? The API answers every error with a fix, and so should these docs. Back to runearc.com