Skip to main content

Campaigns

A campaign is a bulk send to a resolved audience. Campaign jobs are routed to leadx-ms-send-manager; one-to-one messages and AI Genie outreach go elsewhere. If you are sending to many people from a template, this is the right surface.

Before you create one

You need three things:

  1. An audience — at least one selector must be switched on.
  2. A template — see Templates below.
  3. A sending app — for type: "email", an SMTP/provider configuration from Integrations.

Audience selection

Audience is expressed as a set of boolean switches plus the matching data. At least one of the *Bool flags must be true, or creation fails with CampaignSegmentsRequired_400.

FlagPairs withMeaning
segmentsBoolsegments: [id]Saved segments.
tagsBoolcustomAudience.tagsContacts carrying these tags.
categoriesBoolcustomAudience.categoriesContacts in these categories.
contactsBoolcustomAudience.contactsAn explicit contact id list.
customSegmentsBoolcustomAudienceAn inline advanced-filter audience.

A segment id that doesn't resolve is reported as CampaignSegmentNotFound_400 naming the missing ids — deliberately distinct from an audience that resolves to nobody, which is CampaignAudienceEmpty_400.

Preview before committing

curl -X POST https://api.leadx.in/api/key/protected/campaign/audience-preview \
-H "apikey: $KEY" -H "Content-Type: application/json" \
-d '{ "segmentsBool": true, "segments": ["665a..."] }'

Always do this first. An empty audience refuses campaign creation outright.

Create

curl -X POST https://api.leadx.in/api/key/protected/campaign \
-H "apikey: $KEY" -H "Content-Type: application/json" \
-d '{
"name": "Q3 product announcement",
"type": "email",
"description": "Announcing the analytics tier",
"segmentsBool": true,
"segments": ["665a..."],
"template": "665c...",
"smtp": { "id": "665d..." },
"scheduleType": "scheduled",
"startAt": "2026-09-15T09:00:00.000Z",
"endAt": "2026-09-20T17:00:00.000Z",
"timeWindow": { "start": "09:00", "end": "17:00" },
"daysOfWeek": [1, 2, 3, 4, 5],
"intervalMs": 2000,
"startCampaign": false
}'
FieldNotes
nameRequired. Must be unique per company (CampaignNameAlreadyExists_400).
typeRequired. email, whatsapp, and the other configured channels.
templateTemplate id for the channel.
smtp{ id } of the sending configuration. Required at start time for email.
scheduleType / startAt / endAtWhen it runs.
timeWindow / daysOfWeekThrottle sends to business hours. daysOfWeek is 0–6, Sunday = 0.
intervalMsDelay between sends, for provider rate limits.
triggerWorkflowDefault true — whether sends emit workflow events.
startCampaigntrue starts immediately; false creates it idle.

:::warning Plan limits still apply here Campaign creation checks the plan's campaign allowance directly, not through the middleware an API key skips. Exceeding it returns PlanLimitExceeded_403. :::

Run control

MethodEndpointPurpose
PUT/campaign/:id/play-pausePause or resume.
PUT/campaign/:id/continueMove a failed campaign back to active.
POST/campaign/:id/retry-failedRetry failed recipients.
POST/campaign/:id/sync-failedRe-sync the failed contact list.
POST/campaign/:id/assignTagTag everyone who failed — handy for a follow-up segment.
POST/campaign/test/:typeSend a test message without touching the audience.

Always send a test first. POST /campaign/test/:type is the only way to see a rendered message before committing to the whole audience.

Monitoring

# Per-recipient outcomes
curl -G https://api.leadx.in/api/key/protected/campaign/665f.../recipients \
-H "apikey: $KEY" \
--data-urlencode 'status=failed' --data-urlencode 'page=1' --data-urlencode 'limit=50'

# Campaign-level log
curl https://api.leadx.in/api/key/protected/campaign/665f.../logs -H "apikey: $KEY"

/recipients is the per-person report from the v2 send engine and is the one to build dashboards on. Note it uses page and limit rather than the usual p and n.

Delivery events per provider live under /logs.

Manual campaigns

MethodEndpoint
GET / POST/campaign/manual
GET/campaign/manual/:id

Manual campaigns are one-off sends assembled outside the scheduled pipeline.

Templates

MethodEndpointNotes
GET / POST / DELETE/template/emailEmail templates.
GET / PUT/template/email/:id
POST/template/email/generate-aiDraft an email template with AI.
GET / POST / DELETE/template/whatsappWhatsApp templates.
GET/template/whatsapp/:id
POST/template/whatsapp/generate-aiDraft a WhatsApp template with AI.
POST/template/whatsapp/status-reconcilePull approval status from Meta.
GET/template/category/:panelAvailable template categories.

:::note WhatsApp templates need Meta approval A WhatsApp template must be approved by Meta before a campaign can send it. Create it, then poll status-reconcile until it reports approved. Approved templates cannot be edited — CannotUpdateApprovedTemplate_400. :::