MCP

campaign/start_by_id

Tool: act

Start a campaign (transition to Running).

Validates the personalization variables in the campaign's own subject/body and in all followup subjects/bodies, then begins sending to enrolled prospects. First send begins approximately 1–4 minutes after start (observed live). delayMinSeconds controls the minimum delay between consecutive sends after the first, not the initial delay, and it is in seconds (30 means 30 seconds, not 30 minutes).

A nonexistent campaign ID returns 422 "not found or access denied", NOT 404 (upstream quirk).

This starts sending real email — requires confirm_send: true in arguments (the call is rejected with MCP_CONFIRMATION_REQUIRED without it). Consent must be fresh and specific to this send: right before calling, tell the user what will be sent and to whom, and get their explicit yes. A general or earlier "go ahead" does NOT satisfy this — "yes, fix it" / "get this running" from earlier in the conversation does not count, and neither does the user merely asking how to send or what's needed. Only set confirm_send: true if you have just asked the user to confirm THIS send and they agreed in this exact context. When in doubt, ask first.

Personalization is validated here (422). The variable vocabulary is a closed set — not a derivation from prospect field names, so custom1 is {{CUSTOM_1}} and {{CUSTOM1}} fails: personalization-variables. The error names every offending expression at once, grouped Fix Subject: / Fix Body:, so one round trip fixes them all: Wrong placeholder: {{X}} means no such name exists in any casing, while Placeholder has to match correct case. Change {{x}} to {{X}}. names the exact form to use. Nothing was sent — repair the copy with campaign/patch_by_id or followup/patch_by_id and start again. Caveat: an expression containing a | (a default: fallback, say) is not checked at all, so spell the name correctly before adding a filter.

Preflight checklist — start only sends if all of these hold: (1) fromEmails is a connected sender (sender/get); (2) at least one prospect is enrolled (prospect/post_bulk with campaignId); (3) campaign-level subject + body are set (validated at start even when followups carry their own). Missing (1) or (2), the campaign transitions to Running but never sends; missing (3) is a 422. Upstream checks these one at a time and fails fast on whichever it hits first (often just naming fromEmails) — expect to work through this checklist in order rather than seeing every gap in one response. Full flow: sending-a-campaign.

Arguments

name type req notes
id integer Campaign ID — the object's campaignId
confirm_send boolean Required to actually start sending — set true only after your user gave a fresh, specific yes to this send (a general earlier go-ahead doesn't count)

Response

200 — {campaignId: integer, status: string}. Deltas: none. The action response returns lowercase status: "running" while GETs return Title-Case "Running" — normalize before comparing (upstream inconsistency).

Errors: 400, 401, 404, 406, 409, 415, 422, 429, 500 — shared schema: schemas/errors. 422 on an unrecognized personalization variable (see above).

After starting, sending is paced — the first email typically lands within about a minute, but several minutes is normal. sentCount: 0 with every prospect on sendingStatus: NotSet is what a healthy campaign looks like during that wait, so give it a few minutes before concluding anything. If it stays quiet, work through why-isnt-it-sending.

Invoke

Call act with name: "campaign/start_by_id".