Guides

Campaigns

Run campaigns from the systems that already know your customers. A campaign moves through the same steps as in the console: draft, checks, test, approval, schedule, report.

The lifecycle

  1. Create a draft

    Name it, give it a subject and a sending domain, and start from a template, your own HTML or a starter design, in your brand look unless you ask for the original.

    POST /campaigns
  2. Check it

    Validation runs the same checks a send does and says which ones block it. Render it to see the message as a recipient would, as HTML or plain text.

    POST /campaigns/{id}/validate
  3. Send a test

    Test copies go only to people on your account, 30 an hour, with "[Test]" before the subject and an unsubscribe link that goes nowhere.

    POST /campaigns/{id}/test
  4. Approve it

    Approval keeps the campaign exactly as it stands, and every blocking check must pass. Change anything afterwards and it must be approved again.

    POST /campaigns/{id}/approve
  5. Schedule it

    Send now or at a time. Scheduling twice never sends twice. A campaign that is sending can be paused and resumed, and one that has not started can be cancelled back to a draft.

    POST /campaigns/{id}/schedule
  6. Read the report

    Each measure with its definition and rate, clicks by link, a timeline, the subject test's result, and plain observations comparing it with your usual results.

    GET /campaigns/{id}/report

What applies to every campaign

  • A campaign goes to subscribed contacts only: those with any of its audienceTags, or everyone subscribed if it has none. Pending contacts are never sent marketing.
  • Without the Campaigns add-on, a campaign must fit in what is left of the free allowance; with it, the list must fit the plan. Either is answered 402 payment_required when scheduling.
  • Campaigns and automations share one hourly sending allowance, set by your plan.

Marketing is not transactional

A campaign is the place for anything that sells. Transactional email skips consent, so it refuses mail that reads as marketing to someone who unsubscribed.
POST/campaigns

Create a campaign

Creates a draft. Its design starts from a template, from an email's HTML you send, or from a starter design, in your brand look unless you ask for the original. A domainId that is not one of yours is left empty. Set the topic, segment, subject test and brief afterwards with PATCH /campaigns/:id. Needs audience:write.

Needsaudience:writeReturns201 Created

Body

namestringrequired
Your name for the campaign, 1 to 120 characters.
subjectstringoptional
Up to 200 characters. From the imported HTML's title if left out.
preheaderstringoptional
The preview line, up to 200 characters.
fromNamestringoptional
Up to 100 characters.
fromLocalstringoptional
The part of the from address before the @; "news" if left out.
domainIduuid | nulloptional
The sending domain.
replyTostring (email) | nulloptional
Where replies go.
audienceTagsstring[]optional
Up to 20 tags; the campaign goes to subscribed contacts with any of them, or everyone if empty.
templateIdstringoptional
A built in template ("builtin:...") or one of your own, as the starting design.
look'brand' | 'original'optional
Start in your brand look ("brand", the default) or the template's own.
htmlstringoptional
An existing email's HTML, up to 900,000 characters, read into the design (see POST /campaigns/import-html).
bodystringoptional
Plain body text in the older body language, up to 100,000 characters; leave it out to start from a design.
POST/campaigns
curl -X POST https://app.rykonmail.com/api/v1/campaigns \
  -H "Authorization: Bearer $RYKON_MAIL_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "API docs example",
    "subject": "Our autumn collection is here",
    "preheader": "Twelve new pieces, made in small batches.",
    "fromName": "Northwind Traders",
    "fromLocal": "news",
    "domainId": "965a5cd1-455b-4c7d-8ae3-f68caf0c7993",
    "replyTo": "hello@northwind-local.test",
    "audienceTags": [
      "vip"
    ]
  }'
Response
201 Created
{
  "id": "9e210b02-8326-4122-a449-2196ccd8cc38",
  "name": "API docs example",
  "subject": "Our autumn collection is here",
  "preheader": "Twelve new pieces, made in small batches.",
  "from_name": "Northwind Traders",
  "from_local": "news",
  "domain_id": "965a5cd1-455b-4c7d-8ae3-f68caf0c7993",
  "domain": "northwind-local.test",
  "reply_to": "hello@northwind-local.test",
  "body": "",
  "audience_tags": [
    "vip"
  ],
  "segment": null,
  "topic_id": null,
  "experiment": null,
  "experiment_result": null,
  "brief": {},
  "updated_by": null,
  "state": "draft",
  "state_reason": null,
  "scheduled_at": null,
  "started_at": null,
  "finished_at": null,
  "created_at": "2026-10-30T06:14:34.949Z",
  "updated_at": "2026-10-30T06:14:34.949Z"
}

In the reference: Create a campaign

POST/campaigns/{id}/schedule

Schedule or send a campaign

Sends now, or at a time. Only a draft whose approval still covers it as it stands can be scheduled (409 otherwise). Without the Campaigns add-on a campaign must fit in what is left of the free allowance, and with it the list must fit the plan; either answers 402. Scheduling twice never sends twice. Needs audience:write.

Needsaudience:writeReturns200 OK

Path parameters

iduuidrequired
The campaign's id.

Body

atstring (date-time) | nulloptional
When to send; now if null or left out.
POST/campaigns/{id}/schedule
curl -X POST https://app.rykonmail.com/api/v1/campaigns/9e210b02-8326-4122-a449-2196ccd8cc38/schedule \
  -H "Authorization: Bearer $RYKON_MAIL_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "at": "2026-10-30T08:15:19Z"
  }'
Response
200 OK
{
  "id": "9e210b02-8326-4122-a449-2196ccd8cc38",
  "name": "API docs example",
  "subject": "Our autumn collection is here",
  "preheader": "Twelve new pieces, made in small batches.",
  "from_name": "Northwind Traders",
  "from_local": "news",
  "domain_id": "965a5cd1-455b-4c7d-8ae3-f68caf0c7993",
  "domain": "northwind-local.test",
  "reply_to": "hello@northwind-local.test",
  "body": "",
  "audience_tags": [
    "vip"
  ],
  "segment": null,
  "topic_id": "bea753b0-6132-4bc2-bc2a-18ff86ed0079",
  "experiment": null,
  "experiment_result": null,
  "brief": {},
  "updated_by": "key sa1pteyz44qbm",
  "state": "scheduled",
  "state_reason": null,
  "scheduled_at": "2026-10-30T08:15:18.947Z",
  "started_at": null,
  "finished_at": null,
  "created_at": "2026-10-30T06:14:34.949Z",
  "updated_at": "2026-10-30T06:15:19.947Z"
}

In the reference: Schedule or send a campaign

Every campaign endpoint

Automations

Journeys that start when someone subscribes, through a form or a tag, and stop the moment they unsubscribe. Each email in a journey reaches a person once.