Campaigns

API reference for creating campaign drafts, sending or scheduling them with warm-up, and reading their results.

Using an AI agent? Just ask:“Draft a campaign to my Newsletter list and show me before sending.”Connect your agent →

Create a draft#

POST/api/v1/campaigns

Creates a draft. Nothing is sent. The response says whether it's ready (ready_to_send), what's missing (problems), and how many people it would reach (recipients).

Body

  • namestringrequired
    Internal name.
  • fromstringrequired
    Sender on a verified domain: Acme <[email protected]>.
  • liststring | string[]required
    A list name or id, or up to 50 of them. Someone on several lists gets it once.
  • subjectstring
    Required unless the template has one.
  • htmlstring
    The email HTML. Your postal address and an unsubscribe link are added automatically.
  • templatestring
    Use a saved template's content instead of html.
  • preheaderstring
    Preview text.
  • reply_tostring
    Where replies go.
Request
curl https://agent.maillayer.com/api/v1/campaigns \
  -H "Authorization: Bearer $MAILLAYER_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "November update",
    "from": "Acme <[email protected]>",
    "list": ["Newsletter", "Customers"],
    "subject": "What we shipped in November",
    "html": "<h1>Hi {{ first_name | default: \"there\" }}</h1><p>…</p>"
  }'
Response · 201
{
  "id": "c7d2…",
  "name": "November update",
  "status": "draft",
  "subject": "What we shipped in November",
  "from": "Acme <[email protected]>",
  "lists": ["Newsletter", "Customers"],
  "scheduled_at": null,
  "sent_at": null,
  "ready_to_send": true,
  "problems": [],
  "recipients": 4812,
  …
}

Send or schedule#

POST/api/v1/campaigns/:id/send

An empty body sends now. The campaign must be a draft and ready.

Body

  • scheduled_atstring
    ISO 8601 time at least a minute from now, to schedule instead.
  • warmuptrue | object
    Send in growing batches. true uses the defaults, or set initial_batch (50), growth_factor (2), interval_hours (24) and max_batch (10,000).
Request
curl https://agent.maillayer.com/api/v1/campaigns/c7d2…/send \
  -H "Authorization: Bearer $MAILLAYER_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "scheduled_at": "2026-11-18T09:00:00Z", "warmup": true }'
This emails real people and can't be undone. Errors: 409 not_draft, 422 not_ready or invalid_schedule.

Get a campaign#

GET/api/v1/campaigns/:id

Status and results:

Response · 200
{
  "id": "c7d2…",
  "status": "sent",
  …,
  "warmup": null,
  "stats": {
    "recipients": 4812, "sent": 4812, "delivered": 4760,
    "opened": 2015, "clicked": 402, "bounced": 52,
    "complained": 1, "unsubscribed": 9,
    "open_rate": 42.3, "click_rate": 8.4, "bounce_rate": 1.1
  },
  "dashboard_url": "https://agent.maillayer.com/campaigns/c7d2…"
}

List campaigns#

GET/api/v1/campaigns?limit=20

Recent campaigns, newest first, in data. limit goes up to 100. See the Campaigns guide.