Bulk email campaigns

One email to a contact group or an explicit list of up to 10,000 addresses — drafted, sent asynchronously, with live progress counters.

Create a campaign

POST/api/v1/email/campaigns

Parameters

FieldTypeRequiredDescription
namestringYesInternal label.
domain_uuiduuidYesThe verified domain to send from.
subjectstringYesSubject line.
html / textstringYesAt least one body.
fromstringNoLocal part or full address on the domain; omit for the domain default.
source_typestringYesgroup — email every contact in a contact group that has an email address; manual — the explicit list in to.
group_uuiduuidNoRequired for group campaigns.
tostring[]NoManual audience, up to 10,000 addresses.
curl -X POST https://api.mobilesasa.com/api/v1/email/campaigns \
  -H "Authorization: Bearer $MOBILESASA_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "July newsletter",
    "domain_uuid": "7c2e91d4-…",
    "subject": "What's new at Yourbrand this July",
    "html": "<h1>Hello!</h1><p>Here's what we shipped…</p>",
    "source_type": "group",
    "group_uuid": "9d0b33a1-…"
  }'

Send it

POST/api/v1/email/campaigns/{uuid}/send

Creating never sends. The send call queues the campaign for the fan-out worker (a second send call returns 409) — recipients are resolved, suppressed addresses skipped, and each remaining recipient is billed one unit as its email goes out at a provider-friendly pace.

curl -X POST https://api.mobilesasa.com/api/v1/email/campaigns/7f31ab02-…/send \
  -H "Authorization: Bearer $MOBILESASA_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{}'

Track progress

GET/api/v1/email/campaigns/{uuid}
GET/api/v1/email/campaigns
curl "https://api.mobilesasa.com/api/v1/email/campaigns/7f31ab02-…" \
  -H "Authorization: Bearer $MOBILESASA_TOKEN"
Response — 200
{
  "success": true,
  "data": {
    "uuid": "7f31ab02-…",
    "name": "July newsletter",
    "status": "completed",
    "source_type": "group",
    "total_recipients": 1874,
    "total_sent": 1791,
    "total_suppressed": 74,
    "total_failed": 9,
    "started_at": "2026-07-12T08:00:04Z",
    "completed_at": "2026-07-12T08:02:41Z"
  }
}

Campaign statuses

FieldTypeRequiredDescription
draftinitialNoCreated, not sent.
queued / sendingin flightNoWaiting for or being processed by the fan-out worker; counters update live.
completedfinalNoEvery recipient processed — see the sent/suppressed/failed split.
failedfinalNoThe campaign stopped — failure_reason says why (most commonly insufficient email balance; recipients already sent stay sent and billed).

Balance covers the whole audience

Recipients are billed in batches as the campaign runs. If your email balance runs out mid-campaign the campaign fails at that point with the partial counts recorded — top up and send a fresh campaign to the remainder. Pre-check: audience size × your email rate ≤ balance.