MCP
Tool reference
The 201 tools the server offers. An assistant is shown only the ones your permissions and its granted scope allow, so the list it works from may be shorter than this one.
Arguments are camelCase over MCP. Each tool is also a REST endpoint taking the same arguments in snake_case; the link beside a tool goes to its page in the API reference, which carries request and response samples. A tool failure comes back as a result with isError: true and a sentence the assistant can act on, not as a protocol error.
Workspace
workspace_overviewWorkspace overview
The workspace's plan, credit balance, connected channels and agent count. Start here: it says what the rest of the tools will find.
- Scope
read- Needs
- View on Settings
- REST
- GET/workspace
Takes no arguments.
list_workspacesList client workspaces
The organization's client workspaces, for an agency. Each is an isolated set of contacts, campaigns, senders and conversations. Answers only in the agency workspace. Over the REST API, pass an id as the X-Workspace-Id header to act inside that workspace with an agency key.
- Scope
read- Needs
- View on Settings
- REST
- GET/workspaces
Takes no arguments.
get_workspace_settingsRead the workspace settings
The workspace's steering settings as Settings shows them: its goal, the send window the launcher sends inside (with the platform default when none is saved), the countries it sells to (servedCountries, ISO codes; empty is no preference, and every automatic lead search is held to them), the sender of record (legal entity and postal address), the logo URL, and the monitoring keywords the intent signals search for. Read before changing any of them.
- Scope
read- Needs
- View on Workspace context
Takes no arguments.
set_send_windowSet the send window
Sets the hours and weekdays this workspace sends in, in one timezone. The launcher sends only inside the window, paced so every sender's daily limit is reached by close. The same rules as Settings: whole hours, the day must end after it starts, at least one day.
- Scope
write- Needs
- Read and write on Workspace context
Arguments
timezonestringoptional- IANA timezone, e.g. Europe/London. Omit for America/New_York.
startHourintegerrequired- First sending hour, 0 to 23, in the timezone.
endHourintegerrequired- Hour sending stops, 1 to 24, exclusive. Must be after startHour.
daysinteger[]required- ISO weekdays that send: 1 is Monday, 7 is Sunday.
set_served_countriesSet the countries the workspace sells to
Replaces the countries this workspace sells to. Every automatic lead search (the daily sourcing pull, onboarding sourcing and the prospect tools) looks only for people in these countries, and skips anyone whose company is on record elsewhere. Pass the whole list, not only additions: read it first with get_workspace_settings. An empty list is no preference. Change it only when the person asks.
- Scope
write- Needs
- Read and write on Workspace context
Arguments
countriesstring[]required- Country names or ISO alpha-2 codes, e.g. ["United States", "CA", "United Kingdom"]. Empty for no preference.
set_workspace_goalSet the workspace goal
Sets the overarching goal the CEO agent steers toward, one sentence to a short paragraph. With a goal set, it reads the workspace's numbers once a day, briefs the person in Notifications and nudges the specialist that should run next. An empty goal turns steering off.
- Scope
write- Needs
- Read and write on Workspace context
Arguments
goalstringrequired- The goal, up to 1,000 characters. Empty clears it and stops steering.
set_sender_identitySet the sender of record
Sets the legal entity name and postal address recorded as the sender of record on every email this workspace sends. Neither is printed in the email. Both are replaced; an empty value clears one. Use only the person's own legal details, never invented ones.
- Scope
write- Needs
- Read and write on Settings
Arguments
legalEntityNamestringrequired- The registered legal name of the sending business.
postalAddressstringrequired- Its full postal address.
set_logo_urlSet the workspace logo
Sets the workspace's logo to an image at a public URL, or clears it with null. Uploading a file is done on the Branding screen.
- Scope
write- Needs
- Read and write on Settings
Arguments
logoUrlstring | nullrequired- A full https URL to a PNG, JPEG, WebP or SVG, or null to clear it.
Contacts
list_contactsList contacts
Contacts in the workspace. Filter as the Contacts table does (status, interest, minimum intent heat, list, label, sourcing agent, industry, location, company size, has email, has phone) or by having a LinkedIn profile; sort newest first or hottest first. Every contact is in-ICP by construction: fit_score is intent heat from 1 to 5, and 4 or more is high intent. intent_evidence_at is when engagement was last observed; LinkedIn outreach waits for intent evidence. For "high-intent leads" use minHeat 4, not a status or interest value.
- Scope
read- Needs
- View on Contacts
- REST
- GET/contacts
Arguments
statusstringoptional- Outbound state. Not an intent measure; use minHeat for that.
newresearchingqueuedcontactedrepliedmeeting_bookedbounceddisqualifiedsuppressedlost intereststringoptional- Your team's read of their interest, set by hand or from a reply.
interestedmaybenot_interestedunknown minHeatintegeroptional- Only contacts whose intent heat (fit_score) is at least this. 4 or more is high intent.
hasLinkedinbooleanoptional- Only contacts with a LinkedIn profile URL, which LinkedIn outreach needs.
sortstringoptionaldefault: newest- newest: most recently added first. heat: hottest first, then most recent intent evidence.
newestheat searchstringoptional- Matches name, email, company or title, as the Contacts search box does.
labelIdstring | nulloptional- Only contacts carrying this label. Take the id from list_labels.
agentIdstring | nulloptional- Only contacts this agent sourced. Take the id from list_agents.
industrystringoptional- Industry contains this text.
locationstringoptional- Location contains this text.
companySizestringoptional- Exact headcount band, as the contact holds it, e.g. 51-200.
hasEmailbooleanoptional- true: only contacts with an email. false: only contacts without one.
hasPhonebooleanoptional- true: only contacts with a phone. false: only contacts without one.
listIdstring | nulloptional- Optional. Omit this field or use null to search all workspace contacts. Only pass a real static list ID returned by list_lists; never use zero/FF placeholders.
limitintegeroptionaldefault: 25- Rows per page, 1 to 100.
cursorstringoptional- Opaque cursor from the previous page's next_cursor. Omit for the first page. Keep every other argument the same while paging.
get_contactGet a contact
One contact in full, including research, signals, the labels they carry, the lists they are on, and their ten most recent conversations.
- Scope
read- Needs
- View on Contacts
Arguments
contactIdstringrequired- The contact's id.
read_linkedin_profileRead a LinkedIn profile
Reads one person's public LinkedIn profile through the workspace's connected LinkedIn account: headline, about, current role, recent positions and location. Use it before writing to somebody — it is what personalisation should be built on, and it works on the first day of a workspace when there is no sent history to learn from. One person per call; LinkedIn counts these against the operator's own account.
- Scope
read- Needs
- View on Contacts
Arguments
contactIdstringoptional- A contact in this workspace. Its stored LinkedIn URL is used.
profileUrlstringoptional- A LinkedIn profile URL, if you do not have a contact id.
push_contacts_to_crmPush contacts to a CRM
Writes chosen contacts into the workspace's connected CRMs as contact records with a note — up to 100 per call, by id or by static list. Replies, opt-outs and booked meetings already reach the CRM on their own; this is for people the operator wants there now, such as a freshly imported list or the leads a campaign qualified. Pass provider to write into one CRM only. A person with no email is skipped, since CRMs upsert on it. Sends nothing to the contact.
- Scope
write- Needs
- Read and write on Contacts
Arguments
contactIdsstring[] | nulloptional- Contacts to push, up to 100. Use null with listId.
listIdstring | nulloptional- A static list whose members are pushed, up to 100. Use null with contactIds.
providerstring | nulloptional- Only this CRM. Omit to reach every connected CRM.
hubspotpipedriveattiosalesforcezohogohighlevel notestring | nulloptional- What the CRM note should say. Defaults to who the person is and where they stand.
create_contactCreate a contact
Adds one person to Contacts, bypassing sourcing. Needs an email or a LinkedIn URL: a contact no channel can reach is refused. Checked against workspace and platform suppression (the address, its domain, the company's domain and the LinkedIn profile) before it is written, and deduplicated inside the workspace on LinkedIn URL, then email. The contact starts cold (intent heat 1) with status new. This creates a row; it does not send anything and spends no credits.
- Scope
write- Needs
- Read and write on Contacts
- REST
- POST/contacts
Arguments
emailstring | nulloptional- Work or personal address. Lowercased and deduplicated on.
linkedinUrlstring | nulloptional- LinkedIn profile URL. The key sourced contacts dedupe on.
firstNamestring | nulloptional- Given name.
lastNamestring | nulloptional- Family name.
fullNamestring | nulloptional- Display name. Built from first and last name when omitted.
titlestring | nulloptional- Job title.
phonestring | nulloptional- Phone number. Stored in E.164 when it parses, as written when not.
companyNamestring | nulloptional- Employer.
companyDomainstring | nulloptional- Employer's web domain. Lets suppression match at company scope.
companyUrlstring | nulloptional- Employer's website.
industrystring | nulloptional- Industry label.
companySizestring | nulloptional- Headcount band, as free text.
locationstring | nulloptional- City or region.
countrystring | nulloptional- Country name or ISO 3166-1 alpha-2 code. Stored as the code. The send window uses it to run on the recipient's clock.
notesstring | nulloptional- Free-text notes shown on the contact.
listIdstring | nulloptional- Optional existing static list ID from list_lists. Use null when absent; never invent an ID.
import_contactsImport contacts
Adds up to 250 of your own people to Contacts in one call; call again for more. Each row needs an email or a LinkedIn URL. Rows are deduplicated inside the batch and against the workspace, and checked against suppression, before anything is written. Pass listId or listName to land everyone, including people already present, on a static list. Spends no credits and sends nothing. For people from the prospect database use import_prospects instead.
- Scope
write- Needs
- Read and write on Contacts
Arguments
contactsobject[]required- The people to add, up to 250.
emailstring | nulloptional- Work or personal address. Lowercased and deduplicated on.
linkedinUrlstring | nulloptional- LinkedIn profile URL. The key sourced contacts dedupe on.
firstNamestring | nulloptional- Given name.
lastNamestring | nulloptional- Family name.
fullNamestring | nulloptional- Display name. Built from first and last name when omitted.
titlestring | nulloptional- Job title.
phonestring | nulloptional- Phone number. Stored in E.164 when it parses, as written when not.
companyNamestring | nulloptional- Employer.
companyDomainstring | nulloptional- Employer's web domain. Lets suppression match at company scope.
companyUrlstring | nulloptional- Employer's website.
industrystring | nulloptional- Industry label.
companySizestring | nulloptional- Headcount band, as free text.
locationstring | nulloptional- City or region.
countrystring | nulloptional- Country name or ISO 3166-1 alpha-2 code. Stored as the code. The send window uses it to run on the recipient's clock.
notesstring | nulloptional- Free-text notes shown on the contact.
listIdstring | nulloptional- Existing static list ID from list_lists. Use null when using listName to create or find a list. Never invent an ID.
listNamestring | nulloptional- A static list everyone joins, created if it does not exist. Set listId to null when using this field.
update_contactUpdate a contact
Corrects what is known about one contact, sets their interest, or moves them on the pipeline board. Only the fields you pass change; pass null to clear a text field. A new email, LinkedIn URL or company domain is checked against suppression the way create_contact checks a new person, and is refused when it is blocked or when another contact in the workspace already has it; a contact always keeps an email or a LinkedIn URL. Moving the stage to lost also marks the contact lost, and moving it to booked records a meeting and announces it to attached CRMs, exactly as dragging the card does.
- Scope
write- Needs
- Read and write on Contacts
Arguments
contactIdstringrequired- The contact's id.
emailstring | nulloptional- Email address. Checked against suppression before it is saved.
linkedinUrlstring | nulloptional- LinkedIn profile URL. Checked against suppression before it is saved.
firstNamestring | nulloptional- Given name.
lastNamestring | nulloptional- Family name.
fullNamestring | nulloptional- Display name.
titlestring | nulloptional- Job title.
phonestring | nulloptional- Phone number.
companyNamestring | nulloptional- Employer.
companyDomainstring | nulloptional- Employer's web domain.
industrystring | nulloptional- Industry label.
companySizestring | nulloptional- Headcount band.
locationstring | nulloptional- City or region.
countrystring | nulloptional- Country name or ISO alpha-2 code.
notesstring | nulloptional- Free-text notes.
intereststringoptional- Your read of their interest.
interestedmaybenot_interestedunknown pipelineStagestringoptional- The inbox board column to move them to.
unansweredwaiting_connectionconnectedfirst_touchfollow_upinterestedbookedlost
update_contactsSet interest on many contacts
Sets your team's read of interest (interested, maybe, not_interested or unknown) on many contacts at once, exactly as the Contacts screen's bulk bar does. For any other field, or one person, use update_contact. Sends nothing and spends nothing.
- Scope
write- Needs
- Read and write on Contacts
Arguments
contactIdsstring[]required- Contact ids, up to 5,000 a call. Read them from list_contacts.
intereststringrequired- The interest to set on every one of them.
interestedmaybenot_interestedunknown
disqualify_contactsDisqualify contacts
Marks contacts as not worth pursuing and stops their pending outreach. With suppress: true it also adds each contact's email and LinkedIn URL to the workspace blocklist, so sourcing cannot rediscover them, and marks them suppressed. Suppressing needs compliance access as well and is refused without it.
- Scope
write- Needs
- Read and write on Contacts
Arguments
contactIdsstring[]required- Contact ids, up to 5,000 a call. Read them from list_contacts.
suppressbooleanoptionaldefault: false- Also add their identities to the workspace blocklist.
delete_contactsDelete contacts
Permanently deletes contacts with their conversations, messages and queued steps. Cannot be undone. Suppression rows are deliberately kept: deleting somebody who opted out must not make them contactable again. To stop outreach without losing history, use disqualify_contacts.
- Scope
write- Needs
- Read and write on Contacts
Arguments
contactIdsstring[]required- Contact ids, up to 5,000 a call. Read them from list_contacts.
export_contactsExport contacts
Exports contacts as the Contacts screen's CSV download does: the same columns, which re-import cleanly, with labels last. Pass contactIds for a selection, or the table's filters (a list, a label, status, heat and the rest) for everyone matching, up to 5,000. Answers with CSV text, the first 500 rows unless you raise limit, and says when it stopped short. Over the REST API it answers with the rows as JSON instead.
- Scope
read- Needs
- View on Contacts
Arguments
contactIdsstring[] | nulloptional- Export exactly these contacts, in this order. Omit to export by filter.
searchstring | nulloptional- Matches name, email, company or title, as the Contacts search box does.
statusstring | nulloptional- Outbound state.
newresearchingqueuedcontactedrepliedmeeting_bookedbounceddisqualifiedsuppressedlost intereststring | nulloptional- Your team's read of their interest.
interestedmaybenot_interestedunknown minHeatinteger | nulloptional- Only contacts whose intent heat (fit_score) is at least this.
agentIdstring | nulloptional- Only contacts this agent sourced (from list_agents).
listIdstring | nulloptional- Only members of this list (from list_lists).
labelIdstring | nulloptional- Only contacts carrying this label (from list_labels).
industrystring | nulloptional- Industry contains this text.
locationstring | nulloptional- Location contains this text.
companySizestring | nulloptional- Exact headcount band, as the contact holds it.
hasEmailboolean | nulloptional- true: only with an email. false: only without.
hasPhoneboolean | nulloptional- true: only with a phone. false: only without.
limitintegeroptionaldefault: 500- The most rows to hand back.
get_contact_historyRead a contact's history
Everything between the workspace and one contact on email, LinkedIn and SMS, oldest first: what was sent (with bounces and opens), what they wrote back, what is scheduled to go and when, and drafts waiting for a person, each with the campaign and step it came from. rewriteBeforeSending marks a scheduled message that will be rewritten to follow the workspace's latest copy lessons before it goes. upNext lists the campaign steps queued for them that have no message written yet, soonest first, with why the launcher is holding one when it says. Pages back in time with nextCursor.
- Scope
read- Needs
- View on Inbox
Arguments
contactIdstringrequired- The contact's id, from list_contacts or get_contact.
limitintegeroptionaldefault: 100- Messages per page, 1 to 200.
cursorstringoptional- nextCursor from the previous page, for the messages before it. Omit for the most recent.
Lists
list_listsList the lists
Lists (audiences) in the workspace, newest first, with how many members each static list holds. A static list holds the people put on it; a signal list resolves to whoever a signal matched; a filter list is a saved description. Campaigns target lists.
- Scope
read- Needs
- View on Contacts
- REST
- GET/lists
Arguments
kindstringoptional- Only lists of this kind.
staticsignalfilter limitintegeroptionaldefault: 25- Rows per page, 1 to 100.
cursorstringoptional- Opaque cursor from the previous page's next_cursor. Omit for the first page. Keep every other argument the same while paging.
create_listCreate a list
Creates an empty static list. Put people on it with add_contacts_to_list, or name it as listName on an import. A list with the same name is refused rather than duplicated.
- Scope
write- Needs
- Read and write on Contacts
- REST
- POST/lists
Arguments
namestringrequired- The list's name. Name it after the ICP it holds.
descriptionstringoptional- What the list is for.
add_contacts_to_listAdd contacts to a list
Puts contacts on a static list. Contacts already on it are left alone, and ids that are not contacts of this workspace are ignored and reported.
- Scope
write- Needs
- Read and write on Contacts
Arguments
listIdstringrequired- The static list's id.
contactIdsstring[]required- Contact ids, up to 500 a call.
remove_contacts_from_listRemove contacts from a list
Takes contacts off a static list. The contacts themselves are untouched, and steps a campaign already queued for them are not cancelled.
- Scope
write- Needs
- Read and write on Contacts
Arguments
listIdstringrequired- The static list's id.
contactIdsstring[]required- Contact ids, up to 500 a call.
rename_listRename a list
Renames a list (audience) of any kind, and optionally rewrites its description. A name another list in the workspace already has is refused. Campaigns and agents that use the list keep using it. The workspace's ICP sourcing pool (“ICP: <default ICP name>”) keeps its name, because sourcing and campaigns with ICP sourcing on find it by name; its description can still change.
- Scope
write- Needs
- Read and write on Contacts
Arguments
listIdstringrequired- The list's id, from list_lists.
namestringrequired- The new name.
descriptionstring | nulloptional- The new description. Omit to keep the current one; null or empty clears it.
delete_listDelete a list
Permanently deletes a list (audience). Its contacts stay in the workspace. Every campaign drawing from it stops taking new people from it, and steps already queued for its members are not cancelled; agents stop drawing from it and routing rules that sent contacts to it are deleted. Refused while a campaign build is still filling it, and for the workspace's ICP sourcing pool (“ICP: <default ICP name>”), which campaigns with ICP sourcing on draw from by name; remove_contacts_from_list takes people out of it instead. Delete only what the person asked to remove.
- Scope
write- Needs
- Read and write on Contacts
Arguments
listIdstringrequired- The list's id, from list_lists.
Prospects
list_prospect_filtersList the prospect filter axes
Returns every axis a prospect query can narrow on — fifteen lookup fields in four groups plus contact_info — with the group each belongs to and what narrowing on it means. Free. Call it once before planning a search so the filters you build name axes the database actually honours; a misspelled axis matches everybody rather than erroring.
- Scope
read- Needs
- View on Contacts
Takes no arguments.
resolve_prospect_filterResolve a prospect filter value
Turns a label into the id a prospect filter matches on, with a count of matching records so a query can be sized before it is run. Fields, by group — job_info: job_title, seniority_level, department. company_info: company_industry, sic_codes, company_employee_count, company_revenue, company_name. company_location: company_country, company_state, company_city. location: country, state, city, personal_zip. advanced: social_connections, homeowner, net_worth, income_range, children, married, age_range. company_employee_count, company_revenue and the advanced fields are fixed bands, not lookups: resolve_prospect_filter answers them from their options (a range such as 18-25 returns every band it overlaps) and list_prospect_filters lists them. sic_codes, personal_zip and the advanced fields exist only with freshOnly: true and are refused otherwise, so a query using one resolves every other filter with freshOnly: true as well. In that corpus a person's city is rarely filled in: narrow a metro there with personal_zip, whose ids are the 5-digit ZIPs themselves (pass the metro's ZIPs together), or with state. Without a fresh-only axis, prefer freshOnly: false for a city, which resolves cities well. Job titles are exact labels: resolve the job and pass every returned label that is the same job (Life Insurance Agent, Licensed Life Insurance Agent, Independent Life Insurance Agent) as one ORed list. company_industry is a coarse list of about 150 labels per corpus; trades and local services (plumbing, roofing, HVAC, electrical, landscaping) are not on it. For those use sic_codes with freshOnly: true: the id is the 4-digit code itself (1711 plumbing, heating and air-conditioning contractors; 1761 roofing, siding and sheet metal; 1731 electrical work), the lookup's list is partial and reports no counts, so pass a code you know and size it with count_prospects. Resolve with the same freshOnly you intend to search with — the two corpora number their values differently and an id from the wrong one silently matches nothing. The answer's freshOnly says which corpus its ids belong to.
- Scope
read- Needs
- View on Contacts
Arguments
fieldstringrequired- The axis to resolve on, e.g. job_title, company_industry, state, age_range.
querystringrequired- The label to look up, e.g. Texas or VP Sales. For a band axis, the range asked for, e.g. 18-25.
freshOnlybooleanoptional- Which corpus to resolve in. Defaults true. Must match the search. Fresh-only axes are always resolved in the fresh corpus.
limitnumberoptional- How many candidate values to return. Defaults to 8.
offsetintegeroptional- Skip this many candidates, to page past the first ones on a long axis, as the Search screen's typeahead scrolls. Defaults to 0.
count_prospectsSize a prospect query
Returns how many prospects match a filter set, without returning any of them. Free. Use it to check an ICP is neither empty nor the whole database before searching.
- Scope
read- Needs
- View on Contacts
Arguments
savedSearchIdstringoptional- A saved search's id from list_saved_searches. Runs that search's own filters and corpus, exactly as the Search screen does. Use it instead of search when the operator names a saved search; never pass a saved search's name as search.
searchstringoptional- The Search screen's own filter model, as the compact JSON string list_saved_searches returns and save_search takes: {"job_info":{"job_title":{"include":[{"value":"<id>","label":"VP Sales"}]}},"company_employee_count":["3"]}. Lookup ids come from resolve_prospect_filter in the corpus the model searches (the whole database unless it uses sic_codes or an advanced axis). When given it replaces filters, freshOnly, enrichedOnly, liOnly and contactInfo, and the corpus follows from it. Every tool that takes it must be passed the same string.
filtersobjectoptional- Filter groups, each an object of field -> array of numeric ids from resolve_prospect_filter. job_info: job_title, seniority_level, department. company_info: company_industry, sic_codes, company_employee_count, company_revenue, company_name. company_location: company_country, company_state, company_city. location: country, state, city, personal_zip. advanced: social_connections, homeowner, net_worth, income_range, children, married, age_range. company_employee_count, company_revenue and the advanced fields are fixed bands, not lookups: resolve_prospect_filter answers them from their options (a range such as 18-25 returns every band it overlaps) and list_prospect_filters lists them. sic_codes, personal_zip and the advanced fields exist only with freshOnly: true and are refused otherwise, so a query using one resolves every other filter with freshOnly: true as well. In that corpus a person's city is rarely filled in: narrow a metro there with personal_zip, whose ids are the 5-digit ZIPs themselves (pass the metro's ZIPs together), or with state. Without a fresh-only axis, prefer freshOnly: false for a city, which resolves cities well. Job titles are exact labels: resolve the job and pass every returned label that is the same job (Life Insurance Agent, Licensed Life Insurance Agent, Independent Life Insurance Agent) as one ORed list. company_industry is a coarse list of about 150 labels per corpus; trades and local services (plumbing, roofing, HVAC, electrical, landscaping) are not on it. For those use sic_codes with freshOnly: true: the id is the 4-digit code itself (1711 plumbing, heating and air-conditioning contractors; 1761 roofing, siding and sheet metal; 1731 electrical work), the lookup's list is partial and reports no counts, so pass a code you know and size it with count_prospects. E.g. {job_info:{seniority_level:[3]}, location:{state:[44]}}. Narrow step by step: add one axis, count, then add the next. Flat keys are accepted too.
freshOnlybooleanoptional- Defaults true. Selects which corpus — and therefore which id vocabulary — applies: every lookup, count, search and import for one market uses the same value. freshOnly: true is required by sic_codes, personal_zip and the advanced bands (age, income, homeowner…); there, narrow a place by state or personal_zip, because few people in that corpus have a city. freshOnly: false is the whole database and resolves cities well. When switching, re-resolve every filter in the other corpus. The fresh corpus holds United States people only; a workspace that sells elsewhere searches with freshOnly: false.
enrichedOnlybooleanoptional- Defaults false. Only people the corpus already holds contact details for. Cheaper to reveal, smaller pool.
liOnlybooleanoptional- Defaults false. Only people with a LinkedIn profile URL, which every LinkedIn step needs.
contactInfostring[]optional- Require that a profile already holds these details, e.g. ["phone"] for an SMS audience. Narrows to people a reveal can answer for.
emailwork_emailphone
search_prospectsSearch the prospect database
Returns a page of prospects matching a filter set, 25 by default and up to 100. Free. Contact details come back empty; use enrich_prospects on the ids worth revealing. alreadyInWorkspace marks people this workspace already holds as contacts (contactId says which), so they are not bought twice. To run a saved search pass its savedSearchId (or its filters as search, never its name); that search is then remembered in the person's recent searches, as it is on the screen. filtersApplied says what the search was narrowed by, "none" meaning the whole database: quote it when you tell the person what you found.
- Scope
read- Needs
- View on Contacts
Arguments
savedSearchIdstringoptional- A saved search's id from list_saved_searches. Runs that search's own filters and corpus, exactly as the Search screen does. Use it instead of search when the operator names a saved search; never pass a saved search's name as search.
searchstringoptional- The Search screen's own filter model, as the compact JSON string list_saved_searches returns and save_search takes: {"job_info":{"job_title":{"include":[{"value":"<id>","label":"VP Sales"}]}},"company_employee_count":["3"]}. Lookup ids come from resolve_prospect_filter in the corpus the model searches (the whole database unless it uses sic_codes or an advanced axis). When given it replaces filters, freshOnly, enrichedOnly, liOnly and contactInfo, and the corpus follows from it. Every tool that takes it must be passed the same string.
filtersobjectoptional- Filter groups, each an object of field -> array of numeric ids from resolve_prospect_filter. job_info: job_title, seniority_level, department. company_info: company_industry, sic_codes, company_employee_count, company_revenue, company_name. company_location: company_country, company_state, company_city. location: country, state, city, personal_zip. advanced: social_connections, homeowner, net_worth, income_range, children, married, age_range. company_employee_count, company_revenue and the advanced fields are fixed bands, not lookups: resolve_prospect_filter answers them from their options (a range such as 18-25 returns every band it overlaps) and list_prospect_filters lists them. sic_codes, personal_zip and the advanced fields exist only with freshOnly: true and are refused otherwise, so a query using one resolves every other filter with freshOnly: true as well. In that corpus a person's city is rarely filled in: narrow a metro there with personal_zip, whose ids are the 5-digit ZIPs themselves (pass the metro's ZIPs together), or with state. Without a fresh-only axis, prefer freshOnly: false for a city, which resolves cities well. Job titles are exact labels: resolve the job and pass every returned label that is the same job (Life Insurance Agent, Licensed Life Insurance Agent, Independent Life Insurance Agent) as one ORed list. company_industry is a coarse list of about 150 labels per corpus; trades and local services (plumbing, roofing, HVAC, electrical, landscaping) are not on it. For those use sic_codes with freshOnly: true: the id is the 4-digit code itself (1711 plumbing, heating and air-conditioning contractors; 1761 roofing, siding and sheet metal; 1731 electrical work), the lookup's list is partial and reports no counts, so pass a code you know and size it with count_prospects. E.g. {job_info:{seniority_level:[3]}, location:{state:[44]}}. Narrow step by step: add one axis, count, then add the next. Flat keys are accepted too.
freshOnlybooleanoptional- Defaults true. Selects which corpus — and therefore which id vocabulary — applies: every lookup, count, search and import for one market uses the same value. freshOnly: true is required by sic_codes, personal_zip and the advanced bands (age, income, homeowner…); there, narrow a place by state or personal_zip, because few people in that corpus have a city. freshOnly: false is the whole database and resolves cities well. When switching, re-resolve every filter in the other corpus. The fresh corpus holds United States people only; a workspace that sells elsewhere searches with freshOnly: false.
enrichedOnlybooleanoptional- Defaults false. Only people the corpus already holds contact details for. Cheaper to reveal, smaller pool.
liOnlybooleanoptional- Defaults false. Only people with a LinkedIn profile URL, which every LinkedIn step needs.
contactInfostring[]optional- Require that a profile already holds these details, e.g. ["phone"] for an SMS audience. Narrows to people a reveal can answer for.
emailwork_emailphone pagenumberoptional- 1-based page of the match. Defaults to 1.
pageSizenumberoptional- How many to return, 1 to 100. Defaults to 25.
enrich_prospectsReveal prospect contact details
Reveals email, work email and phone for prospect ids from search_prospects. Spends workspace credits: each person revealed is metered as enrich.reveal, the same rate the Enrich button pays, and the call refuses when the balance cannot cover it. Pass fields to buy only what the campaign needs, e.g. {phone:true,email:false,workEmail:false} for SMS. IMPORTANT: pass the same filters and freshOnly (or search, or savedSearchId) you searched with. An id is resolved against the population those flags describe, so omitting them enriches a different person and charges for it; a call with no filters at all is refused.
- Scope
write- Needs
- Read and write on Contacts
Arguments
idsstring[]required- Prospect ids from search_prospects.
fieldsobjectoptional- Which details to buy. Each defaults to true: {email, workEmail, phone}.
emailbooleanoptionalworkEmailbooleanoptionalphonebooleanoptionalsavedSearchIdstringoptional- A saved search's id from list_saved_searches. Runs that search's own filters and corpus, exactly as the Search screen does. Use it instead of search when the operator names a saved search; never pass a saved search's name as search.
searchstringoptional- The Search screen's own filter model, as the compact JSON string list_saved_searches returns and save_search takes: {"job_info":{"job_title":{"include":[{"value":"<id>","label":"VP Sales"}]}},"company_employee_count":["3"]}. Lookup ids come from resolve_prospect_filter in the corpus the model searches (the whole database unless it uses sic_codes or an advanced axis). When given it replaces filters, freshOnly, enrichedOnly, liOnly and contactInfo, and the corpus follows from it. Every tool that takes it must be passed the same string.
filtersobjectoptional- Filter groups, each an object of field -> array of numeric ids from resolve_prospect_filter. job_info: job_title, seniority_level, department. company_info: company_industry, sic_codes, company_employee_count, company_revenue, company_name. company_location: company_country, company_state, company_city. location: country, state, city, personal_zip. advanced: social_connections, homeowner, net_worth, income_range, children, married, age_range. company_employee_count, company_revenue and the advanced fields are fixed bands, not lookups: resolve_prospect_filter answers them from their options (a range such as 18-25 returns every band it overlaps) and list_prospect_filters lists them. sic_codes, personal_zip and the advanced fields exist only with freshOnly: true and are refused otherwise, so a query using one resolves every other filter with freshOnly: true as well. In that corpus a person's city is rarely filled in: narrow a metro there with personal_zip, whose ids are the 5-digit ZIPs themselves (pass the metro's ZIPs together), or with state. Without a fresh-only axis, prefer freshOnly: false for a city, which resolves cities well. Job titles are exact labels: resolve the job and pass every returned label that is the same job (Life Insurance Agent, Licensed Life Insurance Agent, Independent Life Insurance Agent) as one ORed list. company_industry is a coarse list of about 150 labels per corpus; trades and local services (plumbing, roofing, HVAC, electrical, landscaping) are not on it. For those use sic_codes with freshOnly: true: the id is the 4-digit code itself (1711 plumbing, heating and air-conditioning contractors; 1761 roofing, siding and sheet metal; 1731 electrical work), the lookup's list is partial and reports no counts, so pass a code you know and size it with count_prospects. E.g. {job_info:{seniority_level:[3]}, location:{state:[44]}}. Narrow step by step: add one axis, count, then add the next. Flat keys are accepted too.
freshOnlybooleanoptional- Defaults true. Selects which corpus — and therefore which id vocabulary — applies: every lookup, count, search and import for one market uses the same value. freshOnly: true is required by sic_codes, personal_zip and the advanced bands (age, income, homeowner…); there, narrow a place by state or personal_zip, because few people in that corpus have a city. freshOnly: false is the whole database and resolves cities well. When switching, re-resolve every filter in the other corpus. The fresh corpus holds United States people only; a workspace that sells elsewhere searches with freshOnly: false.
enrichedOnlybooleanoptional- Defaults false. Only people the corpus already holds contact details for. Cheaper to reveal, smaller pool.
liOnlybooleanoptional- Defaults false. Only people with a LinkedIn profile URL, which every LinkedIn step needs.
contactInfostring[]optional- Require that a profile already holds these details, e.g. ["phone"] for an SMS audience. Narrows to people a reveal can answer for.
emailwork_emailphone
import_prospectsImport prospects into Contacts
Pulls people into this workspace's Contacts, enriched — always. Every candidate is revealed first (email and phone bought from the corpus, metered as enrich.reveal) and only the people a vendor answered with an address become contacts. Two ways to say who: pass the same `filters` you searched with plus a `limit` (up to 3000), which pulls everyone matching rather than only the page you looked at — prefer this when the person asked for a list or a market, and pass the whole count when they asked for all of it — or pass `ids` from search_prospects. Pass `listName` to land the pull on a new named list (created if new; name it after the ICP), or `listId` for an existing static list. Priced at 8 data credits per person asked for (quote_prospect_export gives the figure); a pull the balance cannot cover is refused before anything is bought. On the Agent screen the pull is not run by this call: it is sized, quoted and shown to the person as a card to approve, and once approved it runs to the end on its own, however large, and lands on the list. The answer then has status "awaiting_approval": tell the person what the card will pull and cost, and do not call import_prospects again for the same people. Skips anyone already present (they still join the list), anyone suppressed, and anyone with no LinkedIn profile to dedupe on. IMPORTANT: filters and freshOnly (or search, or savedSearchId) must be the ones you searched with; a call with no filters at all is refused. If the answer's code is quota_exhausted because the platform's data supply is used up, the filters are not the cause: do not change them or retry, tell the person plainly.
- Scope
write- Needs
- Read and write on Contacts
Arguments
idsstring[]optional- Prospect ids from search_prospects. Omit to import by filter instead.
limitnumberoptional- With filters and no ids: how many matching people to pull, newest page first. Up to 3000. Pass the count when the person asked for everyone.
listNamestringoptional- A static list the pull lands on, created if it does not exist. Name it after the ICP, e.g. 'Life insurance agents — Florida'.
listIdstring | nulloptional- An existing static list to land the pull on, from list_lists. Takes precedence over listName. Use null when absent; never invent an id.
savedSearchIdstringoptional- A saved search's id from list_saved_searches. Runs that search's own filters and corpus, exactly as the Search screen does. Use it instead of search when the operator names a saved search; never pass a saved search's name as search.
searchstringoptional- The Search screen's own filter model, as the compact JSON string list_saved_searches returns and save_search takes: {"job_info":{"job_title":{"include":[{"value":"<id>","label":"VP Sales"}]}},"company_employee_count":["3"]}. Lookup ids come from resolve_prospect_filter in the corpus the model searches (the whole database unless it uses sic_codes or an advanced axis). When given it replaces filters, freshOnly, enrichedOnly, liOnly and contactInfo, and the corpus follows from it. Every tool that takes it must be passed the same string.
filtersobjectoptional- Filter groups, each an object of field -> array of numeric ids from resolve_prospect_filter. job_info: job_title, seniority_level, department. company_info: company_industry, sic_codes, company_employee_count, company_revenue, company_name. company_location: company_country, company_state, company_city. location: country, state, city, personal_zip. advanced: social_connections, homeowner, net_worth, income_range, children, married, age_range. company_employee_count, company_revenue and the advanced fields are fixed bands, not lookups: resolve_prospect_filter answers them from their options (a range such as 18-25 returns every band it overlaps) and list_prospect_filters lists them. sic_codes, personal_zip and the advanced fields exist only with freshOnly: true and are refused otherwise, so a query using one resolves every other filter with freshOnly: true as well. In that corpus a person's city is rarely filled in: narrow a metro there with personal_zip, whose ids are the 5-digit ZIPs themselves (pass the metro's ZIPs together), or with state. Without a fresh-only axis, prefer freshOnly: false for a city, which resolves cities well. Job titles are exact labels: resolve the job and pass every returned label that is the same job (Life Insurance Agent, Licensed Life Insurance Agent, Independent Life Insurance Agent) as one ORed list. company_industry is a coarse list of about 150 labels per corpus; trades and local services (plumbing, roofing, HVAC, electrical, landscaping) are not on it. For those use sic_codes with freshOnly: true: the id is the 4-digit code itself (1711 plumbing, heating and air-conditioning contractors; 1761 roofing, siding and sheet metal; 1731 electrical work), the lookup's list is partial and reports no counts, so pass a code you know and size it with count_prospects. E.g. {job_info:{seniority_level:[3]}, location:{state:[44]}}. Narrow step by step: add one axis, count, then add the next. Flat keys are accepted too.
freshOnlybooleanoptional- Defaults true. Selects which corpus — and therefore which id vocabulary — applies: every lookup, count, search and import for one market uses the same value. freshOnly: true is required by sic_codes, personal_zip and the advanced bands (age, income, homeowner…); there, narrow a place by state or personal_zip, because few people in that corpus have a city. freshOnly: false is the whole database and resolves cities well. When switching, re-resolve every filter in the other corpus. The fresh corpus holds United States people only; a workspace that sells elsewhere searches with freshOnly: false.
enrichedOnlybooleanoptional- Defaults false. Only people the corpus already holds contact details for. Cheaper to reveal, smaller pool.
liOnlybooleanoptional- Defaults false. Only people with a LinkedIn profile URL, which every LinkedIn step needs.
contactInfostring[]optional- Require that a profile already holds these details, e.g. ["phone"] for an SMS audience. Narrows to people a reveal can answer for.
emailwork_emailphone
quote_prospect_exportQuote a prospect import
What importing a number of prospects could cost in data credits, before anything is revealed: one enrich.reveal per person, against the organization's data balance, exactly as the Search screen's export dialog quotes it. People already in the workspace and people no vendor holds an address for come back cheaper, so this is the most it can cost. import_prospects refuses a pull this says is unaffordable. Free and read-only.
- Scope
read- Needs
- View on Contacts
Arguments
countintegerrequired- How many people the import would ask for, up to 3000.
remap_prospect_filtersMove prospect filters to the other corpus
Renumbers lookup filter values for the other corpus. The whole database (full) and the recently verified slice (fresh) number every value independently, so a filter built in one matches nobody, or the wrong people, in the other. Pass search (the Search screen's filter model) to get it back renumbered for the corpus you name, with the values that corpus does not hold dropped and named; or pass selections to renumber individual values. Matching is by exact label, never a near match. Free.
- Scope
read- Needs
- View on Contacts
Arguments
corpusstringrequired- The corpus to renumber into: full is the whole database, fresh the verified slice.
fullfresh searchstring | nulloptional- The Search screen's filter model as its compact JSON string, to renumber whole.
selectionsobject[] | nulloptional- Individual values to renumber, when not passing search.
Campaigns
list_campaignsList campaigns
Every campaign in the workspace, newest first: status, goal, template, audiences, daily target and entry rule. Reads only. A campaign is the only way outreach happens, and its status is the switch.
- Scope
read- Needs
- View on Demand
- REST
- GET/campaigns
Arguments
statusstringoptional- Only campaigns in this state.
draftactivepausedcompleted
get_campaignGet a campaign
One campaign by id or exact name, with its senders and how many queued steps sit in each state. pending steps are waiting for their scheduled time; every campaign sends on its own.
- Scope
read- Needs
- View on Demand
Arguments
campaignstringrequired- The campaign's id or exact name.
create_campaignCreate a campaign
Create a draft campaign with a name and a goal. It runs nothing until audiences, templates and senders are attached (campaign.configure) and it is activated (campaign.set_status).
- Scope
write- Needs
- Read and write on Demand
- REST
- POST/campaigns
Arguments
namestringrequired- The name to give it. Names are how campaigns, templates and lists are referred to, so make it specific.
goalstringoptional- What the campaign or template is for. Decides the default step chain and how the copy agent writes.
start_conversationbook_meetingbook_demoevent_signupnurturereengage endDatestringoptional- The last day the campaign runs, YYYY-MM-DD. Omit for no end date.
configure_campaignConfigure a campaign
Change a campaign: its name, goal, priority and end date; audiences, templates (with split weights) and senders (with share-of-day weights); ongoing sourcing, daily target, and email pacing and limits. Only given fields change; a given list replaces that list. Every campaign sends on its own: from day one it emails its whole audience and sends a LinkedIn connection request to every contact with a profile.
- Scope
write- Needs
- Read and write on Demand
Arguments
campaignstringrequired- The campaign, by id or exact name (case-insensitive).
audiencesstring[]optional- Names of the lists the campaign targets. Replaces the current set.
templatesobject[]optional- The templates the campaign runs, by name. More than one is an A/B split by weight. Replaces the current set.
namestringrequired- The name to give it. Names are how campaigns, templates and lists are referred to, so make it specific.
weightintegeroptional- This template's share of the split, 1 to 100. Defaults to an even split.
sendersstring | object[]optional- The sending accounts the campaign may use: each a handle, or { handle, weight } to set its share of the day. Replaces the current set. See list_senders.
namestringoptional- A new name for the campaign. Unique within the workspace.
goalstringoptional- What the campaign is for. Steers how the copy agent writes its messages.
start_conversationbook_meetingbook_demoevent_signupnurturereengage priorityintegeroptional- Which campaign gets the day when several want the same senders: 0 normal, 1 elevated, 2 high, 3 urgent.
endDatestring | nulloptional- The last day the campaign enters people, YYYY-MM-DD. Null removes the end date.
minIntent1optional- The minimum intent heat a contact needs to enter. Campaigns email their whole audience, so the only accepted value is 1.
waitForIntentfalseoptional- Whether entry waits for recorded intent. Neither email nor LinkedIn waits: every contact is emailed, and every contact with a profile gets a connection request, from day one. The only accepted value is false.
dailyTargetinteger | nulloptional- How many new contacts to enter per day, 1 to 1000. Null means as many as the senders' allowances permit.
emailMinGapMinutesintegeroptional- The shortest gap between two of this campaign's emails from one sender, in minutes.
emailRandomGapMinutesintegeroptional- Up to this many extra minutes, chosen at random, added to each email gap.
emailAutoReplyModestringoptional- What an automatic email reply does: stop ends the sequence, smart_pause holds it until the person is back.
stopsmart_pause emailPrioritizeNewLeadsbooleanoptional- Send first touches to new contacts ahead of follow-ups that are due.
autoSourcebooleanoptional- Include the workspace's ongoing ICP sourcing pool. False limits entry to attached audiences.
emailDailySendLimitinteger | nulloptional- Maximum campaign emails per day. Zero holds email; null removes the campaign-specific limit.
emailDailyNewLeadLimitinteger | nulloptional- Maximum new email recipients per day. Zero holds new recipients; null removes this campaign limit.
set_campaign_statusActivate, pause or resume a campaign
Move a campaign between draft, active, paused and completed. Activation and resume check the same readiness list the campaign page shows, and refuse naming each gap: an audience attached, a template (one with no steps passes until it has run), a sender that can send (the campaign's own, or the workspace's connected sender for a channel it names none for), and enough action credits to write a step. With no sender attached it attaches every connected email and LinkedIn sender in the workspace and names them in the answer, or refuses when none is connected. Does not send: the launcher and the gate stay the only path to a person.
- Scope
write- Needs
- Read and write on Demand
Arguments
campaignstringrequired- The campaign, by id or exact name (case-insensitive).
statusstringrequired- The state to move it to.
draftactivepausedcompleted
set_campaign_eventSet a campaign's LinkedIn event
Point a campaign at the LinkedIn event it exists to fill, or clear it with null. The id is the number at the end of the event URL — digits only, because it is interpolated into a URN and the vendor answers 200 to a malformed one. It is the campaign-wide default for linkedin.event_invite ("Send Invite to Event"); a step carrying its own eventId setting keeps using that. Sends nothing: an invitation goes out when the launcher reaches that step.
- Scope
write- Needs
- Read and write on Demand
Arguments
campaignstringrequired- The campaign, by id or exact name (case-insensitive).
eventIdstring | nullrequired- The LinkedIn event's numeric id, the digits at the end of the event URL. Null clears it.
delete_campaignDelete a campaign
Delete a campaign by id or exact name. Its unsent steps (pending or approved) are cancelled first and an active campaign is paused before it goes, so nothing it had queued goes out afterwards; messages already sent stay in the history. Cannot be undone. To stop a campaign and keep it, set its status to paused instead.
- Scope
write- Needs
- Read and write on Demand
Arguments
campaignstringrequired- The campaign to delete, by id or exact name (case-insensitive).
queue_linkedin_connectionsQueue LinkedIn connection requests
Start the campaign's LinkedIn tract for chosen contacts: queues the sequence's first LinkedIn step, normally the connection request, which carries no note. Selects up to limit contacts with intent heat at least minHeat (4+ is high intent) and a LinkedIn profile, hottest first unless sort is newest; pass contactIds only when the operator named specific people. Each contact must be eligible: not suppressed, declined or replied, not already on LinkedIn in this campaign, and not mid-sequence in another campaign. Intent evidence is not required. Nothing is sent here; the launcher sends within the connected LinkedIn account's ramp, the send window and past the blocklist. The campaign may be omitted when exactly one active campaign can run LinkedIn; otherwise the error names the candidates and you choose, without asking the operator. Returns a summary, what was queued, who was skipped and why, and the account's remaining invitations today. Never ask the operator about personalised notes: connection requests never carry one.
- Scope
write- Needs
- Read and write on Demand
Arguments
campaignstringoptional- Campaign name or UUID whose LinkedIn tract to start. Optional when exactly one active campaign can run LinkedIn; otherwise the error names the candidates.
contactIdsstring[]optional- Specific contacts instead of a heat selection, when the operator named people. Eligibility still applies; limit is ignored.
minHeatintegeroptionaldefault: 4- Minimum intent heat. 4 or more is high intent.
limitintegeroptionaldefault: 25- How many contacts to queue. Default 25.
sortstringoptionaldefault: heat- heat: hottest first. newest: most recently added first.
heatnewest
campaign_launch_diagnosticsInspect campaign sending blockers
Read the campaign's actual status and queued/failed outreach steps with their recorded errors. Use when a campaign is active but messages are not leaving, or the operator asks why calls are not being booked. A queued step is not a send. Use the existing campaign/sender/agent tools to fix the specific cause and preserve its audience.
- Scope
read- Needs
- View on Demand
Arguments
campaignIdstringrequired- The campaign's id, from list_campaigns.
campaign_run_progressRead campaign build progress
Read saved campaign build stages, actual sourced counts, campaign and conversation links, and blockers. Check this before retrying or creating a replacement campaign.
- Scope
read- Needs
- View on Demand
Arguments
runIdstringoptional- One build's id. Omit for the 20 most recent builds in this workspace.
start_campaign_runBuild and launch a campaign
Continue with runId, or start saved campaign work for this conversation. Follow-up turns reuse the same primary work identity even if the name changes. For an intentionally separate campaign, supply a distinct stable separateKey, and reuse that key on retries. Names never establish identity. sourcing "pool" launches a campaign on the workspace's ongoing lead pool, which daily sourcing keeps filling from the default ICP: it needs only a name and a brief, uses no signal, and a workspace has one pool build in flight at a time (asking again returns it). sourcing "tam", the default, pages the full TAM of a chosen ICP: first save the ICP and configure its intent signal, then call this once with both ids (omitted, they default to the workspace default ICP and its newest active signal); it sources and enriches into one campaign audience in saved batches. Either way it creates an outbound and nurture sequence with email and LinkedIn steps, starts intent monitoring and activates through the normal send gates, and every connected sender serves the campaign. Work continues after the chat closes. Do not also import prospects or create a second campaign for this run. Read campaign_run_progress for results; queued is not launched or booked. Outside the Agent screen a build is identified by separateKey, or by its name when there is none.
- Scope
write- Needs
- Read and write on Demand
Arguments
runIdstringoptional- Continue this saved build instead of starting one. Omit to start.
separateKeystringoptional- A stable key for an intentionally separate build. Reuse it on retries; a new key starts new work.
namestringoptional- The campaign's name. Required when starting.
briefstringoptional- What the campaign is for, in the operator's words. Required when starting.
sourcingstringoptional- pool launches on the workspace's ongoing lead pool, filled daily from its default ICP, and needs only name and brief. tam, the default, pages the full TAM of icpId and needs signalId.
tampool icpIdstringoptional- The saved ICP to source from, from list_icps. Omitted, a TAM build uses the workspace's default ICP (or its only one); a pool build always uses the default.
signalIdstringoptional- The active intent signal linked to that ICP, from list_signals. Omitted, a TAM build uses that ICP's newest active signal; a pool build uses none.
waitForIntentfalseoptional- Always false: every campaign emails its audience from day one.
targetintegeroptional- People to import in a TAM build's first batch, 1 to 10,000. Defaults to 1,000. A pool build has no batch.
resume_campaign_runResume a campaign build
Resume a blocked saved campaign after fixing its reported blocker, or run a parked one's retry now instead of at its retry time. Keeps the same assets and cursor. If zero leads were found and you edited its saved ICP, set refreshTargeting true to reload that ICP and restart sourcing in the same campaign. Existing sourced audiences cannot be silently retargeted.
- Scope
write- Needs
- Read and write on Demand
Arguments
runIdstringrequired- The build's id, from campaign_run_progress.
refreshTargetingbooleanoptional- Reload the build's saved ICP and restart sourcing. Only for a build that found nobody.
Templates
generate_templateGenerate a template with AI
Write a sequence template from a brief: one metered model call authors the step chain (channels, waits, tracts, per-step guidance), validated before it is saved. The per-recipient copy is still written at send time by the normal drafting path.
- Scope
write- Needs
- Read and write on Demand
Arguments
namestringrequired- The name to give it. Names are how campaigns, templates and lists are referred to, so make it specific.
briefstringrequired- What the sequence should say and to whom, 10 to 2000 characters. The copy agent authors every step from this.
attemptstringoptional- An idempotency key for this generation, up to 64 characters. Send the same value when retrying after a lost answer, and the retry is refused rather than billed a second time. Omit it and every call is a separate charge.
goalstringoptional- What the campaign or template is for. Decides the default step chain and how the copy agent writes.
start_conversationbook_meetingbook_demoevent_signupnurturereengage
delete_templateDelete a template
Delete a template and its steps, by name. Refused while any campaign still runs it, with the campaigns named. Contacts already mid-sequence keep their history.
- Scope
write- Needs
- Read and write on Demand
Arguments
templatestringrequired- The template, by id or exact name (case-insensitive).
add_template_stepAdd a step to a template
Append a step to the end of one of a template's tracts. Read the sequence first (template.steps) — this adds to the end rather than inserting, so the order it produces is the order it is given. Authoring only: the launcher is still the only path to a person, and it performs the step on its next tick like any other.
- Scope
write- Needs
- Read and write on Demand
Arguments
templatestringrequired- The template, by id or exact name (case-insensitive).
actionstringrequired- What the step does, given as the action id or as the label the builder shows. linkedin.connection_request = "Send Connection Request" (message; no settings) | linkedin.message = "Send Message" (message; settings: writing) | linkedin.perform_action = "Perform Action" (interaction; settings: verb) | linkedin.inmail = "Send InMail" (message; settings: writing, subject) | linkedin.comment = "Post AI Comment" (message; no settings) | linkedin.event_invite = "Send Invite to Event" (interaction; settings: eventId) | email.send = "Send Email" (message; settings: writing, subject) | sms.send = "Send SMS" (message; settings: writing) | data.enrich_profile = "Enrich Profile" (internal; no settings) | crm.push = "Push to CRM" (internal; no settings) | webhook.send = "Send Webhook" (internal; settings: note) | label.add = "Add Label" (internal; settings: label) | label.remove = "Remove Label" (internal; settings: label)
tractstringoptional- Which parallel tract the step is in, by the name the builder shows. Omit when the template has one tract; required when it has more.
labelstringoptional- The step's display name. Defaults to the action's own name.
waitAmountintegeroptional- How long to wait before this step, measured from the previous step landing. 0 to 365.
waitUnitstringoptional- The unit waitAmount is in.
hoursdaysbusiness_days branchConditionstring | nulloptional- The event this step waits behind. Cold email starts unconditionally; the first LinkedIn step waits for engaged, and a later LinkedIn message waits for request_accepted. Null is unconditional.
engagedrequest_accepted bodystring | nulloptional- The step's body. By default it is writing guidance used to personalize each recipient's message at draft time, not literal delivery copy; report it as saved guidance. With settings.writing "template" it is the message itself, sent as written: {{first_name}}-style variables are filled from each lead and only the {{ai.*}} parts are written per lead; report it as a saved template. For exact copy on one message, edit that draft through the inbox tool.
settingsobjectoptional- Per-action settings, validated against the chosen action's own schema, laid over the step's own: give only what changes. Changing the action resets them, except that a template carries over to another message step. Email, LinkedIn message, InMail and SMS steps take writing ("guidance" or "template"). An email template's subject line is settings.subject and may use variables and {{ai.subject}}; an email guidance step's subject is written with its body. InMail's own subject setting is separate from templates.
edit_template_stepChange a step in a template
Replace what one step of a template does: its action, label, wait, condition, body or settings. Identify it by its position within its tract, as template.steps reports it. Only the fields given change, and settings given are laid over the step's own. Changing the action resets the settings, because an event id means nothing to a label step, except that a template carries over to another message step.
- Scope
write- Needs
- Read and write on Demand
Arguments
templatestringrequired- The template, by id or exact name (case-insensitive).
positionintegerrequired- The step's position within its tract, counting from 1.
tractstringoptional- Which parallel tract the step is in, by the name the builder shows. Omit when the template has one tract; required when it has more.
actionstringoptional- What the step does, given as the action id or as the label the builder shows. linkedin.connection_request = "Send Connection Request" (message; no settings) | linkedin.message = "Send Message" (message; settings: writing) | linkedin.perform_action = "Perform Action" (interaction; settings: verb) | linkedin.inmail = "Send InMail" (message; settings: writing, subject) | linkedin.comment = "Post AI Comment" (message; no settings) | linkedin.event_invite = "Send Invite to Event" (interaction; settings: eventId) | email.send = "Send Email" (message; settings: writing, subject) | sms.send = "Send SMS" (message; settings: writing) | data.enrich_profile = "Enrich Profile" (internal; no settings) | crm.push = "Push to CRM" (internal; no settings) | webhook.send = "Send Webhook" (internal; settings: note) | label.add = "Add Label" (internal; settings: label) | label.remove = "Remove Label" (internal; settings: label)
labelstringoptional- The step's display name. Defaults to the action's own name.
waitAmountintegeroptional- How long to wait before this step, measured from the previous step landing. 0 to 365.
waitUnitstringoptional- The unit waitAmount is in.
hoursdaysbusiness_days branchConditionstring | nulloptional- The event this step waits behind. Cold email starts unconditionally; the first LinkedIn step waits for engaged, and a later LinkedIn message waits for request_accepted. Null is unconditional.
engagedrequest_accepted bodystring | nulloptional- The step's body. By default it is writing guidance used to personalize each recipient's message at draft time, not literal delivery copy; report it as saved guidance. With settings.writing "template" it is the message itself, sent as written: {{first_name}}-style variables are filled from each lead and only the {{ai.*}} parts are written per lead; report it as a saved template. For exact copy on one message, edit that draft through the inbox tool.
settingsobjectoptional- Per-action settings, validated against the chosen action's own schema, laid over the step's own: give only what changes. Changing the action resets them, except that a template carries over to another message step. Email, LinkedIn message, InMail and SMS steps take writing ("guidance" or "template"). An email template's subject line is settings.subject and may use variables and {{ai.subject}}; an email guidance step's subject is written with its body. InMail's own subject setting is separate from templates.
remove_template_stepRemove a step from a template
Delete one step of a template, by its position within its tract. The step's guidance and settings go with it. Contacts already scheduled on that step still perform it — a queue row carries its own action — but nothing new is scheduled onto it. Refused when it is the template's last step, because a template with no steps reads as one that predates the builder and is re-seeded with the default chain.
- Scope
write- Needs
- Read and write on Demand
Arguments
templatestringrequired- The template, by id or exact name (case-insensitive).
positionintegerrequired- The step's position within its tract, counting from 1.
tractstringoptional- Which parallel tract the step is in, by the name the builder shows. Omit when the template has one tract; required when it has more.
list_templatesList sequence templates
The workspace's sequence templates, newest first. A template is the chain of steps a campaign runs; read its steps with list_template_steps.
- Scope
read- Needs
- View on Demand
- REST
- GET/templates
Arguments
limitintegeroptionaldefault: 25- Rows per page, 1 to 100.
cursorstringoptional- Opaque cursor from the previous page's next_cursor. Omit for the first page. Keep every other argument the same while paging.
list_template_stepsRead a template's steps
The steps of one template by id or exact name, in order within each tract: action, channel, the wait before it, the condition it sits behind, and its copy. An empty list means the template has never been authored and runs the default chain for its goal.
- Scope
read- Needs
- View on Demand
Arguments
templatestringrequired- The template's id or exact name.
list_template_libraryList the template library
The ready-made sequences a new template can start from: each entry's key, what the motion is for, its goal and channel, and its steps. Reads only. Pass a key to create_template to start a template from it; that costs nothing, unlike generate_template.
- Scope
read- Needs
- View on Demand
Arguments
goalstringoptional- Only entries built for this goal. Omit for the whole library.
start_conversationbook_meetingbook_demoevent_signupnurturereengage
create_templateCreate a template
Create a sequence template, blank or started from a library entry (see list_template_library). No model call and no credits. A blank template runs the default chain for its goal until steps are added with add_template_step or replace_template_steps. To have the copy agent write the chain from a brief instead, use generate_template.
- Scope
write- Needs
- Read and write on Demand
- REST
- POST/templates
Arguments
namestringrequired- The template's name. Unique within the workspace.
goalstringoptional- What the sequence is for. Defaults to start_conversation, as on the screen.
start_conversationbook_meetingbook_demoevent_signupnurturereengage channelstring | nulloptional- A label for the template's main channel. Omit or null for any channel; a library entry supplies its own. The steps decide what actually runs.
emaillinkedinsms librarystringoptional- A library entry's key to copy the steps from. Omit for a blank template.
replace_template_stepsReplace a template's steps
Save a template's whole sequence at once, as the builder does: reorder steps, insert one in the middle, move one between tracts, or rewrite the chain. Read it first with list_template_steps, change the list, and send every step back; steps left out are removed. The chain is validated as on the screen and refused with the reason when it would not run. Contacts already scheduled keep the action their step was queued with. Authoring only: the launcher is the only path to a person.
- Scope
write- Needs
- Read and write on Demand
Arguments
templatestringrequired- The template, by id or exact name (case-insensitive).
stepsobject[]required- Every step the template should have afterwards, 1 to 60.
positionintegerrequired- The step's position within its tract, counting from 1. Two steps in one tract cannot share a position.
tractstring | nulloptional- The parallel tract the step runs in, e.g. campaign-email. Steps sharing a tract run in order; different tracts run side by side. Omit or null for the template's single unnamed tract.
actionstringoptional- What the step does: an action id such as email.send, or the label the builder shows. add_template_step's description lists every action and its settings. Omitted, a step with a channel is that channel's message: email.send, linkedin.message or sms.send.
channelstringoptional- The step's channel. Derived from the action when there is one; read only to pick the message action for a step sent without one.
labelstringoptional- The step's display name. Defaults to the action's own name.
waitAmountintegerrequired- How long to wait before this step, from the previous step landing. 0 to 365.
waitUnitstringrequired- The unit waitAmount is in.
hoursdaysbusiness_days branchConditionstring | nulloptional- The event this step waits behind, or null for none. engaged may gate only the first LinkedIn step of a tract; request_accepted may gate one later step of a tract.
bodystring | nulloptional- A message step's body: writing guidance by default, or the message itself when settings.writing is "template" (variables filled per lead, only {{ai.*}} parts written): send a template back exactly as list_template_steps gave it. May cite blocks as [[Block name]]; each cited block must exist (see list_blocks).
settingsobjectoptional- Per-action settings, validated against the action's own schema: for a message step, writing and, on an email template, subject. Left out, a step keeps the settings stored for the step at the same position and tract with the same action.
blocksstring[]optional- Ignored: cited blocks are read from the body. Accepted so a step read back can be sent as it came.
list_blocksList template blocks
The workspace's reusable copy blocks, newest first: name, mode (ai or static), its prompt or text, and the source fields it may use. A step's guidance cites a block as [[name]]. Reads only.
- Scope
read- Needs
- View on Demand
- REST
- GET/blocks
Arguments
limitintegeroptionaldefault: 25- Rows per page, 1 to 100.
cursorstringoptional- Opaque cursor from the previous page's next_cursor. Omit for the first page. Keep every other argument the same while paging.
create_blockCreate a template block
Create a reusable copy block that sequence steps can cite as [[name]] in their guidance: an ai block the drafter writes per recipient from a prompt, or a static block with fixed text. Nothing is sent; the drafter reads it when it writes a step.
- Scope
write- Needs
- Read and write on Demand
- REST
- POST/blocks
Arguments
namestringrequired- The block's name. Steps cite it as [[name]], so keep it readable.
modestringrequired- ai: the drafter writes this part per recipient from the prompt. static: the same text for everyone.
aistatic promptstringoptional- For an ai block, what to write. May reference the listed source fields.
bodystringoptional- For a static block, the exact words.
sourceRefsstring[]optional- The typed fields an ai block's prompt may draw on. The drafter refuses any other.
Account: NameAccount: DomainAccount: NotesRecipient: First NameRecipient: TitleRecipient: Notes
update_blockChange a template block
Change a block's name, mode, prompt, text or source fields. Only the fields given change. A rename is refused while any step still cites the old name, because citations are by name and would be orphaned.
- Scope
write- Needs
- Read and write on Demand
Arguments
blockstringrequired- The block, by id or exact name (case-insensitive).
namestringoptional- The block's name. Steps cite it as [[name]], so keep it readable.
modestringoptional- ai: the drafter writes this part per recipient from the prompt. static: the same text for everyone.
aistatic promptstringoptional- For an ai block, what to write. May reference the listed source fields.
bodystringoptional- For a static block, the exact words.
sourceRefsstring[]optional- The typed fields an ai block's prompt may draw on. The drafter refuses any other.
Account: NameAccount: DomainAccount: NotesRecipient: First NameRecipient: TitleRecipient: Notes
delete_blockDelete a template block
Delete a block by id or exact name. Refused while any step still cites it, with the count, so a live sequence is never left citing nothing.
- Scope
write- Needs
- Read and write on Demand
Arguments
blockstringrequired- The block, by id or exact name (case-insensitive).
Campaign queue
list_queued_stepsList queued outreach steps
Sequence steps in the outreach queue, newest first, with the contact and the drafted copy. Every campaign sends on its own, so pending steps run on schedule; approve_queued_steps sends chosen ones next and reject_queued_steps cancels them. Filter by campaign and status.
- Scope
read- Needs
- View on Demand
- REST
- GET/queue
Arguments
campaignstringoptional- A campaign id or exact name.
statusstringoptionaldefault: pending- Only steps in this state.
pendingapprovedrejectedlaunchedskippedfailed limitintegeroptionaldefault: 25- Rows per page, 1 to 100.
cursorstringoptional- Opaque cursor from the previous page's next_cursor. Omit for the first page. Keep every other argument the same while paging.
approve_queued_stepsSend queued steps next
Sends pending steps of one campaign next: they go to the launcher on its next tick instead of at their scheduled time. The launcher still runs each step inside the send window, under the sender's daily limit, and re-checks suppression first. Steps that are no longer pending are skipped and reported. Needs inbox access as well as demand.
- Scope
write- Needs
- Read and write on Demand
Arguments
campaignstringrequired- The campaign's id or exact name.
queueIdsstring[]required- Queued step ids from list_queued_steps, up to 200.
reject_queued_stepsCancel queued steps
Cancels pending steps of one campaign so they never send, with an optional reason recorded on each. Steps that are no longer pending are skipped and reported.
- Scope
write- Needs
- Read and write on Demand
Arguments
campaignstringrequired- The campaign's id or exact name.
queueIdsstring[]required- Queued step ids from list_queued_steps, up to 200.
reasonstringoptional- Why, recorded on each step.
Conversations
list_conversationsList conversations
Threads in the inbox, most recently active first. Use status to find what needs an answer.
- Scope
read- Needs
- View on Inbox
Arguments
statusstringoptional- Only threads in this state. replied is the one waiting on you.
openawaiting_replyrepliedmeeting_bookedclosedopted_outlost channelstringoptional- Only threads on this channel.
emaillinkedinsms contactIdstringoptional- Only this contact's threads.
limitintegeroptionaldefault: 25- Rows per page, 1 to 100.
cursorstringoptional- Opaque cursor from the previous page's next_cursor. Omit for the first page. Keep every other argument the same while paging.
read_conversationRead a conversation
Every message on one thread, oldest first.
- Scope
read- Needs
- View on Inbox
Arguments
conversationIdstringrequired- The conversation's id. A message's, queued step's or contact's id is read as its conversation.
announce_meetingAnnounce a booked meeting
Pushes a booked meeting to every CRM and alert destination this workspace has attached. Use when a meeting was booked somewhere the product did not see it.
- Scope
write- Needs
- Read and write on Inbox
Arguments
contactIdstringrequired- The contact the meeting is with.
detailstringoptional- When, and anything the CRM note should carry.
draft_replyWrite a reply on a thread
Writes your words into an existing conversation as an outbound message. By default it is saved as a draft for a person to review in the inbox. With send: true it is released for sending instead, as the inbox's Send button does: queued as your request (or handed to its campaign step), and the launcher sends it on its next tick after the suppression check and the send gate; a refused message comes back as blocked with the reason. This cannot start a conversation: only a campaign step or the contact writing in opens a thread.
- Scope
write- Needs
- Read and write on Inbox
Arguments
conversationIdstringrequired- The thread to reply on.
bodystringrequired- The message text.
subjectstringoptional- Email only. Defaults to the thread's subject.
sendbooleanoptionaldefault: false- Release it for sending instead of saving a draft.
generate_reply_draftHave the copy agent draft a reply
Asks the copy agent to write the next message on an existing conversation, from the thread and what is known about the contact, and saves it as a draft for review. Spends credits for one AI message. Never queues: read the draft, then send it with release_draft or update_draft. Refused when the thread already holds an unsent message.
- Scope
write- Needs
- Read and write on Inbox
Arguments
conversationIdstringrequired- The thread to draft on.
instructionstringoptional- What the reply should do, e.g. 'offer Tuesday or Thursday'.
update_draftEdit or send a draft
Edits an unsent outbound message. Without send it is kept as a draft, and any earlier schedule, send request or refusal on it is cleared, as the inbox's Save does. With send: true it is released for sending, as the inbox's Send does: queued as your request (or handed to its campaign step) for the launcher's next tick. Works on messages that are drafted, awaiting_approval or blocked. A message already queued or sent is refused; use release_draft or discard_draft for a queued one.
- Scope
write- Needs
- Read and write on Inbox
Arguments
messageIdstringrequired- The draft's id, from read_conversation.
bodystringoptional- Replacement text.
subjectstringoptional- Replacement subject. Email only.
sendbooleanoptionaldefault: false- Release it for sending after the edit.
revise_draftRevise a draft from an instruction
Rewrites an unsent draft from an instruction in plain words ('warmer opener', 'shorter', 'drop the jargon'), as the inbox's Ask for changes box does, and keeps the result as the draft. When the person says what to change, use this rather than rewriting the words yourself with update_draft: the rewrite is held to the rules every message follows (no message calls itself cold, sales or a pitch), and a request about how every message should read is saved as a workspace lesson that later drafts follow. Answers with the new words, anything it declined to do and why, and what it learned. Spends credits for one AI message. Never sends. Works on drafted, awaiting_approval and blocked messages.
- Scope
write- Needs
- Read and write on Inbox
Arguments
messageIdstringrequired- The draft's id, from read_conversation.
instructionstringrequired- What to change, in the person's own words.
schedule_draftSchedule a draft
Releases an unsent draft to leave at a chosen time, from one minute to 60 days out, as the inbox's schedule picker does, optionally with new words. It is queued as your request and the launcher sends it at that time behind the send gate; a draft owned by a campaign step is handed to that step for that time. Works on drafted, awaiting_approval and blocked messages.
- Scope
write- Needs
- Read and write on Inbox
Arguments
messageIdstringrequired- The draft's id, from read_conversation.
sendAtstringrequired- When to send, as an ISO 8601 time with an offset, from one minute to 60 days from now.
bodystringoptional- Replacement text.
subjectstringoptional- Replacement subject. Email only.
release_draftSend a message as soon as possible
Releases an unsent outbound message for the launcher's next tick, usually within a minute, as the inbox's Send now does, without changing its words. A draft is approved as your request; a message already queued (scheduled by a person, an automatic answer sitting out its delay, or one held for working hours) has its wait cleared. A message owned by a campaign step is handed to that step. Nothing is sent from here: the launcher still runs the suppression check and the send gate.
- Scope
write- Needs
- Read and write on Inbox
Arguments
messageIdstringrequired- The unsent message's id.
discard_draftDiscard an unsent message
Deletes an outbound message that has not been sent: a draft, a blocked message, or one queued and not yet picked up by the launcher. Discarding a campaign step's message stops that step for this contact. A sent message cannot be withdrawn, and neither can one the launcher is sending right now.
- Scope
write- Needs
- Read and write on Inbox
Arguments
messageIdstringrequired- The unsent message's id.
search_inboxSearch the inbox board
The inbox as its board shows it: one card per contact and channel, most recent activity first, with the pipeline stage (derived, or where a person dropped it), whether it needs a reply, holds a draft to review or failed to send, and when the next queued step can leave. view picks the board's tab: attention (needs a person), replies, drafts, failed, all, or pipeline (every card, for one channel). A contact who opted out has the status opted_out and is only in all and pipeline. query matches the contact's name, email or company and message text. 50 cards a page.
- Scope
read- Needs
- View on Inbox
- REST
- GET/inbox
Arguments
viewstringoptionaldefault: attention- Which tab of the board.
attentionrepliesdraftsfailedallpipeline querystringoptional- Text to find in the contact's name, email, company or messages.
channelstringoptional- Only this channel. The pipeline view defaults to email.
emaillinkedinsms pageintegeroptionaldefault: 0- Page number, from 0.
get_inbox_conversationOpen a contact's inbox conversation
One contact's conversation as the inbox panel shows it: every message on their email, LinkedIn and SMS threads, oldest first, sent and unsent (send_checked says the launcher recorded its send checks); the pipeline stage; open campaign steps, soonest first, and which unsent message each step owns (stepByMessage); the channels a reply can be drafted on, or why not (draftTargets); an out-of-office email pause; and optOut, set when the contact opted out, in which case nothing more is sent to them on any channel and no reply should be drafted. fit_score is intent heat, 1 to 5.
- Scope
read- Needs
- View on Inbox
Arguments
contactIdstringrequired- The contact's id, from search_inbox or list_contacts.
set_pipeline_stageMove a contact on the pipeline board
Puts a contact's card in a pipeline column, as dragging it on the inbox board does. The card stays there until a new reply resurfaces it. Moving to lost also marks the contact lost (a suppressed contact stays suppressed); moving to booked records a meeting and announces it to attached CRMs.
- Scope
write- Needs
- Read and write on Inbox
Arguments
contactIdstringrequired- The contact whose card to move.
stagestringrequired- The column: unanswered (Queued or approved, nothing sent yet); waiting_connection (LinkedIn invitation sent, not yet accepted); connected (Accepted — first message not sent yet); first_touch (One message out, no reply yet); follow_up (Later steps out, no reply yet); interested (Replied with interest); booked (A meeting is on the calendar); lost (The sequence ran out, or was marked lost).
unansweredwaiting_connectionconnectedfirst_touchfollow_upinterestedbookedlost
set_absence_returnAnswer an out-of-office pause
When a contact's auto-reply says they are away, their email steps wait. This sets the day they are back (steps resume from noon UTC the day after, within the next year) or, with resume: true, lets the steps continue now. Pass exactly one of returnDate or resume.
- Scope
write- Needs
- Read and write on Inbox
Arguments
contactIdstringrequired- The contact whose email steps are paused.
returnDatestringoptional- The day they are back, as YYYY-MM-DD.
resumebooleanoptional- True to resume the steps now instead.
sync_linkedin_inboxCheck LinkedIn for new replies now
Reads every LinkedIn account this workspace owns for replies now, instead of waiting for the webhook or the recovery poll, and files what it finds into the inbox. An account read in the last minute is skipped, because each read spends from the account's daily LinkedIn allowance. Reads only; nothing is sent.
- Scope
write- Needs
- Read and write on Inbox
Takes no arguments.
list_sent_messagesList messages that went out
Every message that left this workspace on email, LinkedIn or SMS, newest first, as the Sent log shows it: the words, when it went, who it went to and from, the campaign and step that sent it or whether a person or the automatic reply writer did (origin), and whether it bounced or was reported as spam (complained), was opened or clicked, or got a reply. feedbackCount is how many times somebody asked for changes to it. Filter by channel, campaign, contact or a text search over the contact, subject and body. Paged: pass nextCursor back as cursor for older messages. To say how a message should have read, use revise_sent_message with its id.
- Scope
read- Needs
- View on Inbox
Arguments
channelstringoptional- Only messages on this channel.
emaillinkedinsms campaignIdstringoptional- Only messages a step of this campaign sent, from list_campaigns.
contactIdstringoptional- Only messages to this contact.
querystringoptional- Case-insensitive text matched against the contact's name, email and company, the subject and the body.
limitintegeroptionaldefault: 25- Rows per page, 1 to 100.
cursorstringoptional- Opaque cursor from the previous page's next_cursor. Omit for the first page. Keep every other argument the same while paging.
revise_sent_messageAsk for changes to a message that went out
Takes the person's words about a message that already went out ('too long', 'stop opening with their job title', 'sound less formal'), as Ask for changes in the Sent log does, and teaches the workspace from them. The message that went out is not changed. Answers with a preview of how it should have read, anything the writer declined and why, and the lesson it saved or updated: every message written afterwards follows it, and campaign drafts already written are rewritten to follow it just before they send. The preview is held to the rules every message follows. Spends credits for one AI message. For a draft that has not gone out yet, use revise_draft instead. Take a lesson back with forget_copy_lesson.
- Scope
write- Needs
- Read and write on Agents
Arguments
messageIdstringrequired- The message's id, from list_sent_messages.
instructionstringrequired- How messages like it should read, in the person's own words.
Senders
list_sendersList senders
Connected email, LinkedIn and SMS sending accounts with status and today's enforced allowance: the ramped daily limit, sent today and remaining today. Read this before promising LinkedIn invitations or email volume; a warming account sends fewer than its ceiling. Never returns a credential.
- Scope
read- Needs
- View on Sender accounts
- REST
- GET/senders
Arguments
kindstringoptional- Only accounts of this kind. Omit for every kind.
emaillinkedinsms
email_deliverabilityRead email deliverability
Report every sender's trailing-week health — sent, bounced, complained, current ramp ceiling and warmup state. Reads only.
- Scope
read- Needs
- View on Sender accounts
Takes no arguments.
update_sender_settingsUpdate a sender's settings
Change one connected sender's display name, daily and weekly sending limits, warm-up ramp, or LinkedIn premium flag. Fields you leave out keep their value. The weekly limit may not be below the daily one. Raising a limit or turning the ramp off lets the account send more, sooner, which is how accounts get restricted: read list_senders first and say what changes. A sender the agency shares into a client workspace can only be changed from the agency workspace.
- Scope
write- Needs
- Read and write on Sender accounts
Arguments
senderIdstringrequired- The sender's id, from list_senders.
displayNamestring | nulloptional- The name recipients see on this sender. Null clears it. Omit to keep it.
dailyLimitintegeroptional- Most sends a day, 0 to 2000. The ramp may hold a warming account below it.
weeklyLimitintegeroptional- Most sends a week, 0 to 10000. Not below the daily limit.
rampEnabledbooleanoptional- Whether a new account works up to its limits gradually. Turn it off only for an account that is already warm.
premiumbooleanoptional- LinkedIn only: whether the account can add a note to an invitation.
set_email_spacingSet an email sender's spacing
For one email sender: the minimum wait between two sends across every campaign, and the most campaign emails it sends a day. Each campaign also keeps its own gap; the longer wait wins. Give at least one of the two.
- Scope
write- Needs
- Read and write on Sender accounts
Arguments
senderIdstringrequired- The email sender's id, from list_senders with kind email.
minutesintegeroptional- Minutes to wait between two sends from this mailbox, 0 to 1440.
campaignDailyLimitintegeroptional- Most campaign emails this mailbox sends a day.
remove_senderRemove a sender
Disconnect a sending account at the provider and delete it here. Its queued sends stop leaving through it, a mailbox bought for it is cancelled, and the connected-account add-on goes down with the count. Reconnecting takes the person through the provider's sign-in again. If the provider does not confirm the removal at once, the sender is still removed and the account is removed at the provider in the background.
- Scope
write- Needs
- Read and write on Sender accounts
Arguments
senderIdstringrequired- The sender's id, from list_senders.
list_sms_sendersList SMS numbers
The workspace's SMS numbers with their readiness (registration status, the reason, when it was last checked) and the provider accounts they run on, by a masked identifier. Says whether SMS is switched on for the platform. Never returns a credential. Connecting a provider account or adding a number happens on the Senders screen.
- Scope
read- Needs
- View on Sender accounts
- REST
- GET/sms/senders
Takes no arguments.
pause_sms_senderPause an SMS number
Stop sending from one SMS number. Inbound replies and opt-outs are still recorded. Works while SMS is switched off platform-wide.
- Scope
write- Needs
- Read and write on Sender accounts
Arguments
senderIdstringrequired- The SMS number's connection id, from list_sms_senders.
resume_sms_senderResume an SMS number
Let a paused SMS number send again. It is rechecked against the provider at once and sends only once the provider says it is ready. Queued SMS steps start leaving through it on the next tick.
- Scope
write- Needs
- Read and write on Sender accounts
Arguments
senderIdstringrequired- The SMS number's connection id, from list_sms_senders.
refresh_sms_senderRecheck an SMS number
Ask the provider again whether one SMS number is ready: the credentials still work, the account still owns the number, and replies reach the product. Does not resume a paused number.
- Scope
write- Needs
- Read and write on Sender accounts
Arguments
senderIdstringrequired- The SMS number's connection id, from list_sms_senders.
get_sender_photoGet the sender photo
The workspace's sender photo (the profile picture set on the mailboxes TryGTM bought for it), whether syncing is on, earlier photos that can be put back, and each managed mailbox's state: waiting for the mailbox, queued, updating, accepted by the provider, applied at the provider, needs attention, not syncing or not supported. Also lists email senders signed in directly, which no photo reaches. Applied at the provider does not mean a recipient sees it: that depends on the recipient's email provider.
- Scope
read- Needs
- View on Sender accounts
Takes no arguments.
set_sender_photoChoose the sender photo
Make one of this workspace's uploaded photos its sender photo, from get_sender_photo (the current photo or one in previous), and turn syncing on. Every managed mailbox in the workspace is updated in the background, and mailboxes bought later get it too. Sending is never paused for it. Uploading a new picture is done on the Senders screen.
- Scope
write- Needs
- Read and write on Settings
Arguments
photoIdstringrequired- The photo's id: photo.assetId or previous[].assetId from get_sender_photo.
set_sender_photo_syncStop or restart sender photo sync
Stop sending the workspace's sender photo to its managed mailboxes, or start again. Stopping does not remove a photo already applied; it stays on each mailbox, and taking one off is not supported. Starting again brings every mailbox up to the current photo.
- Scope
write- Needs
- Read and write on Settings
Arguments
enabledbooleanrequired- True to sync the photo to the mailboxes, false to stop.
retry_sender_photoRetry the sender photo
Send the current sender photo again now to one managed mailbox that needs attention or is waiting, or to all of them when mailboxId is left out. Mailboxes already up to date are left alone.
- Scope
write- Needs
- Read and write on Settings
Arguments
mailboxIdstring | nulloptional- A mailbox's id from get_sender_photo's mailboxes. Omit for every mailbox.
Signals and ICPs
list_icpsRead ideal customer profiles
Read the workspace's saved ICPs, identifiers and targeting criteria before creating or changing a campaign. The ids here are the ones save_icp, configure_intent_tracking and start_campaign_run accept.
- Scope
read- Needs
- View on Workspace context
- REST
- GET/icps
Takes no arguments.
save_icpSave an ideal customer profile
Create or update a campaign ICP from the company's product, buyer pains and request. Supply the id from list_icps to edit an existing ICP; without one, an ICP with the same name is updated and otherwise a new one is created. Omitted fields stay unchanged. Use real targeting phrases, never invented vendor filter IDs. Set is_default only when the person wants this to become the workspace's main ICP.
- Scope
write- Needs
- Read and write on Workspace context
- REST
- POST/icps
Arguments
idstring | nulloptional- An existing ICP's UUID from list_icps, to update it. Omit or use null to create one, or to let the tool find the existing one. Never invent or guess an ID.
namestringrequired- The ICP's name.
descriptionstringoptional- Who this is, in a sentence or two. The lead judge reads it.
job_titlesstring[]optional- Job titles to target, e.g. VP Marketing. Real phrases, up to 100. Omit to leave unchanged.
industriesstring[]optional- Industries to target. Real phrases, up to 100. Omit to leave unchanged.
company_sizesstring[]optional- Headcount bands, e.g. 51-200. Real phrases, up to 100. Omit to leave unchanged.
locationsstring[]optional- Countries, states or cities. Real phrases, up to 100. Omit to leave unchanged.
company_typesstring[]optional- Kinds of company, e.g. SaaS, agency. Real phrases, up to 100. Omit to leave unchanged.
technologiesstring[]optional- Technologies the company uses. Real phrases, up to 100. Omit to leave unchanged.
exclusionsstring[]optional- Who to leave out: titles, industries or named companies. Real phrases, up to 100. Omit to leave unchanged.
matching_modestringoptional- How strictly candidates are judged against the profile. discovery is widest.
discoverybalancedhigh_precision is_defaultbooleanoptional- true makes this the workspace's default ICP, the one sourcing and the monitoring signals read; the previous default stops being the default. Omit to leave it as it is.
senioritiesstring[]optional- Seniority levels the prospect search filters on directly. Omit to leave unchanged.
FounderOwnerC-LevelPartnerVPHeadDirectorManagerSeniorEntry
configure_intent_trackingConfigure intent tracking
Create or update the active LinkedIn keyword engagement signal linked to the campaign's ICP. Select buying-relevant topics from the company context. Monitoring observes evidence; creating a signal does not prove any lead has intent. Without an id, the tool updates the keyword signal already linked to this ICP or the workspace's unlinked one, and creates one only when neither exists.
- Scope
write- Needs
- Read and write on Signals
Arguments
idstring | nulloptional- An existing keyword signal's UUID from list_signals, to update it. Without one, the tool updates the keyword signal already linked to this ICP, then the workspace's unlinked keyword signal, and only then creates one. Omit or use null to create one, or to let the tool find the existing one. Never invent or guess an ID.
namestringrequired- The signal's name.
icpIdstringoptional- The ICP people engaging with these topics are judged against, from list_icps. Omitted, the workspace's default ICP (or its only one) is used.
keywordsstring[]required- Buying-relevant topics to watch for engagement with, 3 characters or more each.
statusstringoptionaldefault: active- active sweeps on the next tick; paused and draft do not sweep.
activepauseddraft
set_monitoring_keywordsSet the monitoring keywords
Replaces the workspace's monitoring keywords, the list on the Intent screen that the managed intent signals search LinkedIn and the open web for. Pass the whole list, not only additions: read it first with get_workspace_settings. Each is 1 to 4 words a buyer would literally write in a LinkedIn post or job advert ("cold email", "missed calls", a competitor's name), at most 48 characters and no explanation in brackets, up to 24. Saving refreshes every managed signal from the list and starts a sweep. A phrase kept from the old list keeps its class; negatives are kept.
- Scope
write- Needs
- Read and write on Workspace context
Arguments
keywordsstring[]required- The complete list of buying-relevant phrases to monitor, in the words buyers use.
save_named_accountsSave the named accounts
Saves the companies the workspace wants to reach by name, and its best current customers, onto the static "Named accounts" audience, the same list onboarding writes. A company name is a target, never a contact: sourcing finds the people there, with its reveal and suppression checks. Each list given replaces the stored one.
- Scope
write- Needs
- Read and write on Contacts
Arguments
targetsstring[]optional- Company names or domains to reach, up to 40. Omit to leave that list as it is.
bestCustomersstring[]optional- Current best customers, up to 40. They are evidence for lookalikes and are never contacted. Omit to leave that list as it is.
list_signalsList signals
Keyword and intent signals, with when each last swept and what it found.
- Scope
read- Needs
- View on Signals
- REST
- GET/signals
Takes no arguments.
get_signalGet a signal
One signal with its definition, when it last ran, its last error, and the most recent people it matched with the evidence for each match.
- Scope
read- Needs
- View on Signals
Arguments
signalIdstringrequired- The signal's id, from list_signals.
set_signal_statusPause or resume a signal
Pauses a signal so it stops sweeping, or resumes it so the next sweep picks it up. Pausing does not remove the people it already found. Two refusals: a managed draft the intent setup set aside is not started by hand, because the setup would set it aside again within minutes (it starts by itself once set_monitoring_keywords gives it keywords of its kind); and a signal a campaign build is still sourcing through is not paused until the build has finished sourcing, because the build would stop for good.
- Scope
write- Needs
- Read and write on Signals
Arguments
signalIdstringrequired- The signal's id.
statusstringrequired- active resumes; paused stops the sweep.
activepaused
update_signal_keywordsChange a signal's keywords
Replaces the phrases one signal searches for: 1 to 24 phrases, each 1 to 4 words a buyer would literally write in a post, at most 48 characters. The next sweep plans its search from the new list. The workspace's managed signals take their keywords from the monitoring list and are refused here; change those with set_monitoring_keywords. Role changes has no keywords (it reads contacts' profiles for new roles) and is refused too.
- Scope
write- Needs
- Read and write on Signals
Arguments
signalIdstringrequired- The signal's id, from list_signals.
keywordsstring[]required- The whole new list. Phrases not in it are dropped.
delete_signalDelete a signal
Permanently deletes a signal, its matches and any audience built on it; the matched contacts stay, and campaigns drawing from those audiences lose them. Refused for the workspace's managed signals (they are recreated, so pause them with set_signal_status), for a signal a campaign build was set up with, and for one an automation starts on. Delete only what the person asked to remove.
- Scope
write- Needs
- Read and write on Signals
Arguments
signalIdstringrequired- The signal's id, from list_signals.
Company context
delete_context_recordDelete a context record
Permanently deletes one company profile, product or service, persona, ICP, competitor or intelligence document from this workspace, the same delete as the AI context screens. The agents stop reading it at once and it cannot be restored. Read it first with read_workspace_context or list_icps and delete only what the person asked to remove. Refused while something still uses it, such as an audience built on an ICP.
- Scope
write- Needs
- Read and write on Workspace context
Arguments
resourcestringrequired- Which kind of context record it is.
company_profilesproducts_servicespersonasicp_definitionscompetitorsintelligence_documents idstringrequired- The record's id, from read_workspace_context or list_icps.
read_workspace_contextRead company and buyer context
Read saved company facts, products and services, personas, competitors or intelligence documents, together with the fields each resource accepts. Read before save_workspace_context. Personas describe buyer motivations; save_icp controls actual targeting.
- Scope
read- Needs
- View on Workspace context
Arguments
resourcestringrequired- Which kind of context record.
company_profilesproducts_servicespersonascompetitorsintelligence_documents idstringoptional- One record's id. On a read, omit for the newest 20. On a save, omit to create.
save_workspace_contextSave company or buyer context
Create or edit a company profile, product or service, persona, competitor or intelligence document using the fields read_workspace_context returned. Supply id to edit. Omitted fields and other tone settings are preserved. Save only facts you were given or can source; never manufacture proof, customers, pricing or offers. Distinguish inferred buyer hypotheses from company facts. Use save_icp for targeting and configure_intent_tracking for signals.
- Scope
write- Needs
- Read and write on Workspace context
Arguments
resourcestringrequired- Which kind of context record.
company_profilesproducts_servicespersonascompetitorsintelligence_documents idstringoptional- One record's id. On a read, omit for the newest 20. On a save, omit to create.
fieldsobjectrequired- The fields to set, by the names the read returned as editable. Omitted fields are preserved.
Agents
list_agentsList agents
Agents in the workspace with their mode and status.
- Scope
read- Needs
- View on Agents
- REST
- GET/agents
Takes no arguments.
edit_agent_promptEdit an agent's prompt
Replace the editable role, tasks or guidelines on one agent. Cannot reach the platform rules, which are not part of the editable prompt.
- Scope
write- Needs
- Read and write on Agents
Arguments
presetstringrequired- Which agent: leads, intent, outreach, copy or qa.
leadsintentoutreachcopyqa rolestringoptional- The agent's role statement. Replaces the current one.
tasksstring[]optional- The agent's task list, up to 24. Replaces the current list.
guidelinesstring[]optional- The agent's guidelines, up to 48. Replaces the current list.
update_agentUpdate an agent
Edits one agent's persona, display copy or editable prompt, the same fields as the Agents screen's Basics, Copy and Prompt tabs. Only the fields given change. The prompt is the role, tasks, guidelines and extra instructions; the platform rules above it cannot be changed. Model tier, temperature and thinking are set with set_agent_model. The roster is fixed at five: this never creates, starts or stops an agent.
- Scope
write- Needs
- Read and write on Agents
Arguments
agentIdstringoptional- The agent's id, from list_agents. Pass this or preset.
presetstringoptional- The agent's role, from list_agents: leads, intent, outreach, copy or qa. Pass this or agentId.
leadsintentoutreachcopyqa namestringoptional- The agent's display name.
descriptionstringoptional- One or two sentences about what it does. Blank clears it.
rolestringoptional- Who the agent is, in the second person. Replaces the stored role.
tasksstring[]optional- What it does, one task per entry, up to 24. Replaces the stored list. Omit to leave unchanged.
guidelinesstring[]optional- How it does it, one rule per entry, up to 48. Replaces the stored list. Omit to leave unchanged.
extrastringoptional- Free-form extra instructions. Blank clears them.
humanizationPackstringoptional- The humanisation pass applied after generation, by name. The default pack is default.
copyobjectoptional- Display copy the screens show. Never read by a model.
displayNamestringoptional- Name shown on cards. Blank uses the role's.
taglinestringoptional- One line under the name. Blank uses the role's.
workingLabelstringoptional- Status word while it works. Blank is Working.
idleLabelstringoptional- Status word while idle. Blank is Idle.
emptyStatestringoptional- What its empty screen says. Blank uses the role's.
set_agent_modelSet an agent's model
Sets which model tier runs one agent, its temperature and how much it thinks, as on the Agents screen's Prompt tab. A higher tier and more thinking cost more on every run the agent makes, so change them only when the person asked. Only the settings given change.
- Scope
write- Needs
- Read and write on Agents
Arguments
agentIdstringoptional- The agent's id, from list_agents. Pass this or preset.
presetstringoptional- The agent's role, from list_agents: leads, intent, outreach, copy or qa. Pass this or agentId.
leadsintentoutreachcopyqa tierstringoptional- economy is cheapest, premium the most capable.
economystandardpremium temperaturenumberoptional- 0 is most literal, 1 most varied.
thinkingstringoptional- Reasoning budget. The largest cost multiplier; off unless the task needs it.
offlowmediumhigh
set_agent_guardrailsSet an agent's guardrails
Sets the topics one agent must not raise and the claims it must never make, as on the Agents screen's Guardrails tab. Each list given replaces the stored one. The unsubscribe requirement is fixed on and cannot be changed.
- Scope
write- Needs
- Read and write on Agents
Arguments
agentIdstringoptional- The agent's id, from list_agents. Pass this or preset.
presetstringoptional- The agent's role, from list_agents: leads, intent, outreach, copy or qa. Pass this or agentId.
leadsintentoutreachcopyqa blockedTopicsstring[]optional- Topics the agent must not raise, up to 64. Omit to leave unchanged.
prohibitedClaimsstring[]optional- Claims the agent must never make, up to 64. Omit to leave unchanged.
set_agent_knowledgeSet an agent's knowledge
Sets which intelligence documents one agent reads, and how, as on the Agents screen's Knowledge tab. The list replaces the stored one; an empty list unbinds every document. full_context inlines a document into every prompt, rag retrieves only the relevant passage, auto lets the runtime choose. Document ids come from read_workspace_context with resource intelligence_documents.
- Scope
write- Needs
- Read and write on Agents
Arguments
agentIdstringoptional- The agent's id, from list_agents. Pass this or preset.
presetstringoptional- The agent's role, from list_agents: leads, intent, outreach, copy or qa. Pass this or agentId.
leadsintentoutreachcopyqa documentsobject[]required- Every document the agent should read, up to 64.
documentIdstringrequired- An intelligence document's id.
usagestringoptionaldefault: auto- How the agent reads it.
autoragfull_context
reset_agentReset an agent's prompt
Puts one agent's prompt, display copy and model back to its role's defaults, discarding every edit to them. Guardrails, knowledge and pacing are untouched. Use only when the person asked to start the agent's writing over.
- Scope
write- Needs
- Read and write on Agents
Arguments
agentIdstringoptional- The agent's id, from list_agents. Pass this or preset.
presetstringoptional- The agent's role, from list_agents: leads, intent, outreach, copy or qa. Pass this or agentId.
leadsintentoutreachcopyqa
list_copy_lessonsList the copy writer's lessons
The writing rules this workspace taught its copy writer by asking for changes to drafts, most-taught first, with how many requests taught each. Every draft the workspace writes follows them, on top of the agents' prompts. Remove one with forget_copy_lesson.
- Scope
read- Needs
- View on Agents
- REST
- GET/copy-lessons
Takes no arguments.
forget_copy_lessonRemove a copy lesson
Retires one lesson from list_copy_lessons, as Remove on the Agents screen does. Messages written afterwards stop following it. Campaign drafts written under it that are still waiting to go are rewritten without it just before they send, and each rewrite spends credits for one AI message; drafts written before it was taught, and words a person wrote or edited, are left as they are. Use it when the person says a saved rule is wrong or no longer wanted.
- Scope
write- Needs
- Read and write on Agents
Arguments
lessonIdstringrequired- The lesson's id, from list_copy_lessons.
Compliance
list_suppressionsList the blocklist
Addresses, domains, LinkedIn profiles and company names this workspace will not contact, newest first. Includes platform-scope rows, which apply to every workspace and cannot be lifted here.
- Scope
read- Needs
- View on Audit log and compliance
- REST
- GET/suppressions
Arguments
targetstringoptional- Only rows of this kind.
emaildomainlinkedin_urlcompany_name limitintegeroptionaldefault: 25- Rows per page, 1 to 100.
cursorstringoptional- Opaque cursor from the previous page's next_cursor. Omit for the first page. Keep every other argument the same while paging.
add_suppressionAdd to the blocklist
Blocks one email address, domain, LinkedIn profile or company name for this workspace, and stops every pending step for contacts it matches by email. Sourcing will not bring a blocked identity back. Suppression survives contact deletion and every retention purge. An entry that already exists is reported as a conflict, which is the state you wanted.
- Scope
write- Needs
- Read and write on Audit log and compliance
Arguments
targetstringrequired- What kind of identity the value is.
emaildomainlinkedin_urlcompany_name valuestringrequired- The address, domain, profile URL or company name.
reasonstringoptionaldefault: manual- Why it is blocked.
unsubscribebouncecomplaintmanualcompetitorexisting_customerlegal_request notestringoptional- Free text kept beside the row.
remove_suppressionRemove from the blocklist
Lifts one of this workspace's own blocklist entries. Platform-scope rows, and rows written because somebody unsubscribed, are not the workspace's to lift and are refused.
- Scope
write- Needs
- Read and write on Audit log and compliance
Arguments
suppressionIdstringrequired- The entry's id, from list_suppressions.
list_audit_eventsRead the audit log
Security-relevant events for the organization, newest first: sign-ins, member changes, billing changes, and API keys and connectors being created or revoked. Carries who and what, never a raw IP address. Organization-level: answers only in the agency workspace.
- Scope
read- Needs
- View on Audit log and compliance
- REST
- GET/audit-events
Arguments
actionstringoptional- Only this action, e.g. api_key.created.
limitintegeroptionaldefault: 25- Rows per page, 1 to 100.
cursorstringoptional- Opaque cursor from the previous page's next_cursor. Omit for the first page. Keep every other argument the same while paging.
Calendars
list_calendarsRead connected calendars
Read this workspace's connected calendars, selected verified booking pages, last completed sync and actual sync errors. A calendar connection alone does not mean a scheduling link has been selected. A Go High Level connection appears here too: with booking_event_type null it is CRM only, and select_scheduling_link turns one of its calendars into the calendar meetings are booked into.
- Scope
read- Needs
- View on Inbox
- REST
- GET/calendars
Takes no arguments.
list_scheduling_linksFind real scheduling pages
Read active event types and their real booking URLs from a connected Calendly, Cal.com or Go High Level account (for Go High Level, the location's calendars). Google Calendar alone returns no scheduling page; never invent one. Use these exact IDs with select_scheduling_link.
- Scope
write- Needs
- Read and write on Inbox
Arguments
calendarIdstringoptional- The calendar connection's id, from list_calendars. The tool may omit it when the workspace has one connected calendar; the REST route takes it in the path.
select_scheduling_linkSelect a verified booking page
Verify and save an existing provider event type or Go High Level calendar for outreach and replies. Choose the relevant sales/demo event from list_scheduling_links; if there is only one suitable event use it. Once selected, the agent offers that calendar's free times, books confirmed meetings into it, and syncs its appointments. Pass eventTypeId null to stop booking into the connection. Does not create an invitation or book a person.
- Scope
write- Needs
- Read and write on Inbox
Arguments
calendarIdstringoptional- The calendar connection's id, from list_calendars. The tool may omit it when the workspace has one connected calendar; the REST route takes it in the path.
eventTypeIdstring | nullrequired- The event type or calendar to book into, by the id list_scheduling_links returned. Pass null to stop booking into this connection; for Go High Level that makes it CRM only again.
sync_calendarCheck calendar meeting outcomes
Reconcile a due calendar page with known contacts. Only provider-confirmed attendees count as booked; drafts, positive replies, and unaccepted invitations do not. A scheduled or partial sync is not proof there are zero meetings. Automatic polling continues every 15 minutes.
- Scope
write- Needs
- Read and write on Inbox
Arguments
calendarIdstringoptional- The calendar connection's id, from list_calendars. The tool may omit it when the workspace has one connected calendar; the REST route takes it in the path.
list_calendar_meetingsRead verified calendar meetings
Read actual provider-verified meetings and cancellations, optionally for a campaign. Attribution uses the last campaign message actually sent before the booking was created. These are calendar outcomes; manual inbox status alone is not provider verification.
- Scope
read- Needs
- View on Inbox
Arguments
campaignIdstringoptional- Only meetings attributed to this campaign.
list_integrationsList integrations
Attached third-party accounts and their health. Never returns a credential — only which provider is attached, whether it last verified, and why it did not.
- Scope
read- Needs
- View on Integrations
- REST
- GET/integrations
Takes no arguments.
test_integrationTest an integration
Calls the vendor with the stored credential and records the answer on the connection: connected when it worked, degraded with the reason when it did not. Use it when list_integrations shows an error, after the operator says they changed a token or its scopes, or before promising that a CRM push or calendar booking will land. Never returns the credential.
- Scope
write- Needs
- Read and write on Integrations
Arguments
providerstringrequired- Which connection to test, by provider id from list_integrations.
google_calendarcalendlycal_comhubspotpipedriveattiosalesforcezohogohighlevelslackzapierwebhook
import_crm_contactsImport contacts from a CRM
Pulls people from a connected CRM into this workspace's Contacts as leads — today from Go High Level, newest first. Narrow by a tag the operator applied in the CRM, or by a name, email or phone query. Reads up to 1000 CRM contacts per call and returns nextCursor when more remain; call again with it to continue. Rows are deduplicated against the workspace and checked against suppression, and a person with no email is not imported because no channel can reach them. Pass listId or listName to land everyone on a static list. Spends no credits and sends nothing.
- Scope
write- Needs
- Read and write on Contacts
Arguments
providerstringoptionaldefault: gohighlevel- The CRM to read from. Only gohighlevel can be read today.
gohighlevel tagstring | nulloptional- Only people carrying this tag in the CRM, e.g. 'hot' or 'webinar'.
querystring | nulloptional- A name, email or phone to match, the way the CRM's own search box would.
limitintegeroptionaldefault: 100- How many CRM contacts to read in this call, newest first. Up to 1000.
cursorstring | nulloptional- nextCursor from the previous call, to continue where it stopped. Omit to start from the newest.
listIdstring | nulloptional- Existing static list ID from list_lists. Use null when using listName.
listNamestring | nulloptional- A static list everyone joins, created if it does not exist. Name it after the source, e.g. 'HighLevel — hot leads'.
configure_integrationConfigure an integration
Change an attached integration's settings without touching its key: the card's name, the account address (a HubSpot portal, a Calendly user, a Google calendar id, a Slack channel) or the booking event type. The change is checked against the vendor with the stored key first, and nothing is saved if the vendor refuses it. Entering or replacing a key happens on the Integrations screen.
- Scope
write- Needs
- Read and write on Integrations
Arguments
providerstringrequired- The integration, by provider id from list_integrations.
google_calendarcalendlycal_comhubspotpipedriveattiosalesforcezohogohighlevelslackzapierwebhook displayNamestringoptional- The name shown on the integration's card.
externalAccountIdstringoptional- The account address the vendor's API needs: a portal id, user URI, calendar id or Slack channel. Never a key.
eventTypestringoptional- Booking integrations: the event type meetings are booked as.
disconnect_integrationDisconnect an integration
Detach an integration from this workspace and delete its stored key. Bookings, CRM sync or alerts through it stop at once, and reconnecting means entering the key again on the Integrations screen.
- Scope
write- Needs
- Read and write on Integrations
Arguments
providerstringrequired- The integration, by provider id from list_integrations.
google_calendarcalendlycal_comhubspotpipedriveattiosalesforcezohogohighlevelslackzapierwebhook
set_webhook_eventsChoose the webhook's events
Choose which events this workspace's connected webhook endpoint receives: reply.received, reply.opt_out, meeting.booked, contact.created and sequence.step. Replaces the list; an empty list sends nothing. The endpoint itself is connected on the Integrations screen.
- Scope
write- Needs
- Read and write on Integrations
Arguments
eventsstring[]required- The event kinds to deliver.
reply.receivedreply.opt_outmeeting.bookedcontact.createdsequence.step
Notifications
list_notificationsList notifications
What the workspace has been told, newest first: leads found, replies, meetings, approvals needed, low credits, degraded connections and failed runs. A notification never carries a contact's name or address; it carries the entity id to look up.
- Scope
read- Needs
- View on Notifications
Arguments
unreadOnlybooleanoptionaldefault: false- Only notifications not yet marked read.
limitintegeroptionaldefault: 25- Rows per page, 1 to 100.
cursorstringoptional- Opaque cursor from the previous page's next_cursor. Omit for the first page. Keep every other argument the same while paging.
mark_notifications_readMark notifications read
Marks notifications read, by id, or every unread one when all is true. Read state is the only thing about a notification that can be changed.
- Scope
read- Needs
- View on Notifications
Arguments
notificationIdsstring[]optional- The notifications to mark.
allbooleanoptionaldefault: false- Mark every unread notification instead.
count_unread_notificationsCount unread notifications
How many notifications are unread in this workspace for whoever authorised this, the number on the shell's bell. Cheaper than listing when only the count matters.
- Scope
read- Needs
- View on Notifications
Takes no arguments.
Insights and usage
get_usageRead credit balance and usage
Credits remaining in each purse (data and action) and what was spent over a trailing window, by metered action. In the agency workspace this is the organization's ledger. Inside a client workspace it is that workspace's own spend against the limits the agency set, because the balance belongs to the agency. `status` says whether agents are paused or running low for lack of credits, and why.
- Scope
read- Needs
- View on Billing and usage
- REST
- GET/usage
Arguments
periodstringoptionaldefault: 30d- The trailing window: 7 days, 30 days or 3 months.
7d30d3mo
list_credit_costsList what each action costs
The price list: every metered action, the purse it is paid from (data or action) and its cost in credits per unit. The same rates apply in the app, over MCP and over the API.
- Scope
read- Needs
- View on Billing and usage
- REST
- GET/credit-costs
Takes no arguments.
get_insightsRead the outreach funnel
The funnel over a trailing window: leads found, contacted, conversations started, replied, interested and meetings booked, plus messages sent per channel and inbound replies. The same definitions the Insights screen uses.
- Scope
read- Needs
- View on Insights
- REST
- GET/insights
Arguments
periodstringoptionaldefault: 30d- The trailing window: 7 days, 30 days or 3 months.
7d30d3mo
get_funnel_snapshotRead the funnel snapshot
One read of the whole funnel for this workspace: contacts and the uncontacted pool, warm and hot leads not yet reached, each channel's capacity and use today, senders that lost their sign-in, every campaign and what stalls it, this week's outcomes against last week's, credits and sourcing. Starts with the bottlenecks, ranked in the order to fix them, and ends with the daily history. Read this first when deciding what to do next.
- Scope
read- Needs
- View on Insights
- REST
- GET/funnel
Arguments
historyDaysintegeroptionaldefault: 14- How many days of the daily funnel history to include, today first (0 to 56).
Labels
list_labelsList labels
Every label in the workspace, by name, with its colour. Labels are the workspace's own tags on contacts, also written by campaign steps (label.add, label.remove). Filter list_contacts or export_contacts by labelId, and put labels on people with add_contact_labels.
- Scope
read- Needs
- View on Contacts
- REST
- GET/labels
Takes no arguments.
add_contact_labelsLabel contacts
Puts one label on contacts. Name an existing label by labelId (from list_labels), or give a name: a label with that name (matched ignoring case) is reused, and a new one is created in the colour you pick. People who already carry it are left alone, and ids that are not contacts of this workspace are ignored and counted. Colours: zinc, graph-agent, graph-audience, graph-company, graph-meeting, graph-note, graph-signal, graph-message, graph-task.
- Scope
write- Needs
- Read and write on Contacts
Arguments
contactIdsstring[]required- Contact ids, up to 5,000 a call. Read them from list_contacts.
labelIdstring | nulloptional- An existing label's id from list_labels. Use null when naming the label instead.
namestring | nulloptional- The label's name, reused if it exists and created if it does not.
colorstringoptionaldefault: zinc- The colour for a label this call creates. Ignored for an existing label.
zincgraph-agentgraph-audiencegraph-companygraph-meetinggraph-notegraph-signalgraph-messagegraph-task
remove_contact_labelsUnlabel contacts
Takes one label off contacts. The label itself stays in the workspace, even when nobody carries it any more, because campaign steps may name it.
- Scope
write- Needs
- Read and write on Contacts
Arguments
contactIdsstring[]required- Contact ids, up to 5,000 a call. Read them from list_contacts.
labelIdstringrequired- The label's id from list_labels.
Domains
list_domainsList sending domains
The workspace's managed sending domains with their status, price and dates, the mailboxes bought on each (setting up, ready or failed, with warm-up progress), and whether the first mailboxes are still on their way.
- Scope
read- Needs
- View on Sender accounts
- REST
- GET/domains
Takes no arguments.
get_domainRead a sending domain
One managed sending domain's status, price and dates, and why it is delayed when it is.
- Scope
read- Needs
- View on Sender accounts
Arguments
domainIdstringrequired- The domain's id, from list_domains.
search_domainsCheck domain names
Ask the registrar whether names are available and what they cost. Takes one domain (acme-mail.com) or a naming pattern of up to 50 names. Answers with a search id at once; read the options with get_domain_search a few seconds later. Buying a domain happens on the Senders screen.
- Scope
write- Needs
- Read and write on Sender accounts
Arguments
querystringrequired- A domain, or a naming pattern that expands to at most 50 names.
get_domain_searchRead a domain search
A domain search's status and its priced options: available or not, premium or not, the price, whether it can be bought today, and when the quote expires. Status queued or running means ask again in a few seconds.
- Scope
read- Needs
- View on Sender accounts
Arguments
searchIdstringrequired- The search id from search_domains or suggest_domains.
suggest_domainsSuggest sending domains
Rank cold-sending domain names for a company's website, with the reasons for each score, and start a registrar search for them. Availability is not known until the search finishes: read it with get_domain_search. Pass earlier search ids for the same website to get new names. Spends credits.
- Scope
write- Needs
- Read and write on Sender accounts
Arguments
websitestringrequired- The company's website or primary domain, such as acme.com.
previousSearchIdsstring[]optional- Up to two earlier suggestion search ids for this website, to exclude their names.
connect_domainConnect a domain you own
Start connecting a domain the organization already owns, bought at any registrar, so mailboxes can be created on it. Answers with a TXT record to publish at the domain's current DNS host. Once the record is found (check_domain_connection, or on its own within minutes), TryGTM prepares the domain's DNS and the connection names two nameservers to set at the registrar. Moving the nameservers moves all of the domain's DNS to TryGTM, so a website or mailboxes already on it stop working: use a domain kept for sending, never the company's main one. Starting again for the same name returns the same connection.
- Scope
write- Needs
- Read and write on Sender accounts
Arguments
namestringrequired- The domain, such as acme-mail.com. A registered domain, not a subdomain.
list_domain_connectionsList domain connections
The workspace's connections of domains it owns, the 50 most recent first: the TXT record that proves each one, what the last check found, the nameservers to set at the registrar once they are known, and whether it is connected, expired or failed.
- Scope
read- Needs
- View on Sender accounts
Takes no arguments.
check_domain_connectionCheck a domain connection
Look for a domain connection's TXT record now instead of waiting for the next automatic check, and answer with the connection. When the record is found the domain is proved and its DNS is prepared; when it is not, lastCheck says what was found instead: nothing yet, a different value, or the name typed twice.
- Scope
write- Needs
- Read and write on Sender accounts
Arguments
connectionIdstringrequired- The connection's id, from connect_domain or list_domain_connections.
remove_domain_connectionRemove a domain connection
Stop connecting a domain: drop the claim, and the domain it became while that still waits for its nameservers. If the owner already moved the nameservers, they should set them back at the registrar. A connected domain whose DNS is already on TryGTM is refused.
- Scope
write- Needs
- Read and write on Sender accounts
Arguments
connectionIdstringrequired- The connection's id, from list_domain_connections.
LinkedIn profiles
list_linkedin_profilesList managed LinkedIn profiles
The personal LinkedIn profiles this workspace manages, each with its state, its capability report (what can be applied automatically and what needs a manual step), whether automatic drafting is on and publishing is paused, and its profilePath. Also lists this workspace's LinkedIn accounts that are not managed yet: enrolling one is its owner's own step on the LinkedIn screen, after a fresh LinkedIn sign-in, so no tool does it. Nothing is published or changed on LinkedIn until a person with LinkedIn access in the workspace approves the exact change on the LinkedIn screen, or the account's automatic posting (which a person turned on there) schedules a post it wrote.
- Scope
read- Needs
- View on linkedin
Takes no arguments.
get_linkedin_profileGet a managed LinkedIn profile
One managed LinkedIn profile: its state and capability report, its switches (automatic drafting, publishing paused), what LinkedIn last showed for the headline, About and Featured (a field LinkedIn did not return is unknown, not empty), earlier recorded versions a restore can name, the current brief (product focus, audience, role, voice, topics to avoid, cadence) and who may approve for it. Nothing is published or changed on LinkedIn until a person with LinkedIn access in the workspace approves the exact change on the LinkedIn screen, or the account's automatic posting (which a person turned on there) schedules a post it wrote.
- Scope
read- Needs
- View on linkedin
Arguments
profileIdstringrequired- The managed profile's id, from list_linkedin_profiles.
list_linkedin_draftsList LinkedIn drafts
A managed profile's recommendations and posts, most recently changed first: headline and About recommendations, Featured changes, new posts and proposed edits or removals of its own posts. Each has its state (needs_review, needs_input, scheduled, published and so on), its current version's text, proposed time, checks and whether it can be approved, and a reviewPath. Nothing is published or changed on LinkedIn until a person with LinkedIn access in the workspace approves the exact change on the LinkedIn screen, or the account's automatic posting (which a person turned on there) schedules a post it wrote. Paged: pass nextCursor back as cursor.
- Scope
read- Needs
- View on linkedin
Arguments
profileIdstringrequired- The managed profile's id, from list_linkedin_profiles.
kindsstring[]optional- Only these kinds of change.
headlineaboutskillsfeatured_addfeatured_removefeatured_reorderpost_createpost_editpost_delete statesstring[]optional- Only drafts in these states, e.g. needs_review.
limitintegeroptionaldefault: 20- Rows per page, 1 to 50.
cursorstringoptional- Opaque cursor from the previous page's nextCursor. Omit for the first page. Keep every other argument the same while paging.
get_linkedin_draftGet a LinkedIn draft
One LinkedIn draft in full: its current version (exact text or field value, links, proposed time and time zone, the claims it makes and the sources behind them, every check and whether it can be approved), its earlier versions, its approvals and publishing attempts, and its history. Nothing is published or changed on LinkedIn until a person with LinkedIn access in the workspace approves the exact change on the LinkedIn screen, or the account's automatic posting (which a person turned on there) schedules a post it wrote. Share its reviewPath with the person, or open it with open_screen (screen linkedin_review, id the itemId); never say it is live.
- Scope
read- Needs
- View on linkedin
Arguments
itemIdstringrequired- The draft's id (itemId), from list_linkedin_drafts or a drafting tool.
list_linkedin_sourcesList LinkedIn sources
The evidence library a managed profile's drafts may draw on: web sources, the person's notes and voice samples, their own posts and records brought in from Context, each with its review status (candidate, public, internal, anonymized, rejected), whether the person attested it, its dates and an excerpt. Only a person reviews or attests a source, on the LinkedIn screen. Nothing is published or changed on LinkedIn until a person with LinkedIn access in the workspace approves the exact change on the LinkedIn screen, or the account's automatic posting (which a person turned on there) schedules a post it wrote. Paged: pass nextCursor back as cursor.
- Scope
read- Needs
- View on linkedin
Arguments
profileIdstringrequired- The managed profile's id, from list_linkedin_profiles.
statusesstring[]optional- Only sources with these review statuses.
candidatepublicinternalanonymizedrejected includeRevokedbooleanoptionaldefault: false- Include revoked sources.
limitintegeroptionaldefault: 25- Rows per page, 1 to 100.
cursorstringoptional- Opaque cursor from the previous page's nextCursor. Omit for the first page. Keep every other argument the same while paging.
list_linkedin_postsList a profile's LinkedIn posts
The posts on a managed profile's own feed, newest first: those published from here and those read from LinkedIn, with the text, when it went out, whether it is still there, and the latest reactions, comments, reposts, impressions and clicks LinkedIn returned (a metric it did not return is unknown, never zero). The postId is what propose_linkedin_post_change takes. Nothing is published or changed on LinkedIn until a person with LinkedIn access in the workspace approves the exact change on the LinkedIn screen, or the account's automatic posting (which a person turned on there) schedules a post it wrote. Paged: pass nextCursor back as cursor.
- Scope
read- Needs
- View on linkedin
Arguments
profileIdstringrequired- The managed profile's id, from list_linkedin_profiles.
originstringoptional- Only posts published from here, or only posts read from LinkedIn.
created_hereimported limitintegeroptionaldefault: 20- Rows per page, 1 to 50.
cursorstringoptional- Opaque cursor from the previous page's nextCursor. Omit for the first page. Keep every other argument the same while paging.
list_linkedin_activityList LinkedIn activity
A managed profile's history, newest first: recommendations, revisions, approvals, cancellations, publishing attempts, readbacks, source changes and changes made on LinkedIn directly, each with who acted (person, agent, operator, API key or system) and when. Nothing is published or changed on LinkedIn until a person with LinkedIn access in the workspace approves the exact change on the LinkedIn screen, or the account's automatic posting (which a person turned on there) schedules a post it wrote. Paged: pass nextCursor back as cursor.
- Scope
read- Needs
- View on linkedin
Arguments
profileIdstringrequired- The managed profile's id, from list_linkedin_profiles.
limitintegeroptionaldefault: 25- Rows per page, 1 to 100.
cursorstringoptional- Opaque cursor from the previous page's nextCursor. Omit for the first page. Keep every other argument the same while paging.
list_linkedin_lessonsList LinkedIn writing preferences
The writing preferences a managed profile's person saved for their own public content (for the profile, for posts, or for both), oldest first. Every later LinkedIn draft for that profile follows them; they never change words a person already approved, and they are separate from the outreach copy lessons. Remove one with forget_linkedin_lesson. Nothing is published or changed on LinkedIn until a person with LinkedIn access in the workspace approves the exact change on the LinkedIn screen, or the account's automatic posting (which a person turned on there) schedules a post it wrote.
- Scope
read- Needs
- View on linkedin
Arguments
profileIdstringrequired- The managed profile's id, from list_linkedin_profiles.
request_linkedin_profile_recommendationWrite a headline, About or skills recommendation
Writes a new headline (the line under the person's name), About section or list of skills to add for a managed profile, from the workspace's context, the account's notes and the person's voice, as Rewrite with AI on the LinkedIn screen does. There is one open recommendation per field: asking again replaces it. It states only facts the workspace or notes give, and leaves out anything else rather than asking. Nothing is published or changed on LinkedIn until a person with LinkedIn access in the workspace approves the exact change on the LinkedIn screen, or the account's automatic posting (which a person turned on there) schedules a post it wrote. Share its reviewPath with the person, or open it with open_screen (screen linkedin_review, id the itemId); never say it is live.
- Scope
write- Needs
- Read and write on linkedin
Arguments
profileIdstringrequired- The managed profile's id, from list_linkedin_profiles.
fieldstringrequired- headline is the short line under the name; about is the long summary; skills are skills to add.
headlineaboutskills requeststring | nulloptional- What the person wants from it, in their words. Omit for the writer's own recommendation.
draft_linkedin_postDraft a LinkedIn post
Writes one post for a managed profile from the workspace's context, the account's notes and the person's voice, as Write a post on the LinkedIn screen does. Every factual claim is tied to a source; what nothing supports is left out, never invented. Nothing is published or changed on LinkedIn until a person with LinkedIn access in the workspace approves the exact change on the LinkedIn screen, or the account's automatic posting (which a person turned on there) schedules a post it wrote. Share its reviewPath with the person, or open it with open_screen (screen linkedin_review, id the itemId); never say it is live.
- Scope
write- Needs
- Read and write on linkedin
Arguments
profileIdstringrequired- The managed profile's id, from list_linkedin_profiles.
anglestring | nulloptional- The observation or lesson the post is built on. Omit to let the writer choose from the sources.
requeststring | nulloptional- Anything else the person asked for, in their words.
revise_linkedin_draftRewrite a LinkedIn draft from a request
Rewrites a LinkedIn draft from the person's words ('less promotional', 'use my example from the launch notes'), as Rewrite with AI on the LinkedIn screen does, saving a new version; earlier versions stay in its history. With saveAsLesson it also saves the request as a preference for every later draft for that profile; say so to the person first. A change a person already approved is not rewritten. Nothing is published or changed on LinkedIn until a person with LinkedIn access in the workspace approves the exact change on the LinkedIn screen, or the account's automatic posting (which a person turned on there) schedules a post it wrote. Share its reviewPath with the person, or open it with open_screen (screen linkedin_review, id the itemId); never say it is live.
- Scope
write- Needs
- Read and write on linkedin
Arguments
itemIdstringrequired- The draft's id (itemId), from list_linkedin_drafts or a drafting tool.
expectedRevisionIdstringrequired- The version you read (revision.id from get_linkedin_draft). A newer version is refused as a conflict.
requeststringrequired- What to change, in the person's words.
saveAsLessonbooleanoptionaldefault: false- Also keep the request as a preference for every later draft for this profile. Only when the person says it applies from now on.
edit_linkedin_draftEdit a LinkedIn draft
Saves new words and/or a proposed publishing time for a LinkedIn draft as a new unapproved version, as Edit on the LinkedIn screen does: text replaces a headline, an About section or a post's text; visibility and comments apply to a new post; scheduledFor and timezone propose when a post goes out. A proposed time is only a proposal. A change a person already approved is not edited. Nothing is published or changed on LinkedIn until a person with LinkedIn access in the workspace approves the exact change on the LinkedIn screen, or the account's automatic posting (which a person turned on there) schedules a post it wrote. Share its reviewPath with the person, or open it with open_screen (screen linkedin_review, id the itemId); never say it is live.
- Scope
write- Needs
- Read and write on linkedin
Arguments
itemIdstringrequired- The draft's id (itemId), from list_linkedin_drafts or a drafting tool.
expectedRevisionIdstringrequired- The version you read (revision.id from get_linkedin_draft). A newer version is refused as a conflict.
textstringoptional- The new words: the headline, the About section or the post's text.
visibilitystringoptional- Who can see a new post.
anyoneconnections commentsstringoptional- Who can comment on a new post.
anyoneconnectionsno_one scheduledForstring | nulloptional- The proposed publishing time, ISO 8601 with an offset. Null proposes no time. Needs timezone.
timezonestring | nulloptional- The IANA time zone the time is shown in, e.g. America/Chicago.
dismiss_linkedin_draftDismiss a LinkedIn draft
Dismisses an open LinkedIn draft, with an optional reason the writer learns from, as Dismiss on the LinkedIn screen does. The same recommendation is not raised again until its inputs change. A change a person already approved is not dismissed; they cancel it on the LinkedIn screen. Nothing is published or changed on LinkedIn until a person with LinkedIn access in the workspace approves the exact change on the LinkedIn screen, or the account's automatic posting (which a person turned on there) schedules a post it wrote.
- Scope
write- Needs
- Read and write on linkedin
Arguments
itemIdstringrequired- The draft's id (itemId), from list_linkedin_drafts or a drafting tool.
reasonstring | nulloptional- Why, in the person's words.
reopen_linkedin_draftReopen a stale LinkedIn draft
Puts a stale or safely failed LinkedIn draft back into review, as Reopen on the LinkedIn screen does, for the person to look at again. It approves nothing: a person approves it again before anything goes out. Nothing is published or changed on LinkedIn until a person with LinkedIn access in the workspace approves the exact change on the LinkedIn screen, or the account's automatic posting (which a person turned on there) schedules a post it wrote. Share its reviewPath with the person, or open it with open_screen (screen linkedin_review, id the itemId); never say it is live.
- Scope
write- Needs
- Read and write on linkedin
Arguments
itemIdstringrequired- The draft's id (itemId), from list_linkedin_drafts or a drafting tool.
propose_linkedin_featuredRecommend Featured changes
Recommends what a managed profile's Featured section should hold and in what order (things that explain the product, show proof, or offer a next step), as the Featured recommendation on the LinkedIn screen does. Only content that already exists is proposed. Where LinkedIn cannot apply a Featured change automatically, the person applies it by hand from the review. Nothing is published or changed on LinkedIn until a person with LinkedIn access in the workspace approves the exact change on the LinkedIn screen, or the account's automatic posting (which a person turned on there) schedules a post it wrote. Share its reviewPath with the person, or open it with open_screen (screen linkedin_review, id the itemId); never say it is live.
- Scope
write- Needs
- Read and write on linkedin
Arguments
profileIdstringrequired- The managed profile's id, from list_linkedin_profiles.
propose_linkedin_post_changePropose an edit or removal of a LinkedIn post
Proposes new text for, or the removal of, one of a managed profile's own published posts (postId from list_linkedin_posts), as the post's Edit or Remove on the LinkedIn screen does. A post that was public cannot be unseen, so a removal says so in its review. Nothing is published or changed on LinkedIn until a person with LinkedIn access in the workspace approves the exact change on the LinkedIn screen, or the account's automatic posting (which a person turned on there) schedules a post it wrote. Share its reviewPath with the person, or open it with open_screen (screen linkedin_review, id the itemId); never say it is live.
- Scope
write- Needs
- Read and write on linkedin
Arguments
profileIdstringrequired- The managed profile's id, from list_linkedin_profiles.
postIdstringrequired- The post's id, from list_linkedin_posts.
actionstringrequired- edit proposes new text; delete proposes removing the post.
editdelete textstring | nulloptional- The new text. Required for edit.
propose_linkedin_restorePropose restoring an earlier headline or About
Proposes putting a managed profile's headline or About section back to an earlier recorded version (snapshotId from get_linkedin_profile's earlierVersions), as Restore this version on the LinkedIn screen does. It is a fresh recommendation like any other; nothing is rolled back automatically. Nothing is published or changed on LinkedIn until a person with LinkedIn access in the workspace approves the exact change on the LinkedIn screen, or the account's automatic posting (which a person turned on there) schedules a post it wrote. Share its reviewPath with the person, or open it with open_screen (screen linkedin_review, id the itemId); never say it is live.
- Scope
write- Needs
- Read and write on linkedin
Arguments
profileIdstringrequired- The managed profile's id, from list_linkedin_profiles.
fieldstringrequired- The field to restore.
headlineabout snapshotIdstringrequired- The recorded version's id, from get_linkedin_profile's earlierVersions.
add_linkedin_sourceAdd a LinkedIn source
Adds a candidate source to a managed profile's evidence library: a web page (kind url, with its link), a note, or a voice sample, as Add source on the LinkedIn screen does. It arrives as a candidate: only a person reviews it for public use or attests a first-hand account, on the LinkedIn screen, and drafts cannot rely on it until then. Nothing is published or changed on LinkedIn until a person with LinkedIn access in the workspace approves the exact change on the LinkedIn screen, or the account's automatic posting (which a person turned on there) schedules a post it wrote.
- Scope
write- Needs
- Read and write on linkedin
Arguments
profileIdstringrequired- The managed profile's id, from list_linkedin_profiles.
kindstringrequired- url is a web page; personal_note a fact or story; voice_sample words that show how the person writes.
urlpersonal_notevoice_sample titlestringrequired- A short title the person will recognise.
excerptstringrequired- The words the source contributes, quoted exactly.
canonicalUrlstring | nulloptional- The page's link. Required for url.
publisherstring | nulloptional- Who published it.
publishedAtstring | nulloptional- When it was published, ISO 8601 with an offset, when known.
expiresAtstring | nulloptional- When a time-sensitive fact stops being safe to use, ISO 8601 with an offset.
import_linkedin_context_sourcesBring Context into a LinkedIn profile's sources
Brings this workspace's Context (the company, the brief's products and personas, its ICP and intelligence documents) into a managed profile's sources as candidates, as Import from Context on the LinkedIn screen does. Nothing from another workspace, and nothing is marked reviewed: a person reviews each for public use on the LinkedIn screen. Nothing is published or changed on LinkedIn until a person with LinkedIn access in the workspace approves the exact change on the LinkedIn screen, or the account's automatic posting (which a person turned on there) schedules a post it wrote.
- Scope
write- Needs
- Read and write on linkedin
Arguments
profileIdstringrequired- The managed profile's id, from list_linkedin_profiles.
revoke_linkedin_sourceRevoke a LinkedIn source
Revokes a source that is wrong or out of date, as Revoke on the LinkedIn screen does: every draft relying on it goes back for review, and an approval relying on it that has not gone out is withdrawn and must be given again. A safety stop: it can only narrow what goes out, never add to it. Nothing is published or changed on LinkedIn until a person with LinkedIn access in the workspace approves the exact change on the LinkedIn screen, or the account's automatic posting (which a person turned on there) schedules a post it wrote.
- Scope
write- Needs
- Read and write on linkedin
Arguments
sourceIdstringrequired- The source's id, from list_linkedin_sources.
reasonstringrequired- Why it is revoked, for the history.
save_linkedin_briefSave a LinkedIn profile's brief
Saves a new version of a managed profile's brief (the product it serves, its audience, the person's role and positioning, call to action, voice, topics to avoid, cadence, time zone and spending cap), as Save brief on the LinkedIn screen does. Omitted fields keep the current brief's values; the first brief needs roleTitle and timezone. Drafts already written keep the version they were written under. Nothing is published or changed on LinkedIn until a person with LinkedIn access in the workspace approves the exact change on the LinkedIn screen, or the account's automatic posting (which a person turned on there) schedules a post it wrote.
- Scope
write- Needs
- Read and write on linkedin
Arguments
profileIdstringrequired- The managed profile's id, from list_linkedin_profiles.
primaryProductIdstring | nulloptional- The product or service the profile is built around, from this workspace's Context.
secondaryProductIdsstring[]optional- Other products it may mention. Replaces the current list.
personaIdsstring[]optional- The buyer personas it speaks to. Replaces the current list.
icpIdstring | nulloptional- The ideal customer profile it speaks to.
roleTitlestringoptional- What the person actually does, in their words. Never invented from the product.
positioningstring | nulloptional- How the person wants to be known.
callToActionstring | nulloptional- The next step the profile invites.
voiceNotesstring | nulloptional- How the person writes.
voiceSampleSourceIdsstring[]optional- Voice samples from this profile's sources. Replaces the current list.
avoidTopicsstring[]optional- Topics never to raise. Replaces the current list.
namingPolicystringoptional- Whether customers may be named: only with permission, anonymized, or never.
name_with_permissionanonymizenever cadencePerWeekintegeroptional- How many posts a week automatic drafting prepares, 0 to 7.
timezonestringoptional- The IANA time zone times are shown in, e.g. America/Chicago.
monthlyCreditCapintegeroptional- The most credits preparing this profile's content may spend in a month.
set_linkedin_switchesPause LinkedIn drafting or publishing
Pauses automatic drafting, or publishing, for a managed profile, as the Pause drafting and Pause publishing switches on the LinkedIn screen do. Pausing publishing holds approved changes (they expire if their window passes) and cancels nothing. Turning drafting on or resuming publishing is the person's own switch on the LinkedIn screen, so this only pauses. Nothing is published or changed on LinkedIn until a person with LinkedIn access in the workspace approves the exact change on the LinkedIn screen, or the account's automatic posting (which a person turned on there) schedules a post it wrote.
- Scope
write- Needs
- Read and write on linkedin
Arguments
profileIdstringrequired- The managed profile's id, from list_linkedin_profiles.
preparationEnabledfalseoptional- false pauses automatic drafting.
publishingPausedtrueoptional- true pauses publishing.
forget_linkedin_lessonRemove a LinkedIn writing preference
Retires one of a managed profile's writing preferences (lessonId from list_linkedin_lessons), as Remove on the LinkedIn screen does. Drafts written afterwards stop following it; words already written or approved are not changed. Use it when the person says a saved preference is wrong or no longer wanted. Nothing is published or changed on LinkedIn until a person with LinkedIn access in the workspace approves the exact change on the LinkedIn screen, or the account's automatic posting (which a person turned on there) schedules a post it wrote.
- Scope
write- Needs
- Read and write on linkedin
Arguments
lessonIdstringrequired- The preference's id, from list_linkedin_lessons.
Other
suppress_contactSuppress a contact
Adds an address to the workspace suppression list and stops every pending message for them. Use this when someone asks to be left alone in a channel the poller does not read.
- Scope
write- Needs
- Read and write on Audit log and compliance
Arguments
emailstringrequired- The address to suppress.
reasonstringoptional- Why. Recorded on the suppression row.
search_workspaceSearch the workspace
Finds named things across the workspace, as the command palette does: contacts and every place a contact already appears (inbox threads, queued campaign steps, lists, the agent that found them), then agents, lists, signals, team members, senders, integrations, templates and notifications. Each hit carries the screen path it opens. Only sections your permissions can see are searched. `failed` names any section that could not be searched this time: its records are missing from `data`, so an empty `data` then does not mean nothing matched.
- Scope
read- Needs
- View on agent
Arguments
querystringrequired- A name, email, company, or record id.
pull_sourcing_forwardPull sourcing forward
Moves this workspace's next GTM Leads sourcing run to now, so new people are found within about 15 minutes instead of at the next daily run. The run spends data credits under the leads agent's own budget, as a scheduled run does. Changes nothing, and says why, when the workspace has no active leads agent, when a run finished in the last 15 minutes, or when a run is already due within the hour. Use it when the pool of people waiting to be contacted is running low.
- Scope
write- Needs
- Read and write on Agents
Takes no arguments.
list_saved_searchesList saved and recent searches
The workspace's saved prospect searches by name, and your own recent searches, most recent first, as the Search screen lists them. Each carries its filters (pass them as search to search_prospects, count_prospects or import_prospects) and a one-line summary.
- Scope
read- Needs
- View on Contacts
Takes no arguments.
save_searchSave a prospect search
Saves a prospect search under a name for the whole workspace, as the Search screen's Save button does. The filters are the Search screen's filter model (search). A name already in use is refused.
- Scope
write- Needs
- Read and write on Contacts
Arguments
namestringrequired- What to call it, e.g. the ICP it finds.
searchstringrequired- The Search screen's filter model as its compact JSON string, as search_prospects takes it and list_saved_searches returns it.
delete_saved_searchDelete a saved search
Removes a saved prospect search from the workspace, for everyone. The contacts it found are untouched.
- Scope
write- Needs
- Read and write on Contacts
Arguments
savedSearchIdstringrequired- The saved search's id from list_saved_searches.
clear_search_historyClear your recent searches
Forgets your own recent prospect searches in this workspace, as the Search screen's Clear button does. Saved searches and other people's history stay.
- Scope
write- Needs
- Read and write on Contacts
Takes no arguments.
sync_linkedin_profileRefresh a LinkedIn profile
Reads the person's own LinkedIn profile now and records what it shows (headline, About, Featured where LinkedIn returns it) and which operations the account supports, as Refresh on the LinkedIn screen does. Reports fields changed on LinkedIn directly since the last read; drafts written against the old text are marked stale for review. It reads only and changes nothing on LinkedIn. Nothing is published or changed on LinkedIn until a person with LinkedIn access in the workspace approves the exact change on the LinkedIn screen, or the account's automatic posting (which a person turned on there) schedules a post it wrote.
- Scope
read- Needs
- View on linkedin
Arguments
profileIdstringrequired- The managed profile's id, from list_linkedin_profiles.
read_operator_memoryRead the operator's memory
The GTM operator's memory for this workspace: its plan (up to 12 steps, each with its ladder rung and status), the bottleneck it is working on, its rolling summary of what the person asked for and what changed, and its last briefing, with the version a save must name. A workspace with no memory reads as version 0. Holds counts, ids and campaign names only.
- Scope
read- Needs
- View on agent
Takes no arguments.
undo_operator_actionUndo an operator change
Takes back one change the GTM operator made, by its action id (list_operator_actions, or the change in the Agent thread). Refused when the record has changed since, naming what changed; a person may pass force to set it back regardless. Some changes can only be undone by a person, and some not at all; the refusal says which and why.
- Scope
write- Needs
- Read and write on agent
Arguments
actionIdstringrequired- The change to take back.
forcebooleanoptional- Set it back even though the record changed since. People only.
reasonCodestringoptional- For the operator: required when undoing lowers send capacity.
deliverability_incidentlost_sign_inperson_askedaudience_exhaustedreplaced_by_bettergoal_changedcomplianceretired_setting reasonstringoptional- For the operator: why, in one sentence.
list_operator_actionsList the operator's changes
The changes the GTM operator made in this workspace, newest first: each as a sentence (what changed from what to what, why, and whether and until when it can be undone), with its status, reason, changes and undo. Filter by time or by run.
- Scope
read- Needs
- View on agent
Arguments
sincestringoptional- Only changes made at or after this time.
runIdstringoptional- Only the changes one operator run made.
limitintegeroptional- How many, newest first. 50 by default.
list_recommendationsList the operator's recommendations
What the GTM operator has asked a person to do in this workspace: buy credits, move plan, add mailboxes, reconnect a sender, change the goal and so on. Each card says what to do, what it would unlock and the screen where it is done. Open cards by default, most urgent first.
- Scope
read- Needs
- View on agent
Arguments
statusstringoptional- Open by default.
opendonedismissedsupersededexpired
dismiss_recommendationDismiss a recommendation
Closes one of the GTM operator's open recommendation cards as not wanted. The operator does not raise the same card again for 7 days. A person's decision: the operator closes its own cards when they are done.
- Scope
write- Needs
- Read and write on agent
Arguments
recommendationIdstringrequired- The card to dismiss.
notestringoptional- Why, if the person said.
assign_sender_workspaceMove a sender between workspaces
Agency only. Give a sender to one client workspace (only that client's outreach can use it), share it with every client, or make it the agency's own again. Moving a sender changes whose outreach leaves through it, so name the sender and the destination before calling. Answers only in the agency workspace.
- Scope
write- Needs
- Read and write on Sender accounts
Arguments
senderIdstringrequired- The sender's id, from list_senders.
assignTo"agency" | "shared" | stringrequired- Where it goes: agency (the agency's own, private), shared (an agency sender every client may use), or a client workspace id from list_workspaces.
request_mailboxesRequest mailboxes on a domain
Ask for up to three new mailboxes on a ready managed domain, or retry failed ones by address. The mailboxes are bought, built and signed in by the next ticks; nothing is sent. Each mailbox becomes a connected account: past the plan's included accounts each one adds $12 a month to the subscription. Say that before asking.
- Scope
write- Needs
- Read and write on Sender accounts
Arguments
domainIdstringrequired- A ready domain's id, from list_domains.
mailboxesobject[]optional- New mailboxes: firstName, lastName and username for each. Give this or retry.
firstNamestringrequiredlastNamestringrequiredusernamestringrequiredretrystring[]optional- Addresses of failed mailboxes on this domain to try again. Give this or mailboxes.
list_api_keysList API keys
The organization's REST API keys: name, display prefix, read or write scopes, the client workspace a key is pinned to (null is the agency), last use, expiry and revocation. Never returns a key or its hash; a new key is created on the API screen, where it is shown once. Agency workspace only.
- Scope
write- Needs
- Read and write on Integrations
Takes no arguments.
revoke_api_keyRevoke an API key
Revoke one REST API key. Every integration using it starts getting 401 at once, and it cannot be turned back on; a replacement is minted on the API screen. Agency workspace only.
- Scope
write- Needs
- Read and write on Integrations
Arguments
keyIdstringrequired- The key's id, from list_api_keys.
list_authorized_assistantsList authorised assistants
The AI assistants you have connected to this organization over MCP (Claude, ChatGPT, Cursor and the like): which client, read or write access, when it was authorised and last used. Only your own; each person manages theirs.
- Scope
read- Needs
- View on Integrations
Takes no arguments.
revoke_assistantRevoke an assistant
Disconnect one AI assistant you authorised over MCP. It loses access at once and has to be authorised again to come back. Revoking the one you are talking through ends this conversation's access.
- Scope
write- Needs
- Read and write on Integrations
Arguments
assistantIdstringrequired- The authorisation's id, from list_authorized_assistants.
list_membersList members
Who can act in this workspace: each member's name, email, role and permission map. In the agency workspace that is the agency's team; inside a client workspace it is that client's members plus the agency staff who can reach it (read only). Also lists open invites by address and role for someone who manages the team, never their links. Inviting someone happens on the Members screen.
- Scope
read- Needs
- View on team
Takes no arguments.
revoke_inviteWithdraw an invite
Withdraw an invite that has not been accepted. Its link stops working at once; to invite the person again, send a new invite from the Members screen.
- Scope
write- Needs
- Read and write on team
Arguments
inviteIdstringrequired- The invite's id, from list_members.
remove_memberRemove a member
Remove a person from the organization. They lose access to every screen and every assistant they authorised at once. Never the owner, never yourself; inside a client workspace only that workspace's own members. Coming back takes a new invite.
- Scope
write- Needs
- Read and write on team
Arguments
userIdstringrequired- The member's user id, from list_members.
create_client_workspaceCreate a client workspace
Agency only. Create an isolated workspace for a client: its own contacts, senders, campaigns and inbox. Past the plan's included workspaces each one adds $99 a month to the subscription; say so before creating. You stay in this workspace: the person switches into the new one from the workspace menu and finishes its setup at /onboarding.
- Scope
write- Needs
- Read and write on Settings
Arguments
namestringrequired- The client's name, as the workspace menu shows it.
logoUrlstring | nulloptionaldefault: null- A full https URL of the client's logo, or null for none.
dataCreditLimitinteger | nulloptional- Credits this workspace may spend a month. Null removes the limit; 0 freezes it. Omit to keep it.
actionCreditLimitinteger | nulloptional- Credits this workspace may spend a month. Null removes the limit; 0 freezes it. Omit to keep it.
update_client_workspaceUpdate a client workspace
Agency only. Rename a client workspace, change its logo URL, or set its monthly data and action credit limits. Fields you leave out keep their value. Raising or removing a limit lets the client spend more of the agency's credits, so say what changes.
- Scope
write- Needs
- Read and write on Settings
Arguments
workspaceIdstringrequired- The client workspace's id, from list_workspaces.
namestringoptional- The new name.
logoUrlstring | nulloptional- A full https URL of the logo. Null removes it.
dataCreditLimitinteger | nulloptional- Credits this workspace may spend a month. Null removes the limit; 0 freezes it. Omit to keep it.
actionCreditLimitinteger | nulloptional- Credits this workspace may spend a month. Null removes the limit; 0 freezes it. Omit to keep it.
archive_client_workspaceArchive a client workspace
Agency only. Archive a client workspace: nobody can work in it, its members lose access, and its outreach stops. Its data is kept and it can be restored. The client-workspace add-on goes down with the count.
- Scope
write- Needs
- Read and write on Settings
Arguments
workspaceIdstringrequired- The client workspace's id, from list_workspaces.
restore_client_workspaceRestore a client workspace
Agency only. Bring an archived client workspace back. Restoring counts as creating one: past the plan's included workspaces it adds $99 a month to the subscription.
- Scope
write- Needs
- Read and write on Settings
Arguments
workspaceIdstringrequired- The archived workspace's id.
update_profileUpdate your profile
Change your own name or profile picture URL, as other members see them. Your email is your sign-in and cannot be changed here.
- Scope
write- Needs
- Read and write on agent
Arguments
fullNamestringoptional- Your name.
avatarUrlstring | nulloptional- A full https URL of your picture. Null removes it.
get_affiliate_statsRead referral earnings
The organization's referral programme: its code and link, how many organizations it referred and how many pay, commission earned, owed and paid (in cents), and earnings per month for the last year. Agency workspace only.
- Scope
read- Needs
- View on Billing and usage
Takes no arguments.
update_referral_codeChange the referral code
Owner only. Replace the organization's referral code: at least 5 characters, letters, digits and hyphens. The old link stops working the moment the new code is saved, so anyone holding it lands nowhere. Agency workspace only.
- Scope
write- Needs
- Read and write on Billing and usage
Arguments
codestringrequired- The new referral code.