Manage Campaign Monitor clients, subscriber lists, subscribers, campaigns and transactional email over the createsend.com API v3.3.
Campaign Monitor ships in the w6w first-party pack. It declares 42 actions, 3 health checks, and the host runs its code in a sandbox that never sees the credential.
io.w6w.campaignmonitorCampaign Monitor manages email marketing at the agency scale — clients (Campaign Monitor’s term for sub-accounts), each with its own subscriber lists, segments, templates and suppression list, plus the campaigns sent to them and the transactional email sent alongside them.
Subscribers can be added, bulk-imported, updated, unsubscribed or looked up by history, and lists carry their own custom fields and stats. Campaigns are created from a hosted HTML source, sent or previewed, and read back through open, click, bounce and unsubscribe reporting plus recipient-level detail. Transactional sends (SmartEmail and classic) go out alongside the marketing side, with delivery statistics and message history of their own.
It fits agencies and marketing teams running several client accounts through one connection — list hygiene, campaign performance and transactional delivery all reachable from the same workflow, without switching between the client- and account-level views Campaign Monitor itself keeps separate.
Three routes to the same 42 actions. The Workflow tab is generated from Campaign Monitor's own manifest and carries its real ids, so it is copy-pasteable; the Code and CLI examples are the same call for any action on any app, so every app-specific value in them is a blank you fill in.
billing-details-get Read the account's email-credit balance. Agency accounts only; a direct customer gets a 403 with code 403. Credits are a balance with no ceiling and are unused on monthly plans.
campaign-create Create a draft campaign from a hosted HTML URL, targeted at lists or at segments (not both). Returns the campaign ID; sending is a separate action.
campaign-interactions-get Read a page of a sent campaign's opens, clicks, bounces, unsubscribes or spam complaints, optionally only those recorded since a given minute.
campaign-lists-and-segments-get Read the lists and segments a campaign is targeted at, as two separate arrays.
campaign-recipients-get Read a page of the addresses a campaign was sent to, each with the list it came from.
campaign-send Send a draft campaign immediately or schedule it for a date and time in the client's timezone. Irreversible and billable; never retried automatically.
campaign-send-preview Send a test copy of a draft campaign to up to 15 addresses. Personalization uses fallback values, not real subscriber data. Rationed: 240 addresses per 24 hours per client.
campaign-summary-get Read a sent campaign's totals: recipients, opens (total and unique), clicks, unsubscribes, bounces and spam complaints, plus its public web-version and Worldview URLs.
campaign-unschedule Cancel a scheduled campaign and return it to drafts. Fails with code 341 if it is not scheduled — which also covers 'it has already started sending'.
classic-email-send Send a transactional email with content supplied at call time. Returns one MessageID per recipient. Sends mail; never retried automatically.
client-campaigns-get Read a page of a client's sent campaigns, newest first by default, optionally filtered by sent-date range and by tags.
client-drafts-get List a client's draft campaigns with their IDs, subjects, sender details and tags. Returns a bare array, not a paged result.
client-get Read a client's basic and billing details. The client's own secret field is deleted from the response before it is returned.
client-lists-for-email-get Find every list across a client that knows an email address, with the subscriber's state on each and the date they were added.
client-lists-get List every subscriber list belonging to a client, with its ID and name.
client-segments-get List every segment across all of a client's lists, with the list each belongs to.
client-suppress Add one or more email addresses to the client-wide suppression list, silencing them across every list that uses the AllClientLists unsubscribe setting.
client-suppression-list-get Read a page of the client-wide suppression list, with each address's suppression reason and date.
client-tags-get List a client's campaign tags in ascending order with the number of campaigns carrying each.
client-templates-get List a client's templates, each with its ID, name and public preview and screenshot URLs.
client-unsuppress Remove one email address from the client-wide suppression list. Answers code 176 if the address was not on it.
list-create Create a subscriber list for a client and return its ID. Fails with code 250 if the title duplicates an existing list.
list-custom-fields-get List a list's custom fields with their data type, select options and preference-centre visibility. Returns both the display FieldName and the bracketed Key.
list-get Read a list's title, opt-in type, unsubscribe setting and the custom unsubscribe and confirmation page URLs.
list-stats-get Read a list's subscriber counts: totals plus today / yesterday / this week / month / year buckets for new actives, unsubscribes, deletions and bounces. Buckets are calendar-aligned in the client's timezone, not rolling windows.
list-subscribers-get Read a page of a list's subscribers in one state (active, unconfirmed, unsubscribed, bounced or deleted), optionally filtered to those that entered that state since a date.
smart-email-get Read a smart transactional email's sender details, subject, content and — most usefully — the list of email variables its template expects.
smart-email-list List the smart transactional emails defined in Campaign Monitor, optionally filtered to drafts or active ones.
smart-email-send Send a smart transactional email, merging a data object into the template's variables. Returns one MessageID per recipient. Sends mail; never retried automatically.
subscriber-add Add a subscriber to a list, updating them if the address already exists. The write is queued, not immediate — use Import Subscribers when the result must be readable straight away.
subscriber-delete Move a subscriber to the Deleted state on one list. The record remains readable and the address is NOT added to the suppression list.
subscriber-get Read one subscriber's name, state, dates, mobile number and custom fields. Answers for any state, including unsubscribed and deleted.
subscriber-history-get Read a subscriber's campaign and automated-email history with every recorded open, click and bounce. Capped at 60 opens/clicks per campaign, and each event carries an IP address.
subscriber-import Add or update up to 1000 subscribers in one synchronous call. A partial failure is returned as a 400 with code 210 whose ResultData names each failed address.
subscriber-unsubscribe Unsubscribe an address from a list. Whether that also unsubscribes them from the client's other lists and adds them to the suppression list is decided by the list's unsubscribe setting.
subscriber-update Update an existing subscriber's name, address, mobile number and custom fields. Never creates: an unknown address fails with code 203.
system-date-get Read the current date and time in the account's timezone (format YYYY-MM-DD HH:MM:SS, no offset). Use it to compute date filters, which this API always interprets in the client's timezone rather than UTC.
transactional-messages-get List sent transactional messages, newest first, filtered by status, group or smart email. Paged by message ID cursor rather than by page number; 200 per call maximum.
transactional-statistics-get Read transactional sent / bounced / delivered / opened / clicked totals for a date range, optionally narrowed to one classic group or one smart email.
A workflow step names the app and the action, and the editor fills in the
connection when you pick one. This is the Step shape from the
workflow spec, carrying Campaign Monitor's real ids.
{
"manifestVersion": "2",
"name": "campaignmonitor-example",
"steps": [
{
"id": "campaign-create",
"uses": {
"app": "io.w6w.campaignmonitor",
"action": "campaign-create",
"connection": "conn_YOUR_CONNECTION_ID"
},
"with": {
"clientId": "<clientId>",
"name": "<name>",
"subject": "<subject>"
}
}
]
}campaign-create billing-details-get campaign-interactions-get campaign-lists-and-segments-get campaign-recipients-get +37 more actions available
Every app-specific value here is a blank you have to fill in. An
app action is reached through the connection that authenticates it, so the
address is a connection id, not the app id — and connections belong to your account,
so a public page cannot know yours. Create one for Campaign Monitor, then fill in
the three blanks: conn_YOUR_CONNECTION_ID, the action key, and the
parameters that action declares. The call itself is real — the shape is transcribed
from the studio's own snippet builder, which prints the same kind of blanks — but
nothing in it is specific to Campaign Monitor. The Workflow tab is where this app's
real ids are.
npm install @w6w/sdkyarn add @w6w/sdkpnpm add @w6w/sdkdeno add npm:@w6w/sdkimport { W6wClient, isActionRun } from "@w6w/sdk";
// Reads W6W_BASE_URL and W6W_TOKEN from the environment when omitted.
const client = new W6wClient();
const envelope = await client.run({
urn: "conn_YOUR_CONNECTION_ID",
action: "campaign-send",
payload: {
campaignId: "<value>",
// sendDate: "<value>",
confirmationEmail: "<value>",
},
});
if (isActionRun(envelope)) console.log(envelope.value); npm install -g @w6w/cli w6w run conn_YOUR_CONNECTION_ID --action campaign-send --payload '{"campaignId":"<value>","confirmationEmail":"<value>"}' Give an AI agent Campaign Monitor — without giving it Campaign Monitor's credentials. One MCP endpoint exposes every app, function and workflow the caller is entitled to, as tools it can discover and run. Access is granted per team while we onboard.
One tool call{
"name": "w6w_invoke",
"arguments": {
"ref": "app:io.w6w.campaignmonitor#campaign-create",
"input": {
"clientId": "<clientId>",
"name": "<name>",
"subject": "<subject>"
}
}
}
Every tool names its target with a single ref. The
app: form above doesn't name a connection at all — the
host resolves which of the caller's Campaign Monitor connections to sign
with, and refuses rather than guesses when the answer is ambiguous.
The token is attached host-side, at the moment of the call. It is never a tool argument, never in the model's context, and never in a transcript — so a prompt injection has nothing to exfiltrate.
Tools are derived per end user from what that person has actually connected and is entitled to — not one shared bot identity carrying the union of everyone's access.
Multi-step work runs on the workflow engine and returns a run handle the agent can poll — retries, branching and state survive the conversation that started them.
Campaign Monitor's declared health checks are on the surface too, so an agent can tell "the vendor is down" from "your credential expired" before it burns a retry on either.
The MCP surface is part of the hosted platform. Campaign Monitor itself is MIT, and the runtime that executes it is source-available (FSL).
Campaign Monitor declares its own checks, so its health is a property of the app rather than something the host guesses at.
Unauthenticated GET /api/v3.3/systemdate.json against api.createsend.com. A schema-correct 401 {"Code":100} is a pass: it proves the API parsed the request and answered with its own error envelope. Whether a given credential works is the derived auth checks' job.