MCP

Sending a campaign (end to end)

The full path from nothing to a live, sending campaign. Each step is one operation through the Tool named in its row below — follow the link for that operation's fields.

Before you start: a campaign can only send from a connected, warmed-up sender. If the account has none, one can be created via sender/post — SMTP/IMAP credentials the user gathers on their provider's site with your guidance. Work through onboarding first.

If more than one sender is connected, ask the user which sender(s) the campaign should send from before creating it — never pick one silently.

Steps

# Goal Tool Operation
1 Confirm you have a real sender to send from read sender/get
2 Create the campaign — set fromEmails to that sender's address and campaign-level subject + body — collect the user's actual content first (writing-emails); patch before starting if it changes. This alone is a complete, sendable first email (start validates it even when followups carry their own) create campaign/post
3 Add a sequence to hold any automated follow-up steps — a sequence itself has no subject/body, just conditions (opened/replied/etc.) for when its followups fire create campaign/post_sequences_by_id
4 (optional) Add follow-up email(s) to that sequence (subject + body; personalization variables come from a closed list — personalization-variables) — only needed for touches after the first email; skip this entirely for a one-email send create sequence/post_followups_by_id
5 Add your contacts and enrol them into the campaignenrolling into a campaign that is already Running starts sending to those prospects immediately create prospect/post_bulk with campaignId
6 Start sending (validates the personalization variables, then paces the sends) — needs a fresh, send-specific go-ahead from the user (what will be sent, to whom) right before this call, not a general earlier "yes": pass confirm_send: true act campaign/start_by_id
7 Confirm it's sending read campaign/stats_by_id

Step 3 is not optional if you want followups: despite what the underlying API schema may suggest, no sequence exists until you call itcampaign/get_sequences_by_id returns an empty list immediately after campaign/post.

The two things that silently block a send

  1. A real sender. campaign/post defaults fromEmails to the account's login email, which is usually not a connected sender — the campaign then starts but never sends. Always set fromEmails to an address returned by sender/get.

  2. Enrolment is a separate step from creating contacts. Creating a prospect (prospect/post) or moving it to a list does not put it in a campaign. The one operation that enrols is prospect/post_bulk with the campaignId argument — it upserts the contacts and adds them to the campaign's first sequence in one call. It merges onto existing prospects (omitted fields are preserved, not cleared), so enrolling contacts who already exist in the CRM this way is safe.

While testing

Send only to an address you control (e.g. your own inbox) — never enrol real prospects into a throwaway test campaign.

Why isn't it sending? (checklist)

The quick list below covers the mistakes people make while building a campaign. If the campaign is already Running and sentCount is not moving, work through why-isnt-it-sending instead — it starts from the prospects' sendingStatus, which names the blocker directly, and covers schedule windows, limits and ESP matching. First check there: sending is paced, so sentCount: 0 for the first minutes after starting is normal, not a fault.

  1. status is Paused/Draft → it only sends while Running (campaign/start_by_id — get a fresh, specific yes for this send before starting; an earlier general instruction to fix or run things isn't consent to send). A go-ahead given earlier in the conversation (before the campaign existed or was reviewed) does not count — re-confirm at start time, every time.
  2. Sender problems: not connected, or campaign dailyLimit exceeds the sender's own limit (sender/get).
  3. Nobody enrolled, or prospects unvalidated (prospect/get with includeCampaignIds.campaignIds).
  4. Prospects missing a value a variable needs: with deactivateIfMissingPlaceholder: true each one is deactivated rather than mailed (sendingStatus: MissingPlaceholder). Give the variable a default: fallback, or fill the field — personalization-variables.
  5. For a copied campaign, check the source campaign's stats: copies inherit prospect lists, including ones with heavy bounce history.
  6. A followup has useOriginalSubject: true but the campaign's own subject is empty → start still fails validation (it needs a non-empty effective subject regardless of useOriginalSubject) — give the campaign a subject, or the followup its own. To inherit the campaign's subject, omit the followup's subject field entirely — an explicit subject: "" defeats inheritance and fails the same way.