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
namestringrequiredInternal name.fromstringrequiredSender on a verified domain:Acme <[email protected]>.liststring | string[]requiredA list name or id, or up to 50 of them. Someone on several lists gets it once.subjectstringRequired unless the template has one.htmlstringThe email HTML. Your postal address and an unsubscribe link are added automatically.templatestringUse a saved template's content instead of html.preheaderstringPreview text.reply_tostringWhere 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_atstringISO 8601 time at least a minute from now, to schedule instead.warmuptrue | objectSend in growing batches.trueuses the defaults, or setinitial_batch(50),growth_factor(2),interval_hours(24) andmax_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.