Less boo. More booked. Halloween offer: 30 days free on any paid plan. Claim 30 days freeEvery new account gets one free mailbox for warmup and replies. No domain to buy. See how it works

Skip to content

Start a campaign

API referenceCampaigns

From the Campaigns API reference. Requests use the base URL https://app.warmerly.com/api/v1 and an API key, see Authentication.

text
POST /campaigns/{id}/start

Validates the campaign is ready, then flips it to active and sets startedAt (on first start only, later restarts don't reset it). The workspace must not be billing-locked, and starting a draft, completed or archived campaign must fit your plan's active-campaign limit. It then runs the same checks as GET /campaigns/{id}/readiness, plus a live check that the AI provider is reachable when the copy uses {{ai_opener}}:

  • At least one step exists that is a valid email step (subject + bodyText), a LinkedIn step (linkedin_connection / linkedin_message).
  • Your plan includes the channel(s) the campaign actually uses.
  • Your monthly campaign send limit hasn't been reached.
  • At least one sending account is attached for each channel the campaign uses (email → senders, LinkedIn → linkedin-senders).
  • At least one lead is queued.
  • Copy checks: every merge tag exists, the campaign brief is written when the copy uses {{ai_opener}}, and the copy does not link to a Warmerly domain.

Checks marked severity: "warning" do not block, but the start is refused with 400 and error.details.needsAcknowledgement: true until you repeat the call with { "acknowledgeWarnings": true } in the JSON body.

bash
curl -X POST https://app.warmerly.com/api/v1/campaigns/b6a1e7b0-2f2b-4b7a-8e2a-1a2b3c4d5e6f/start \
  -H "X-Api-Key: wmv_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
json
{ "campaign": { "id": "b6a1e7b0-2f2b-4b7a-8e2a-1a2b3c4d5e6f", "status": "active", "startedAt": "2026-07-02T10:00:00.000Z", "...": "..." } }

Failing a readiness check returns 400 bad_request with a human-readable message (e.g. "Add at least one sending mailbox") and the checks in error.details.checks. Missing plan access returns 403 channel_not_included; hitting the monthly send cap returns 402 payment_required. Hitting your plan's active-campaign limit returns 402 plan_capacity, a billing-locked workspace returns 402 billing_locked, and a campaign whose only senders are not allowed to send campaigns at all (for example a free mailbox while sending from free mailboxes is switched off) returns 409 with code sender_cannot_send_campaigns.

Was this page helpful?