Requires the Campaigns permission. Tools in this group are hidden from
tools/list and refused on call when your plan does not grant it.campaign_activity_summary
Read-only Aggregate counts of pending, completed and failed actions across the campaign. Three numbers for the whole campaign — the cheapest “is it working” check. For the same split per step usesequence_step_stats, and for the leads behind one step sequence_leads_at_step.
Parameters
string
required
Campaign id, from
campaign_list or campaign_create.campaign_add_prospects
Write Destructive Top up an already-running campaign with prospects from a new source, without touching its sequence or existing leads. Runs in the background and can take several minutes. Two hard preconditions, both enforced by the backend as thrown errors: the campaign must be ACTIVE — a DRAFTED one fails with “Campaign is not active!” — and it must have finished filtering its first batch. So this is never how a new campaign gets its audience: for that usecampaign_set_source (a search URL) or campaign_upload_leads (CSV rows) before launching. It also does not add leads to this campaign directly — the backend creates a child campaign pointing at this one, which is why campaign_delete reports removing active children.
Parameters
string
required
Campaign id, from
campaign_list or campaign_create.enum (9 values)
required
Source kind for the new batch.
string
LinkedIn source URL, for non-CRM types.
string
CRM sources: contact property holding the profile URL.
string
CRM sources: segment / list query.
campaign_create
Write Create a DRAFTED campaign. Nothing sends untilcampaign_launch. Pass sourceUrl to set the prospect source at the same time (a LinkedIn or Sales Navigator search URL, a group, an event, or a post). For a CSV-driven campaign, omit sourceUrl and follow up with campaign_upload_leads. This is the right starting point for EVERY new campaign. Never begin one with campaign_duplicate unless the user named a campaign to copy — see that tool for why. It creates the campaign and nothing else: the sequence comes from flow_set, accounts and limits from campaign_update, and it only sends after campaign_launch.
Parameters
string
required
Campaign name, shown throughout the app.
string
LinkedIn search / Sales Navigator / Recruiter / group / event / post URL to harvest prospects from. The source type is inferred from the URL shape.
campaign_create_ab_variant
Write Split a campaign into an A/B pair so two versions of the sequence run against comparable halves of the audience. Compare them later withanalytics_campaign. This SPLITS, it does not copy: the backend moves half of the not-yet-contacted leads out of the original into a new DRAFTED campaign, copies the flow, and renames the original to “<title> [A]”. The original therefore ends up with half the audience it had. It needs more than 10 leads still waiting to be contacted and refuses otherwise with “Not enough leads to do AB testing, Duplicate campaign instead!” — in which case campaign_duplicate is the backend’s own suggestion. Use campaign_duplicate when the audience should be left alone, and this when the point is to compare two versions on one audience.
Parameters
string
required
Campaign id, from
campaign_list or campaign_create.campaign_delete
Write Destructive Remove a campaign from your account by moving it to DELETED. Nothing is erased — the campaign, its leads, sequences and activity records all stay in the database, and the campaign simply stops appearing in listings. There is no tool to bring it back, so confirm with the user first. Sending stops because the workers only pick up ACTIVE campaigns; to stop sending without removing the campaign, that is a pause, which belongs in the web app. The only tool allowed to write a campaign status, and the only value it writes is DELETED —campaign_update has no status parameter and nothing sets ACTIVE, PAUSED or ARCHIVED. Deleted campaigns vanish from campaign_list, so confirm before calling: there is no undelete.
Parameters
string
required
Campaign id, from
campaign_list or campaign_create.campaign_duplicate
Write Copy one specific existing campaign — its settings and its whole sequence — into a new DRAFTED campaign, without copying the leads. Use this ONLY when the user asks to duplicate a campaign they have named. It is not a way to start a new campaign: a new campaign has nothing to duplicate, and the copied sequence carries the original audience’s messaging. To start fresh, usecampaign_create. The copied steps cannot be rewritten from here either — sequence_update edits are reverted at launch on a campaign that has not launched yet, so a duplicate is only useful when the existing copy is meant to be kept.
Parameters
string
required
The existing campaign the user named. Never guess this — get it from
campaign_list.campaign_export_stats
Write Generate a CSV export of campaign performance. Returns a filename; the file is served from the CDN and also emailed to the account owner — so it leaves the conversation, which is worth mentioning before calling it. Performance numbers, not people: for a file of prospects uselead_export, and to read the numbers here instead use analytics_campaign.
Parameters
string
Campaign id, from
campaign_list or campaign_create.object
Date window as { from, to } — epoch milliseconds or ISO 8601. Omit for the backend default.
campaign_generate_ai_sequence
Write Ask the platform’s own AI to draft a whole campaign — copy and multi-step sequence — from a brief, and create it as a draft. Requires an AI provider connected in the web app under Settings - Integrations. Use this when the user wants the platform to write the sequence for them; to author one yourself, useflow_set.
Parameters
string
required
Campaign name.
string
required
What the campaign should achieve, e.g. “book discovery calls”.
string
required
Who is being targeted, e.g. “Heads of RevOps at Series B SaaS”.
string
required
Industry.
string
required
What you are offering, in a sentence or two.
string
required
Voice of the copy, e.g. “friendly”, “direct”, “consultative”.
string
required
Proof points or hooks the copy should work in.
integer (1–10)
required
How many steps the sequence should have.
string
Country.
campaign_get
Read-only Everything about one campaign: settings, schedule, limits, attached accounts, lead source, live counters and the flow outline. This is the tool to call before changing anything — it also reports what is still missing before the campaign can launch, in_readiness.blockers, which must be empty before campaign_launch. Read status here before choosing how to edit copy: flow_set for a DRAFTED campaign, sequence_update only once it is ACTIVE or PAUSED. A settings-and-counters snapshot: for the sequence in detail use flow_get, for performance analytics_campaign, and for the people lead_list.
Parameters
string
required
Campaign id, from
campaign_list or campaign_create.boolean
default:"true"
Include a readable outline of the campaign sequence.
campaign_launch
Write Destructive Start a campaign. THIS BEGINS SENDING REAL OUTREACH to real people from the connected LinkedIn account and mailboxes — invitations, messages and emails go out on the configured schedule. Runcampaign_get first and clear every blocker: a saved flow, a lead source, a sending account, and (for CSV campaigns) a finished import. Show the user the full sequence and the audience and get an explicit yes in the conversation before calling — not an assumed one. Launch rebuilds every step from the saved flow graph, so any sequence_update edit made while the campaign was a draft is overwritten here; fix a draft’s copy with flow_set instead. This is the only tool that starts a campaign. Pausing or resuming one afterwards has no tool at all and happens in the web app.
Parameters
string
required
Campaign id, from
campaign_list or campaign_create.boolean
default:"false"
Skip the local readiness check and let the backend decide. Only useful if the check is wrong.
campaign_list
Read-only Campaigns in your account, newest first, 20 per page. Usestatus to filter — DRAFTED campaigns are the ones still being built, ACTIVE ones are sending right now. DELETED campaigns never appear here, which is why a deletion looks like a disappearance. The list view, a few fields each: for one campaign in full use campaign_get, and for performance analytics_campaign. Passing userId to read a sub-account’s campaigns is accepted only from an account owner.
Parameters
ACTIVE | PAUSED | FAILED | DELETED | COMPLETED | ARCHIVED | DRAFTED
Filter by lifecycle status.
string
Search campaign titles.
integer (min 1)
default:"1"
1-indexed page number.
string
Sub-account owner id. Omit for your own campaigns.
campaign_logs
Read-only Chronological record of everything that happened to a campaign: created, started, paused, resumed, lead sources added, settings changed, limits hit. Changes to the CAMPAIGN, written by whoever made them — the audit trail to read when a user asks why a campaign stopped or who changed a limit. Not what happened to the prospects: that isactivity_list, lead_get or sequence_step_stats.
Parameters
string
required
Campaign id, from
campaign_list or campaign_create.campaign_preview_message
Read-only Render a draft message against a real lead from the campaign so you can see how the merge fields resolve before committing the copy to a step. Nothing is sent and nothing is saved — this is the safe way to check a {{placeholder}} actually resolves, since an unknown one renders empty rather than failing. Save the copy withflow_set; to put a real email in front of yourself instead, campaign_send_test_email.
Parameters
string
required
Campaign id, from
campaign_list or campaign_create.string
required
Draft copy, including {{firstName}}-style placeholders.
campaign_send_test_email
Write Destructive Send one real email to an address you control, using a campaign mailbox, so you can check rendering and deliverability before launch. This does send mail: show the user the recipient, subject and body and get an explicit yes first. Only ever to an address they control — it is not a way to message a prospect, and there is no tool for that. To check merge fields without sending anything, usecampaign_preview_message.
Parameters
string
required
Campaign id, from
campaign_list or campaign_create.string
required
Mailbox to send from. See
email_account_list.string (email)
required
Where to send the test. Use your own address.
string
required
Email body.
string
Subject line.
boolean
Send as plain text rather than HTML.
campaign_set_source
Write Destructive Point a DRAFTED campaign at where its prospects come from: a LinkedIn/Sales Navigator search URL, a group, an event, a post, or a CRM segment. For an ACTIVE campaign usecampaign_add_prospects instead — that adds to the existing pool rather than replacing the source.
Parameters
string
required
Campaign id, from
campaign_list or campaign_create.string
A LinkedIn LIST url — a basic search, a Sales Navigator (
/sales/) search, a Recruiter (/talent/) search, or a group / event / post. Not a single profile. Required unless using a CRM source.sales-navigator | recruiter | basic
Assert which LinkedIn surface the url belongs to. The call is rejected if the url does not match, the same way the web app validates its Sales Navigator and Recruiter tabs. Omit to detect it.
enum (9 values)
Override the inferred source type. Use “hubspot” or “ghl” for CRM pulls.
string
CRM sources: the contact property holding the LinkedIn profile URL.
string
CRM sources: the segment / list / filter query to pull.
campaign_update
Write Change a campaign’s SETTINGS: title, sending accounts, schedule, daily limits, timezone and every safety toggle. Only the fields you pass are changed. Attaching accounts is done here: onelinkedAccountId for LinkedIn steps, and emailAccountIds — a list — for EMAIL steps. Ask the user which accounts when there is a choice. NOT this tool: campaign status. It cannot start, pause, resume, archive or delete a campaign, and there is no status parameter. To start one use campaign_launch; to remove one use campaign_delete. Pausing, resuming and archiving are web-app only and have no tool at all — say so rather than looking for a substitute. Nor does it touch the sequence (flow_set) or the audience (campaign_set_source). One side effect worth knowing: changing linkedAccountId rewrites that account onto every lead already in the campaign, not just future ones.
Parameters
string
required
Campaign id, from
campaign_list or campaign_create.string
Short label.
string
The ONE LinkedIn account this campaign sends from. Required for any LinkedIn step. A campaign cannot use two. If
linkedin_account_list returns more than one, ask the user which — do not pick for them.string[]
Mailboxes for EMAIL steps. Unlike the LinkedIn account, several are allowed and sends rotate across them. Only attach these if the user wants email steps, and ask which mailboxes.
string
IANA timezone, e.g. “America/New_York”. Governs the schedule.
object
Sending window per weekday, keyed 0 (Sunday) to 6 (Saturday), in the campaign timezone.
object
Per-day caps per step type. Note the field spelling.
string[]
Tag ids applied to every lead in this campaign — this identifies the campaign’s leads, so it should be a tag belonging to THIS campaign. Never reuse another campaign’s tag: the two campaigns’ leads then become indistinguishable. Mint one with
tag_create (short label, interest NEUTRAL) and pass its id. Pass [] to remove all tags.object (free-form)
Assign leads to team members. Shape mirrors the web app.
string
Ordering strategy for working the lead queue, e.g. “newest” / “oldest”.
boolean
Halt a lead’s sequence as soon as they reply. Default true.
boolean
Skip prospects you already have an open conversation with.
boolean
Never enrol the same profile in two campaigns. Default true.
Only target LinkedIn Premium / Open Profile members.
boolean
Target existing 1st-degree connections instead of new ones.
boolean
Use Sales Navigator messaging. Requires a Premium LinkedIn account.
boolean
Work newly-found prospects before older ones.
boolean
Re-run the search periodically to pull in newly matching prospects.
boolean
EMAIL steps: insert an open-tracking pixel.
boolean
EMAIL steps: rewrite links for click tracking.
boolean
Send email as plain text. Better deliverability, no tracking.
boolean
Pause the campaign without changing its status.
string | number
Future timestamp to auto-start the campaign, instead of launching it now with
campaign_launch.string
AI agent that answers replies in this campaign’s inbox. Pass null to detach it. Never set this on your own: an agent writes to real prospects without further approval. Ask the user whether they want one, and offer both routes — pick an existing agent from
agent_list, or build one with agent_upsert, give it material with kb_upsert and kb_attach, then agent_train. A campaign with no agent is perfectly normal; replies just come to the inbox.campaign_upload_leads
Write Bulk-load prospects into a campaign from parsed CSV rows.header maps each column name to a platform field — profileUrl, salesNavUrl, recruiterUrl, email, firstName, lastName, fullName, personalization, phone, website, or “customVariable” to keep it as a merge field. Rows with neither a profile URL nor an email are skipped silently. Import runs asynchronously; the campaign is only launchable once isFiltered flips true. Use this when the user has a list in hand. When they describe an audience instead, the audience is a LinkedIn search and belongs in campaign_set_source — build the URL with search_url_build. For a campaign that is already running, neither applies: that is campaign_add_prospects.
Parameters
string
required
Campaign id, from
campaign_list or campaign_create.object (free-form)
required
{ “CSV Column Name”: “targetField” }. Use “customVariable” for anything you want as a merge field.
array of object (free-form)
required
Row objects keyed by the CSV column names used in
header.boolean
default:"true"
Skip prospects already enrolled in another active or paused campaign on this account.
search_url_build
Read-only Turn an audience description into a LinkedIn or Sales Navigator people-search URL, so a campaign source can be described rather than pasted. Returns the url plus what it managed to express — hand it tocampaign_set_source.
What it can build: job titles (included and excluded) and free-text keywords with boolean operators. What it CANNOT build: geography, industry, company size, seniority and years-in-role. Sales Navigator only accepts those as numeric ids from its own typeahead (id:103644278 is United States), they cannot be derived from a name, and a wrong id silently searches the wrong audience. For those, either ask the user to paste a Sales Navigator URL with the filters already set, or pass the ids through extraFilters if the user supplies them. Never guess one.
Recruiter (/talent/) URLs cannot be built at all — ask the user for one.
Parameters
basic | sales-navigator
required
“basic” is ordinary LinkedIn search; “sales-navigator” needs a Sales Navigator seat.
string
Free text. Supports boolean operators, e.g. ‘“chatbot” OR “AI agent”’.
string[]
Job titles to include, as plain text.
string[]
Job titles to exclude. Sales Navigator only — basic search cannot express an exclusion.
string
Basic search only: current company, free text.
string
Basic search only: school, free text.
string
Basic search only.
string
Basic search only.
object[]
Id-based filters, only when the USER supplied the ids or they came from a URL they pasted. Do not populate this from memory.
