Skip to main content
A campaign turns a list into an outbound sequence. The API mirrors how campaigns work in the app: you create a draft, Fuse initializes it asynchronously, you review and edit the sequence steps, and nothing sends until you explicitly approve it. That last part is deliberate — a campaign contacts real people, so the API never activates one as a side effect of creating it. The full flow is four calls:
  1. POST /business/campaigns — create the draft.
  2. GET /business/campaigns/{campaignId} — poll until initialization completes.
  3. GET /business/campaigns/{campaignId}/steps — review (and optionally PATCH) the sequence.
  4. POST /business/campaigns/{campaignId}/approve — activate it.
Campaign endpoints require a key with the campaigns scope. See scopes.
Sending accounts (email and LinkedIn) are connected in the Fuse app, not via the API. Connect at least one before you approve — approval fails with CAMPAIGN_NOT_READY if no sending account is available.

Manual vs. AI-generated

Every campaign is one of two types, set by campaignType at creation:
  • manual (the default) — you write the subject and body of every step yourself.
  • ai-generated — Fuse writes the copy during initialization, guided by your prompt, your website, and optional context like a knowledge hub or a writing style.
The type decides which request fields are valid and which step fields you edit later: manual steps have a subject and body you own; AI steps are driven by a topic. AI-only fields on a manual campaign are rejected, not ignored — the request fails so you find out immediately rather than wondering why your prompt had no effect.
1

Create the draft

Provide a campaignName, exactly one of listId or listIds (up to 10 lists), and a channels array — one entry per sequence step, in order.
A 201 means the draft was accepted, not that it is ready — initialization runs in the background, which is what the next step polls for.Core fields:Scheduling (all optional):Exclusions (all optional):AI-only fields — valid only when campaignType is "ai-generated"; a manual campaign rejects them:The endpoint accepts a few additional toggles (unsubscribe link, open-rate tracking, and others) — see the API reference for the full request schema.
All errors use the standard error envelope.
2

Poll until initialization completes

Initialization is asynchronous — for AI campaigns it includes generating the copy for every step, which takes time. Poll the campaign until initializationStatus is "completed":
status and initializationStatus answer different questions: status is the campaign’s lifecycle state (it stays pre-active until you approve), while initializationStatus tells you whether the draft is ready to review. When AI generation fails, initializationError carries readable status text explaining what went wrong.
3

Review the sequence

Once initialized, fetch the steps and read what will actually go out:
sequenceNumber orders the steps and daysBetween is the wait, in days, after the previous step. If anything needs changing, edit it now — see Editing steps below. Approval is the point of no return, so this is the moment to check the copy, the merge tokens, and (for AI campaigns) that every step has a topic.
4

Approve

Approval is the explicit go signal. It validates that the campaign is complete and then activates it:
The 202 means activation was accepted; sending follows your schedule (campaignStartDate, emailDays, timezone). If approval fails instead, see Troubleshooting approval.

Editing steps

PATCH /business/campaigns/{campaignId}/steps/{stepId} edits one step and returns { "stepId": "..." }. Which fields you set depends on the campaign type: on manual steps you write the subject and body; on AI steps you set the topic and let generation handle the copy. Either way you can adjust daysBetween (0–365).
Limits: subject up to 500 characters, body up to 50,000, topic up to 1,000.

Merge tokens

Step content supports two kinds of tokens:
  • Contact tokens{{firstName}}, {{companyName}}, and similar, filled from the contact’s own fields.
  • Column tokens{Column: <name>}, filled from the list’s custom columns. {Column: Pain point} renders the value of the “Pain point” column for that contact.
Column tokens have one behavior worth planning around: if the referenced column has no value for a contact yet, that contact’s send is held until the value exists. This is deliberate — Fuse never sends a half-rendered email — and it is what makes the “enrich a custom column, then send” workflow safe. It also means a campaign can look stalled when it is actually waiting on column data, so fill your columns before approving, or expect sends to trickle out as values land.
The topic gotcha. An AI campaign created from a templateId whose template was captured from a manual campaign inherits each step’s subject and body — but no topic. Approval requires a topic on every AI-generated step, so this combination fails with 422 CAMPAIGN_NOT_READY until you PATCH a topic onto each step.

Troubleshooting approval

Approval failures come back in the standard error envelope:
CAMPAIGN_NOT_READY is the one you fix and retry: add the missing content via step edits, or connect a sending account in the app, then call approve again. CAMPAIGN_NOT_APPROVABLE means retrying will not help — the campaign has already moved past the draft state.

Where to next

Knowledge hubs

Give AI campaigns a curated source of product facts.

Custom columns

Attach per-contact data your steps can merge with column tokens.

Build a list from search

Fill a campaign-ready list from prospect search.

Upload your contacts

Bring your own CRM contacts into a list first.