Skip to main content
About this page · Updated 2026-11-05 16:07 UTC

What this page is: Marketing email: lists, templates, campaigns and reports: every tool on the `communications` MCP server with its scope, inputs and an example call. A slice of the full MCP tool reference.

How far to trust this page: the build checked 0 names, paths, tools, scopes and error codes against the real product (0 do not match). Not yet reviewed claim by claim.

Updated 2026-11-05 16:07 UTCRecently updated pages

MCP tools: Communications

Marketing email: lists, templates, campaigns and reports. This page is the slice of the full MCP tool reference for the communications server (the other servers are listed on the hosted servers page). The main server carries every tool, so these entries apply there too. Failures use the shape described in MCP errors.

motorical_whoami​

Who am I (account, plan, grant). Who this connection is acting for: the account (id, owner email, name), its plan (name, status, hasSubscription), account.billing (price amount in minor units + currency + interval, trial end, current period end / next renewal date, cancelAtPeriodEnd and endsAt, this month's sends against the plan cap, and paymentMethod.status ok or failing; never invoices, receipts or card details; a field it cannot resolve is null with its reason under billing.unavailable) and, for an OAuth connection, the grant: the client, the scopes it holds, the Motor Blocks it covers, when it was granted, and canAdd (permissions it could still be given, with available:false where the plan does not allow it) plus addInDashboard, the page where the person adds them. Account-scoped: no Motor Block needed. grant is null when the call is not made over an OAuth grant. Over OAuth it needs no scope, so any connection can ask what it holds, and every server lists it. Use it instead of inferring scopes from the tool list.

PropertyValue
Needs scopeNo scope: any OAuth connection can call it
Available onHosted servers: main, transactional, analytics, domains, sandbox, webhooks, motorBlocks, communications; the local server too
Acts onThe whole account (no Motor Block needed)
Not listedNever
REST routeGET /api/public/v1/account/whoami
BehaviourRead-only; safe to repeat
InputTypeRequiredMeaning
motorBlockIdstring (uuid)NoOptional. This operation acts on the whole account, so a Motor Block is never needed; pass one only to record which block the call was made on behalf of.

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{}

comms_get_readiness​

Marketing readiness. What still stands between this workspace and a sent marketing campaign. Returns ready, next (the FIRST missing step with a message and a fix hint, or null) and steps in a fixed order: plan, workspace, domain, marketing_block, list, template, plus the sending limits (hourly, daily) of the workspace's campaign Motor Blocks. Read-only. Say the first missing thing, not the whole list. If the missing step is the plan, read the current plans from the motorical://docs/plans resource, or GET https://motorical.com/api/billing/plans if your client cannot read resources (never quote a plan or price from memory); only the person can change plan. Pass workspaceId, or omit it when this authorization covers exactly one workspace; with several, the error lists them. Requires OAuth scope: read:comms (see motorical_whoami for what it allows).

PropertyValue
Needs scoperead:comms
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routeGET /comm-api/api/readiness
BehaviourRead-only; safe to repeat
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices).

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{}

comms_get_map​

Marketing workspace map. The marketing workspace at a glance: its lists (short cards with kind, counts of members and eligible contacts, whether the list is a one-time snapshot, whether its description is good), the 50 most recent campaigns (status, list_ids, exclude_list_ids, pacing), its templates (with how many campaigns use each) and the edges between them: sends_to, excludes, uses, derived_from. Use it to orient yourself in ONE call before choosing a list or template by name. Read-only. Pass workspaceId, or omit it when this authorization covers exactly one workspace. Requires OAuth scope: read:comms (see motorical_whoami for what it allows).

PropertyValue
Needs scoperead:comms
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routeGET /comm-api/api/map
BehaviourRead-only; safe to repeat
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices).

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{}

comms_list_workspaces​

Marketing workspaces. The marketing workspaces this authorization covers: id, name, slug, status and isDefault. A workspace is one brand or sending identity; the default workspace is the account's main one, listed first. Most customers only need the default: do not suggest creating more, and do not mention workspaces at all when exactly one is covered. Account-level, so it takes no workspaceId. Read-only. Requires OAuth scope: read:comms (see motorical_whoami for what it allows).

PropertyValue
Needs scoperead:comms
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routeGET /comm-api/api/workspaces
BehaviourRead-only; safe to repeat
InputTypeRequiredMeaning
limitintegerNoHow many items to return (default 50, at most 200).
offsetintegerNoHow many items to skip, to read the next page (default 0).

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{}

comms_list_marketing_blocks​

Marketing sending identities. The campaign Motor Blocks assigned to this workspace: id, name, active, the sending domain and whether it is verified. A campaign sends through one of these, from an address on its verified domain. If the list is empty or the domain is unverified, comms_get_readiness says what to do next. Read-only. Requires OAuth scope: read:comms (see motorical_whoami for what it allows).

PropertyValue
Needs scoperead:comms
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routeGET /comm-api/api/workspaces/current/motor-blocks
BehaviourRead-only; safe to repeat
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{}

comms_list_lists​

Contact lists. The workspace's contact lists as cards: name, description, kind, where it came from, how many members and how many are eligible to receive mail, and whether it is a one-time snapshot. Counts come from this result; quote them with the time you read them, never from memory. Paged (default 50, at most 200; see page.truncated). To orient in one call use comms_get_map instead. Archived lists are hidden; archived=include shows them too, archived=only just those. Read-only. Requires OAuth scope: read:comms (see motorical_whoami for what it allows).

PropertyValue
Needs scoperead:comms
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routeGET /comm-api/api/lists
BehaviourRead-only; safe to repeat
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
limitintegerNoHow many items to return (default 50, at most 200).
offsetintegerNoHow many items to skip, to read the next page (default 0).
archivedone of include, onlyNoShow archived lists as well (include) or only those (only).

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{}

comms_get_list​

One contact list. One list's card: description, kind, source, member and eligible counts, provenance. Does not return the contacts themselves. Read-only. Requires OAuth scope: read:comms (see motorical_whoami for what it allows).

PropertyValue
Needs scoperead:comms
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routeGET /comm-api/api/lists/{id}
BehaviourRead-only; safe to repeat
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
idstring (uuid)YesThe list id.

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{"id":"<id>"}

comms_compare_lists​

Compare two lists. How two lists overlap: contacts only in the first, only in the second, in both, with the counts of active members. Use it before choosing between two similar lists or before excluding one from a campaign. Two different lists are required (SAME_LIST otherwise). Read-only. Requires OAuth scope: read:comms (see motorical_whoami for what it allows).

PropertyValue
Needs scoperead:comms
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routeGET /comm-api/api/lists/compare
BehaviourRead-only; safe to repeat
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
astring (uuid)YesThe first list id.
bstring (uuid)YesThe second list id.

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{"a":"<a>","b":"<b>"}

comms_get_list_relations​

How a list was built. The lists this list was derived from, excludes or feeds: edges with a relation (derived_from, excludes) and direction. A derived list is a snapshot taken at one moment, not live. Read-only. Requires OAuth scope: read:comms (see motorical_whoami for what it allows).

PropertyValue
Needs scoperead:comms
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routeGET /comm-api/api/lists/{id}/relations
BehaviourRead-only; safe to repeat
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
idstring (uuid)YesThe list id.

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{"id":"<id>"}

comms_list_templates​

Email templates. The workspace's templates as cards: name, subject, kind, description, what it was derived from, and used_by_count (how many campaigns use it, which decides whether it can be deleted). No bodies; fetch one with comms_get_template. Paged (default 50, at most 200). Read-only. Requires OAuth scope: read:comms (see motorical_whoami for what it allows).

PropertyValue
Needs scoperead:comms
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routeGET /comm-api/api/templates
BehaviourRead-only; safe to repeat
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
limitintegerNoHow many items to return (default 50, at most 200).
offsetintegerNoHow many items to skip, to read the next page (default 0).

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{}

comms_get_template​

One email template. One template in full: subject, HTML body, plain-text body, kind, description and the campaigns using it. Read-only. Requires OAuth scope: read:comms (see motorical_whoami for what it allows).

PropertyValue
Needs scoperead:comms
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routeGET /comm-api/api/templates/{id}
BehaviourRead-only; safe to repeat
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
idstring (uuid)YesThe template id.

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{"id":"<id>"}

comms_get_template_rules​

The template rulebook. The rulebook every template is held to, generated from the same constants the validator uses: size limits, removed merge tags, link rules and the closed vocabulary of lint findings and fix types. Read it before writing or repairing a template, and quote limits from it rather than from memory. Read-only. Requires OAuth scope: read:comms (see motorical_whoami for what it allows).

PropertyValue
Needs scoperead:comms
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routeGET /comm-api/api/templates/rules
BehaviourRead-only; safe to repeat
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{}

comms_lint_template​

Lint a template. Check a template against the rulebook. Give templateId for a saved template, or subject with bodyHtml/bodyText for an unsaved draft, never both (AMBIGUOUS_TEMPLATE) and never neither (MISSING_TEMPLATE). Returns findings from a closed vocabulary, each with a severity and a hint. Name every finding to the person before offering a fix. The result carries the workspace settings it was checked against; some findings depend on them (a consent link is live only in a consent-request campaign, a link straight to the unsubscribe landing page unsubscribes no one, click consent needs a tracked link). Requires OAuth scope: read:comms (see motorical_whoami for what it allows).

PropertyValue
Needs scoperead:comms
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routePOST /comm-api/api/templates/lint
BehaviourRead-only; safe to repeat
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
templateIdstring (uuid)NoA saved template. Give this OR the draft fields, never both.
subjectstringNoDraft subject (with bodyHtml and/or bodyText), when not using templateId.
bodyHtmlstringNoDraft HTML body.
bodyTextstringNoDraft plain-text body.

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{}

comms_suggest_template_fixes​

Suggest template fixes. The safe, deterministic fixes for a template, applied IN MEMORY: returns the new fields, what changed and the re-lint. Nothing is saved (applied is false); saving is a separate, later step. Same template-or-draft rule as comms_lint_template. Optional types narrows the fixes to some fix types from the rulebook. Show the person what would change. Requires OAuth scope: read:comms (see motorical_whoami for what it allows).

PropertyValue
Needs scoperead:comms
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routePOST /comm-api/api/templates/fix
BehaviourRead-only; safe to repeat
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
templateIdstring (uuid)NoA saved template. Give this OR the draft fields, never both.
subjectstringNoDraft subject (with bodyHtml and/or bodyText), when not using templateId.
bodyHtmlstringNoDraft HTML body.
bodyTextstringNoDraft plain-text body.
typesarray of stringNoOnly these fix types (names from the template rulebook). Omit for all safe fixes.

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{}

Check template links. Every link in a template with its tracking status and any problem. Same template-or-draft rule as comms_lint_template. Run it before scheduling: a link that cannot be tracked, or a merge tag inside a URL, is reported here. The unsubscribe section says where people end up after they unsubscribe (the workspace landing page or the shared page); the page itself is not opened from here, so tell the person to open it. Requires OAuth scope: read:comms (see motorical_whoami for what it allows).

PropertyValue
Needs scoperead:comms
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routePOST /comm-api/api/templates/check-links
BehaviourRead-only; safe to repeat
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
templateIdstring (uuid)NoA saved template. Give this OR the draft fields, never both.
subjectstringNoDraft subject (with bodyHtml and/or bodyText), when not using templateId.
bodyHtmlstringNoDraft HTML body.
bodyTextstringNoDraft plain-text body.

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{}

comms_preview_template​

Preview a template. What a recipient will see: the rendered HTML, the effective text version, the link table and how the greeting reads. Same template-or-draft rule as comms_lint_template. The preview uses sample data you give (name, email, identity_name), never a real contact. Check the greeting with and without a name: an empty merge tag reads "Hello ,". The result carries the workspace settings (click consent, open tracking, unsubscribe page) so you can say what a real send would add: with open tracking on a hidden tracking image is added, and the consent and unsubscribe links here are examples. Requires OAuth scope: read:comms (see motorical_whoami for what it allows).

PropertyValue
Needs scoperead:comms
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routePOST /comm-api/api/templates/preview
BehaviourRead-only; safe to repeat
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
templateIdstring (uuid)NoA saved template. Give this OR the draft fields, never both.
subjectstringNoDraft subject (with bodyHtml and/or bodyText), when not using templateId.
bodyHtmlstringNoDraft HTML body.
bodyTextstringNoDraft plain-text body.
sampleobjectNoSample recipient to fill the merge tags with. Omit for the default sample.

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{}

comms_list_starters​

Template starters. The ready-made template skeletons: key, name, what each is for and the brand-kit slots it fills. Pick one with the person, then build from it; do not invent a design from scratch when a starter fits. Read-only. Requires OAuth scope: read:comms (see motorical_whoami for what it allows).

PropertyValue
Needs scoperead:comms
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routeGET /comm-api/api/templates/starters
BehaviourRead-only; safe to repeat
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{}

comms_get_brand_kit​

The workspace brand kit. The workspace's brand kit: sender name, colours, logo, footer and address fields used by the starters. If it is empty, ask the person once and keep the answer for the conversation. Never invent a logo URL or legal text. Read-only. Requires OAuth scope: read:comms (see motorical_whoami for what it allows).

PropertyValue
Needs scoperead:comms
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routeGET /comm-api/api/settings/brand-kit
BehaviourRead-only; safe to repeat
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{}

comms_list_campaigns​

Campaigns. The workspace's campaigns, most recent first: name, status, template, scheduled time, sender and pacing. Status is a closed set; pacing.state says whether a send is running, waiting for a limit or finished. Paged (default 50, at most 200). Read-only. Requires OAuth scope: read:comms (see motorical_whoami for what it allows).

PropertyValue
Needs scoperead:comms
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routeGET /comm-api/api/campaigns
BehaviourRead-only; safe to repeat
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
limitintegerNoHow many items to return (default 50, at most 200).
offsetintegerNoHow many items to skip, to read the next page (default 0).

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{}

comms_get_campaign​

One campaign. One campaign: status, template, schedule and timezone, sender, pacing and the reason for its status, plus the workspace settings in force (click consent, open tracking, unsubscribe page). Poll this once to show that a send started; do not poll in a loop. Read-only. Requires OAuth scope: read:comms (see motorical_whoami for what it allows).

PropertyValue
Needs scoperead:comms
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routeGET /comm-api/api/campaigns/{id}
BehaviourRead-only; safe to repeat
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
idstring (uuid)YesThe campaign id.

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{"id":"<id>"}

comms_create_template​

Create an email template. Create a template. DRY RUN by default: checks the template against the rulebook and lints it, and returns what would be created; pass dryRun:false to save it. A description (what it is for) and a kind are required. Kinds: newsletter, promotion, announcement, welcome, reengagement, event, notice, test, other. Read comms_get_template_rules first and fix every finding before saving. The type (html or text) cannot be changed later. A retry of the same call never creates a second template. Never invent a logo URL, legal text or an address. Requires OAuth scope: write:comms.content (see motorical_whoami for what it allows).

PropertyValue
Needs scopewrite:comms.content
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routePOST /comm-api/api/templates
BehaviourChanges data
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
dryRunbooleanNoDefault true: validate and show exactly what would happen, and change nothing. Pass false to actually write.
namestringYes-
subjectstringYes-
typeone of html, textYes-
bodyHtmlstringNo-
bodyTextstringNo-
descriptionstringYesWhat this is for, in one to three sentences. Required.
kindone of newsletter, promotion, announcement, welcome, reengagement, event, notice, test, otherYesRequired.
derivedFromstring (uuid)NoThe template this one is a variation of, if any.
idempotencyKeystringNoOptional. Letters, digits and . _ : - (8 to 128). Omit it: a retry of the same call is made safe automatically. Pass a different one only to deliberately make a second copy.

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{"name":"<name>","subject":"<subject>","type":"html","description":"<description>","kind":"newsletter"}

comms_create_template_from_starter​

Create a template from a starter. Create a template from a ready-made starter, filled with the workspace brand kit. DRY RUN by default: renders the starter and returns it; pass dryRun:false to save it. Get the starter keys from comms_list_starters and check the brand kit with comms_get_brand_kit first. A description is required; kind defaults to the starter's. THE FOOTER: the footer says why the person gets the email, and only the customer knows that. ASK them why these people receive it (for example "You signed up at our shop") and pass it as the reason slot, or save it once as footer_text in the brand kit. With neither, the footer only says who sent the email, and the result carries a footer_reason_default warning: tell the customer and ask, do not invent a reason. The starter's own words are English; write slot text in the brand kit language. SETTINGS: the result carries a settings block with the workspace's click consent, open tracking and unsubscribe-page values; read it to the person, do not change them yourself, and use comms_get_workspace_settings to explain them. The consent block (includeConsentBlock) is an option the PERSON chooses. Requires OAuth scope: write:comms.content (see motorical_whoami for what it allows).

PropertyValue
Needs scopewrite:comms.content
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routePOST /comm-api/api/templates/from-starter
BehaviourChanges data
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
dryRunbooleanNoDefault true: validate and show exactly what would happen, and change nothing. Pass false to actually write.
starterstringYesA starter key from comms_list_starters.
namestringYes-
descriptionstringYesWhat this is for, in one to three sentences. Required.
kindone of newsletter, promotion, announcement, welcome, reengagement, event, notice, test, otherNo-
subjectstringNo-
slotsobject (key/value map)NoValues for the starter's slots (see comms_list_starters).
brandobjectNoA brand kit for this one template only; the stored kit is not changed.
includeConsentBlockbooleanNotrue adds a "please confirm you want to keep hearing from us" block with a button built on {{consent_url}}. Add it only if the person wants to ask for consent. That button is live only in a campaign created as a consent request (elsewhere it is an empty link); it works whether click consent is on or off.
idempotencyKeystringNoOptional. Letters, digits and . _ : - (8 to 128). Omit it: a retry of the same call is made safe automatically. Pass a different one only to deliberately make a second copy.

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{"starter":"<starter>","name":"<name>","description":"<description>"}

comms_update_template​

Edit an email template. Change a template's name, subject, bodies, description or kind. DRY RUN by default: shows exactly what would change (from/to), validates and lints the result, and returns expectedUpdatedAt. A real write (dryRun:false) must pass that expectedUpdatedAt; if the template changed meanwhile, nothing is written (STALE_TEMPLATE). The previous values are returned so the edit can be undone with another call. A campaign that is already scheduled or sending was compiled when it was scheduled and will NOT pick up the edit: the result says so in warnings. The type cannot be changed. Requires OAuth scope: write:comms.content (see motorical_whoami for what it allows).

PropertyValue
Needs scopewrite:comms.content
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routePATCH /comm-api/api/templates/{id}
BehaviourChanges data; safe to repeat
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
dryRunbooleanNoDefault true: validate and show exactly what would happen, and change nothing. Pass false to actually write.
idstring (uuid)YesThe template id.
namestringNo-
subjectstringNo-
bodyHtmlstringNo-
bodyTextstringNo-
descriptionstringNo-
kindone of newsletter, promotion, announcement, welcome, reengagement, event, notice, test, otherNo-
expectedUpdatedAtstringNoThe template's updated_at as you last read it (a dry run returns it as expectedUpdatedAt). Required for a real write; if the template changed since, nothing is written and STALE_TEMPLATE says what is there now.

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{"id":"<id>"}

comms_apply_template_fixes​

Apply the safe template fixes. Apply the rulebook's safe, deterministic fixes to a saved template. DRY RUN by default: returns what would change and the re-lint (the same as comms_suggest_template_fixes); pass dryRun:false with expectedUpdatedAt to save. The previous text is returned. If nothing needs fixing nothing is written. Show the person the changes before saving. Requires OAuth scope: write:comms.content (see motorical_whoami for what it allows).

PropertyValue
Needs scopewrite:comms.content
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routePOST /comm-api/api/templates/fix
BehaviourChanges data; safe to repeat
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
dryRunbooleanNoDefault true: validate and show exactly what would happen, and change nothing. Pass false to actually write.
idstring (uuid)YesThe template id.
typesarray of stringNoOnly these fix types (names from the template rulebook).
expectedUpdatedAtstringNoThe template's updated_at as you last read it (a dry run returns it as expectedUpdatedAt). Required for a real write; if the template changed since, nothing is written and STALE_TEMPLATE says what is there now.

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{"id":"<id>"}

comms_duplicate_template​

Duplicate an email template. Make a copy of a template named "<name> (copy)" that remembers its parent. DRY RUN by default. The safest way to change a template that campaigns use: edit the copy. A retry never makes a second copy; to deliberately make another, pass a different idempotencyKey. Requires OAuth scope: write:comms.content (see motorical_whoami for what it allows).

PropertyValue
Needs scopewrite:comms.content
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routePOST /comm-api/api/templates/{id}/duplicate
BehaviourChanges data
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
dryRunbooleanNoDefault true: validate and show exactly what would happen, and change nothing. Pass false to actually write.
idstring (uuid)YesThe template to copy.
idempotencyKeystringNoOptional. Letters, digits and . _ : - (8 to 128). Omit it: a retry of the same call is made safe automatically. Pass a different one only to deliberately make a second copy.

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{"id":"<id>"}

comms_set_brand_kit​

Change the workspace brand kit. Change the workspace brand kit used by the starters: sender name, postal address, logo (https), colours, font, button radius, footer, reply-to, tone, language, description. Partial: only the fields given change, null clears one. DRY RUN by default: returns the current kit and your patch. A real write returns the previous values of the fields it changed. Never invent a logo URL, an address or legal text: ask the person. Requires OAuth scope: write:comms.content (see motorical_whoami for what it allows).

PropertyValue
Needs scopewrite:comms.content
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routePATCH /comm-api/api/settings/brand-kit
BehaviourChanges data; safe to repeat
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
dryRunbooleanNoDefault true: validate and show exactly what would happen, and change nothing. Pass false to actually write.
brandKitobjectYesThe fields to change; anything not given is left alone, null clears a field, colours merge one by one.

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{"brandKit":{}}

comms_create_list​

Create a contact list (card only). Create an empty list with its card: name, a description of what the list is for, who is in it and where the contacts came from (no counts), a kind and an optional source label. DRY RUN by default: the API checks the card and returns it, nothing is stored; pass dryRun:false to create it. A weak description is refused (LIST_CARD_INVALID) with the findings. Kinds: subscribers, customers, leads, event, test, reengagement, other (derived and system_view are made by the system). This adds no contacts. Requires OAuth scope: write:comms.audience (see motorical_whoami for what it allows).

PropertyValue
Needs scopewrite:comms.audience
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routePOST /comm-api/api/lists
BehaviourChanges data
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
dryRunbooleanNoDefault true: validate and show exactly what would happen, and change nothing. Pass false to actually write.
namestringYes-
descriptionstringYesWhat this is for, in one to three sentences. Required.
kindone of subscribers, customers, leads, event, test, reengagement, otherYesRequired.
sourceLabelstringNoWhere the contacts came from, in a few words (for example "Shopify export 2026-10-20").
idempotencyKeystringNoOptional. Letters, digits and . _ : - (8 to 128). Omit it: a retry of the same call is made safe automatically. Pass a different one only to deliberately make a second copy.

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{"name":"<name>","description":"<description>","kind":"subscribers"}

comms_update_list​

Edit a list card. Change a list's card: name, description, kind or source label. It does not change who is on the list. DRY RUN by default: returns the card as it would be and the previous values; pass dryRun:false to save. A weak description is refused (LIST_CARD_INVALID). The previous values are returned so the change can be undone. Requires OAuth scope: write:comms.audience (see motorical_whoami for what it allows).

PropertyValue
Needs scopewrite:comms.audience
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routePATCH /comm-api/api/lists/{id}
BehaviourChanges data; safe to repeat
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
dryRunbooleanNoDefault true: validate and show exactly what would happen, and change nothing. Pass false to actually write.
idstring (uuid)YesThe list id.
namestringNo-
descriptionstringNo-
kindone of subscribers, customers, leads, event, test, reengagement, otherNo-
sourceLabelstringNo-

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{"id":"<id>"}

comms_list_list_contacts​

Contacts on a list (masked). The members of one list, paged: id, status, consent kind and source, and quality. Addresses are MASKED (j***@example.com) and names are initials only; phone numbers are never returned. Use the ids for comms_remove_from_list. To see real addresses the person opens the dashboard: do not try to get them. q searches by name or address. Counts come from this result. Requires OAuth scope: read:comms (see motorical_whoami for what it allows).

PropertyValue
Needs scoperead:comms
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routeGET /comm-api/api/lists/{id}/contacts
BehaviourRead-only; safe to repeat
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
idstring (uuid)YesThe list id.
qstringNo-
pageintegerNo-
pageSizeintegerNo-

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{"id":"<id>"}

comms_find_contact​

Find a contact by address (masked). Look up ONE contact by the exact address the person gave you: id, status (new, sent, delivered, engaged, bounced, unsubscribed, complained), suppression reason, consent kind and how many lists they are on. The address is returned masked. Not found means nobody in this workspace has that exact address. Use it before comms_unsubscribe_contact or comms_add_suppression. Requires OAuth scope: read:comms (see motorical_whoami for what it allows).

PropertyValue
Needs scoperead:comms
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routeGET /comm-api/api/recipients
BehaviourRead-only; safe to repeat
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
emailstringYesThe address the person typed. It is never echoed back: results show it masked.

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{"email":"<email>"}

comms_search_audience​

Search the whole audience (masked). Search EVERY contact in the workspace, not one list: by domain, status, engagement, consent, suppression, campaign, import batch, dates, or "on no list" / "not on these lists". Each row: id, masked address, initials, status, engagement, last activity, suppression reason, and which lists the person is on (up to 5, plus list_count). Paged (limit up to 100, offset; sort recent, email or activity); total says how many match. Addresses are always masked: to find one person by the full address they gave, use comms_find_contact. To count rather than list, use comms_audience_summary; to turn a filter into a list, comms_derive_list with operation filter. Requires OAuth scope: read:comms (see motorical_whoami for what it allows).

PropertyValue
Needs scoperead:comms
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routePOST /comm-api/api/recipients/search
BehaviourRead-only; safe to repeat
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
filterobjectNo-
limitintegerNo-
offsetintegerNo-
sortone of recent, email, activityNo-

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{}

comms_audience_summary​

Counts across the whole audience. Counts only, for the whole workspace or for a filter: total, by status, by consent, by engagement, the biggest domains, the biggest lists and how many people are on no list. No addresses at all. Use it to understand an audience before touching it, and to check an import or a derived list afterwards. Requires OAuth scope: read:comms (see motorical_whoami for what it allows).

PropertyValue
Needs scoperead:comms
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routePOST /comm-api/api/recipients/summary
BehaviourRead-only; safe to repeat
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
filterobjectNo-
topintegerNoHow many domains and lists to show (default 10).

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{}

comms_suppression_info​

Is this address suppressed, and why. Read the account-wide suppression list for ONE address the person gave you: suppressed or not, the reason (manual, complaint, unsubscribe, bounce...), where it came from and since when. The address is returned masked. A suppression applies to every workspace of the account. Adding one is comms_add_suppression; removing one is only possible in the dashboard. Requires OAuth scope: read:comms (see motorical_whoami for what it allows).

PropertyValue
Needs scoperead:comms
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routeGET /comm-api/api/suppressions/lookup
BehaviourRead-only; safe to repeat
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
emailstringYesThe address the person typed. It is never echoed back: results show it masked.

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{"email":"<email>"}

comms_import_contacts​

Import contacts into a list. Add up to 1001 contacts to a list from rows you were given. Clean messy rows yourself first. A bigger list, or a contact file, is not sent through chat: the person uploads it in the Motorical dashboard (Comm, Lists, the "Import Contacts (CSV)" card, on a computer), which keeps the file between them and Motorical. DRY RUN by default: every row gets its own outcome (created, added_existing, already_in_list, invalid, duplicate_in_request, rejected_unsafe, skipped_unsubscribed, skipped_bounced, skipped_inactive, skipped_suppressed) and nothing is written. People who unsubscribed, bounced or are suppressed in Motorical are never added back, but a new account does not know who opted out in the person's PREVIOUS tool: ask, and add those people with comms_add_suppression (or leave their rows out) BEFORE a real import. If consentConfirmed is false the contacts are still added with no consent recorded, and they can still be emailed (Motorical does not block a campaign on it): the person's answer is the only record of consent, so never pass true for people who did not agree. For many opt-outs (more than a handful) the person uses Comm, Suppressions, Bulk Import in the dashboard, not this tool. Safe to repeat. Show the person the summary first. BEFORE a real import you must ASK the person, in plain words, "Do these people know they will get your marketing email: did they sign up, or are they customers who agreed?", and pass their answer as consentConfirmed (true or false; never guess, never default). A sourceLabel (where the contacts came from) is required. Results show addresses masked. Requires OAuth scope: write:comms.audience (see motorical_whoami for what it allows).

PropertyValue
Needs scopewrite:comms.audience
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routePOST /comm-api/api/lists/{id}/contacts/bulk
BehaviourChanges data; safe to repeat
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
dryRunbooleanNoDefault true: validate and show exactly what would happen, and change nothing. Pass false to actually write.
listIdstring (uuid)YesThe list to add them to.
contactsarray of objectYes-
onExistingone of keep, updateNokeep (default): an existing contact's own values win; update: what you send wins.
sourceLabelstringYesWhere these contacts came from, in a few words. Required.
consentConfirmedbooleanNoThe person's answer to the consent question. Required for a real import.
batchIdstring (uuid)NoThe batchId an earlier call returned. Pass it to add this call to the SAME import, so one comms_undo_import takes back all of it (a big file sent in several calls).

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{"listId":"<listId>","contacts":[],"sourceLabel":"<sourceLabel>"}

comms_remove_from_list​

Remove contacts from a list. Take up to 100 contacts, by id, off ONE list. The contacts themselves are NOT deleted and stay on other lists; they can be added again. DRY RUN by default: names the list and how many ids it would try to remove. There is no "remove everyone matching" mode. Get the ids from comms_list_list_contacts. Requires OAuth scope: write:comms.audience (see motorical_whoami for what it allows).

PropertyValue
Needs scopewrite:comms.audience
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routePOST /comm-api/api/lists/{id}/contacts/bulk-remove
BehaviourChanges data; safe to repeat
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
dryRunbooleanNoDefault true: validate and show exactly what would happen, and change nothing. Pass false to actually write.
listIdstring (uuid)YesThe list.
contactIdsarray of stringYes-

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{"listId":"<listId>","contactIds":[]}

comms_derive_list​

Derive a list from other lists. Make a NEW list from other lists: union, intersection (needs two or more sources) or difference (sources minus excludeListIds), up to 10 sources. Or operation filter: a list of everyone in the workspace who matches a filter (the same filter as comms_search_audience: a domain, a status, a campaign, "on no list"...; give filter and no source lists, at least one filter key is required, at most 10000 people). Suppressed people are copied but stay ineligible, and the dry run counts them apart (would_be_eligible). The result is a one-time SNAPSHOT, not live; it records its sources. DRY RUN by default: returns the counts and creates nothing. A description is required. Only active, not-suppressed members are copied. A retry never creates a second list. Requires OAuth scope: write:comms.audience (see motorical_whoami for what it allows).

PropertyValue
Needs scopewrite:comms.audience
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routePOST /comm-api/api/lists/derive
BehaviourChanges data
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
dryRunbooleanNoDefault true: validate and show exactly what would happen, and change nothing. Pass false to actually write.
namestringYes-
descriptionstringYesWhat the list is for. Required.
operationone of union, intersection, difference, filterYes-
sourceListIdsarray of stringNo-
excludeListIdsarray of stringNo-
filterobjectNoOnly with operation filter.
sourceLabelstringNo-
idempotencyKeystringNoOptional. Letters, digits and . _ : - (8 to 128). Omit it: a retry of the same call is made safe automatically. Pass a different one only to deliberately make a second copy.

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{"name":"<name>","description":"<description>","operation":"union"}

comms_unsubscribe_contact​

Unsubscribe a contact. Honour a request to stop emailing one person, found by the exact address they gave. DRY RUN by default: shows the contact (masked) and its status. Do the dry run, tell the person who you found, and get a clear yes in chat BEFORE dryRun:false. You cannot undo it from here: there is no resubscribe tool, because only the person (or the account owner in the dashboard) may opt someone back in. Someone already unsubscribed, bounced or complained is reported as no change. Requires OAuth scope: write:comms.audience (see motorical_whoami for what it allows).

PropertyValue
Needs scopewrite:comms.audience
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routePOST /comm-api/api/contacts/{id}/unsubscribe
BehaviourChanges data; safe to repeat
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
dryRunbooleanNoDefault true: validate and show exactly what would happen, and change nothing. Pass false to actually write.
emailstringYesThe address the person typed. It is never echoed back: results show it masked.

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{"email":"<email>"}

comms_add_suppression​

Suppress an address. Stop all marketing email to an address. The suppression is ACCOUNT-WIDE: it applies to every workspace of this account, not just this one. Reasons: manual (the person asked), complaint (they reported spam), unsubscribe. Bounces are recorded automatically. DRY RUN by default: says what would be added, and the contact (masked) if there is one. One address at a time: for many addresses (for example a previous tool's unsubscribed list) the person uses Comm, Suppressions, Bulk Import in the dashboard instead. Get the person's clear yes in chat BEFORE dryRun:false. It cannot be removed from here; only the account owner can, in the dashboard. Requires OAuth scope: write:comms.audience (see motorical_whoami for what it allows).

PropertyValue
Needs scopewrite:comms.audience
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routePOST /comm-api/api/suppressions
BehaviourChanges data; safe to repeat
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
dryRunbooleanNoDefault true: validate and show exactly what would happen, and change nothing. Pass false to actually write.
emailstringYesThe address the person typed. It is never echoed back: results show it masked.
reasonone of manual, complaint, unsubscribeYes-

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{"email":"<email>","reason":"manual"}

comms_add_suppressions​

Suppress many addresses. Stop all marketing email to up to 200 addresses at once, for example the people who opted out in the person's PREVIOUS tool: do this BEFORE importing their list. ACCOUNT-WIDE, like comms_add_suppression, and it cannot be removed from here. DRY RUN by default: counts the addresses and shows a masked sample, writes nothing. More than 200: call again with the next 200. Get the person's clear yes in chat BEFORE dryRun:false. Addresses are never echoed back. Requires OAuth scope: write:comms.audience (see motorical_whoami for what it allows).

PropertyValue
Needs scopewrite:comms.audience
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routePOST /comm-api/api/suppressions/bulk
BehaviourChanges data; safe to repeat
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
dryRunbooleanNoDefault true: validate and show exactly what would happen, and change nothing. Pass false to actually write.
emailsarray of stringYes-
reasonone of manual, complaint, unsubscribeYes-

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{"emails":[],"reason":"manual"}

comms_list_imports​

Imports into a list. The recent imports into one list: batchId, source, when, how many contacts it created, how many existing contacts it only added, and whether it was undone. Use the batchId with comms_undo_import. Only imports made with comms_import_contacts or the JSON import API have a batch; a CSV import from the dashboard does not. Requires OAuth scope: read:comms (see motorical_whoami for what it allows).

PropertyValue
Needs scoperead:comms
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routeGET /comm-api/api/lists/{id}/imports
BehaviourRead-only; safe to repeat
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
listIdstring (uuid)YesThe list.

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{"listId":"<listId>"}

comms_undo_import​

Undo an import. Take back one import: the batch's people leave the list, and the contacts the import CREATED that are now on no list are erased. People who already existed are only taken off this list, not erased. Anyone who has unsubscribed, bounced or is suppressed since is kept. DRY RUN by default: says how many would leave the list and how many contacts would be erased. A batch can be undone once. Show the person the numbers and get a clear yes BEFORE dryRun:false. Requires OAuth scope: write:comms.audience (see motorical_whoami for what it allows).

PropertyValue
Needs scopewrite:comms.audience
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routePOST /comm-api/api/lists/{id}/imports/{batchId}/undo
BehaviourChanges data; safe to repeat
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
dryRunbooleanNoDefault true: validate and show exactly what would happen, and change nothing. Pass false to actually write.
listIdstring (uuid)YesThe list.
batchIdstring (uuid)YesThe batchId from comms_list_imports or from the import result.

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{"listId":"<listId>","batchId":"<batchId>"}

comms_set_list_archived​

Archive or restore a list. Put a list away without deleting it, or bring it back (archived:false, POST /comm-api/api/lists/{id}/unarchive). An archived list is hidden from comms_list_lists unless you ask for it and cannot be sent to; nothing else changes and no contact is touched. A list a campaign sends to or excludes cannot be archived. DRY RUN by default. Prefer this to deleting when the person is not sure. Requires OAuth scope: write:comms.audience (see motorical_whoami for what it allows).

PropertyValue
Needs scopewrite:comms.audience
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routePOST /comm-api/api/lists/{id}/archive
BehaviourChanges data; safe to repeat
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
dryRunbooleanNoDefault true: validate and show exactly what would happen, and change nothing. Pass false to actually write.
listIdstring (uuid)YesThe list.
archivedbooleanYestrue to archive, false to restore.

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{"listId":"<listId>","archived":true}

comms_delete_list​

Delete a list. Delete one list for good. Needs the manage:comms.audience permission, which the person adds in the dashboard. A list is only a set of memberships, so you must also say what happens to the people on it: contacts=delete_orphans erases the contacts that are on no other list (people who unsubscribed, bounced or are suppressed are ALWAYS kept, so they cannot be mailed again by a later import); contacts=keep leaves every contact in the workspace. DRY RUN by default and it reports exactly how many people each choice affects. ASK the person which they want ("also delete the people who are on no other list?"), show the numbers, and pass their answer as contacts on the real call: it is required and never defaulted. A list a draft, scheduled or sending campaign sends to, or any campaign excludes, cannot be deleted. Cannot be undone. Requires OAuth scope: manage:comms.audience (see motorical_whoami for what it allows).

PropertyValue
Needs scopemanage:comms.audience
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routeDELETE /comm-api/api/lists/{id}
BehaviourDestructive: asks the person to confirm; safe to repeat
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
dryRunbooleanNoDefault true: validate and show exactly what would happen, and change nothing. Pass false to actually write.
listIdstring (uuid)YesThe list.
contactsone of keep, delete_orphansNodelete_orphans or keep. Required for a real delete; the person's answer.

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{"listId":"<listId>"}

comms_cleanup_orphan_contacts​

Clean up contacts on no list. Erase the contacts that are on no list at all, for example people left behind when lists were deleted earlier. Needs manage:comms.audience. People who unsubscribed, bounced or are suppressed are never erased. DRY RUN by default: says how many are on no list and how many would be erased. Show the person the numbers and get a clear yes BEFORE dryRun:false. Cannot be undone. Requires OAuth scope: manage:comms.audience (see motorical_whoami for what it allows).

PropertyValue
Needs scopemanage:comms.audience
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routePOST /comm-api/api/contacts/cleanup-orphans
BehaviourDestructive: asks the person to confirm; safe to repeat
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
dryRunbooleanNoDefault true: validate and show exactly what would happen, and change nothing. Pass false to actually write.

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{}

comms_delete_contact​

Erase one contact. Erase ONE person from the workspace, found by the exact address they gave: the right to erasure. Needs manage:comms.audience. They leave every list; campaign statistics stay but are no longer linked to them. If they unsubscribed or are suppressed, the suppression stays, so they are not mailed again. DRY RUN by default: shows the contact (masked) and how many lists they are on. Tell the person who you found and get a clear yes BEFORE dryRun:false. Cannot be undone. Requires OAuth scope: manage:comms.audience (see motorical_whoami for what it allows).

PropertyValue
Needs scopemanage:comms.audience
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routeDELETE /comm-api/api/contacts/{id}
BehaviourDestructive: asks the person to confirm; safe to repeat
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
dryRunbooleanNoDefault true: validate and show exactly what would happen, and change nothing. Pass false to actually write.
emailstringYesThe address the person typed. It is never echoed back: results show it masked.

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{"email":"<email>"}

comms_delete_campaign​

Delete a campaign (recycle bin). Move a campaign to the recycle bin. Nothing is erased: the person can restore it in the dashboard. A campaign that is scheduled or sending is REFUSED: cancel it first with comms_cancel_campaign, which needs its own permission. Needs manage:comms.audience, like every delete. DRY RUN by default: names the campaign and its status. Show the person which one and get a clear yes BEFORE dryRun:false. Requires OAuth scope: manage:comms.audience (see motorical_whoami for what it allows).

PropertyValue
Needs scopemanage:comms.audience
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routeDELETE /comm-api/api/campaigns/{id}
BehaviourDestructive: asks the person to confirm; safe to repeat
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
dryRunbooleanNoDefault true: validate and show exactly what would happen, and change nothing. Pass false to actually write.
idstring (uuid)YesThe campaign id.

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{"id":"<id>"}

comms_delete_template​

Delete a template. Delete ONE template for good. Needs manage:comms.audience. A template that any campaign uses (even a finished or deleted one) is REFUSED with the campaigns named: delete or change those first. DRY RUN by default: names the template and says whether it can go. Show the person which one and get a clear yes BEFORE dryRun:false. Cannot be undone: if they may want it back, comms_duplicate_template first. To clear out test drafts, use this once per template. Requires OAuth scope: manage:comms.audience (see motorical_whoami for what it allows).

PropertyValue
Needs scopemanage:comms.audience
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routeDELETE /comm-api/api/templates/{id}
BehaviourDestructive: asks the person to confirm; safe to repeat
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
dryRunbooleanNoDefault true: validate and show exactly what would happen, and change nothing. Pass false to actually write.
idstring (uuid)YesThe template id.

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{"id":"<id>"}

comms_resubscribe_contact​

Opt a contact back in. Opt a person who unsubscribed back in, found by the exact address. Needs manage:comms.audience. Only do this when the PERSON asked to be emailed again; the account owner's wish to mail them is not a reason. Someone who reported your mail as spam cannot be opted back in from here. DRY RUN by default: shows the contact (masked) and its status. Get the person's clear yes, and ask how the contact asked to be re-subscribed, BEFORE dryRun:false. Requires OAuth scope: manage:comms.audience (see motorical_whoami for what it allows).

PropertyValue
Needs scopemanage:comms.audience
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routePUT /comm-api/api/contacts/{id}/resubscribe
BehaviourChanges data; safe to repeat
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
dryRunbooleanNoDefault true: validate and show exactly what would happen, and change nothing. Pass false to actually write.
emailstringYesThe address the person typed. It is never echoed back: results show it masked.

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{"email":"<email>"}

Where to do it in the dashboard. For the few things that must stay between the person and Motorical, not pass through chat: uploading a large contact file (import_csv), exporting a list (export_list: real addresses are never given to an agent) and many opt-outs (bulk_suppressions, if more than a few hundred). Returns the exact steps and the dashboard address to give the person. Calls no API and reads nothing. Requires OAuth scope: read:comms (see motorical_whoami for what it allows).

PropertyValue
Needs scoperead:comms
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routeNone
BehaviourRead-only; safe to repeat
InputTypeRequiredMeaning
purposeone of import_csv, export_list, bulk_suppressionsYes-

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{"purpose":"import_csv"}

comms_create_campaign​

Create a campaign draft. Create a campaign as a DRAFT: a name, a template, the marketing Motor Block it sends through, the lists it goes to and optionally lists to exclude. DRY RUN by default: the API runs every check (the template and lists belong to this workspace, the Motor Block is assigned, the From address is on its verified domain, no list is both sent to and excluded) and returns the would-be draft; nothing is stored. Pass dryRun:false to create it. A real create makes a draft only: it is NOT scheduled and nothing is sent. Get ids from comms_list_templates, comms_list_lists and comms_list_marketing_blocks. A description is required. A retry never makes a second draft. Requires OAuth scope: write:comms.content (see motorical_whoami for what it allows).

PropertyValue
Needs scopewrite:comms.content
Available onHosted servers: main, communications only (no local server)
Acts onOne Motor Block (the motorBlockId input)
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routePOST /comm-api/api/campaigns
BehaviourChanges data
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
dryRunbooleanNoDefault true: validate and show exactly what would happen, and change nothing. Pass false to actually write.
namestringYes-
templateIdstring (uuid)YesThe template to send.
motorBlockIdstring (uuid)YesThe marketing Motor Block it sends through (comms_list_marketing_blocks).
listIdsarray of stringYesThe lists it goes to.
excludeListIdsarray of stringNoLists whose members must NOT receive it. A list cannot be in both.
descriptionstringYesWhat this campaign is for, in one to three sentences. Required.
fromAddressstringNoMust be on the Motor Block's verified domain; omit for the default (noreply@ that domain).
fromNamestringNo-
replyTostringNo-
idempotencyKeystringNoOptional. Letters, digits and . _ : - (8 to 128). Omit it: a retry of the same call is made safe automatically. Pass a different one only to deliberately make a second copy.

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{"name":"<name>","templateId":"<templateId>","motorBlockId":"<motorBlockId>","listIds":[],"description":"<description>"}

comms_update_campaign​

Edit a campaign draft. Change a campaign DRAFT: its From address, From name, reply-to, description, template, lists and excluded lists (null clears a name, a reply-to or the exclusions). DRY RUN by default: the API checks everything and returns what would change and what it is now. A real write (dryRun:false) returns the previous values so it can be undone. Only a draft can have its template, lists or sender changed: a scheduled, sending or finished campaign answers INVALID_STATE. This tool cannot set a send time, a timezone or pacing, and cannot schedule. Requires OAuth scope: write:comms.content (see motorical_whoami for what it allows).

PropertyValue
Needs scopewrite:comms.content
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routePATCH /comm-api/api/campaigns/{id}/settings
BehaviourChanges data; safe to repeat
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
dryRunbooleanNoDefault true: validate and show exactly what would happen, and change nothing. Pass false to actually write.
idstring (uuid)YesThe campaign id.
fromAddressstringNo-
fromNamestringNo-
replyTostringNo-
descriptionstringNoWhat this campaign is for, in one to three sentences. Required.
templateIdstring (uuid)No-
listIdsarray of stringNo-
excludeListIdsarray of stringNo-

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{"id":"<id>"}

comms_duplicate_campaign​

Duplicate a campaign into a new draft. Copy any campaign (draft, scheduled, finished or cancelled) into a NEW draft with the same template, lists, Motor Block, From and tracking (POST /comm-api/api/campaigns/{id}/duplicate). Nothing of the old run is carried over: no schedule, no recipients, no history. DRY RUN by default: names the copy. This is how a finished campaign is sent again, and how a changed version of a scheduled one is made. A retry never makes a second copy; to deliberately make another, pass a different idempotencyKey. Requires OAuth scope: write:comms.content (see motorical_whoami for what it allows).

PropertyValue
Needs scopewrite:comms.content
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routePOST /comm-api/api/campaigns/{id}/duplicate
BehaviourChanges data
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
dryRunbooleanNoDefault true: validate and show exactly what would happen, and change nothing. Pass false to actually write.
idstring (uuid)YesThe campaign to copy.
idempotencyKeystringNoOptional. Letters, digits and . _ : - (8 to 128). Omit it: a retry of the same call is made safe automatically. Pass a different one only to deliberately make a second copy.

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{"id":"<id>"}

comms_preflight_campaign​

Preflight a campaign. The check to run and SHOW before anyone says a campaign is ready. Nothing is sent. It compiles a snapshot of the audience and content, stored as a numbered version, and returns who would receive it (totalRecipients and an audience breakdown of who is in and why others are out), a forecast and warnings. State the numbers exactly as returned, with the version and time. Read the warnings first and mention every one. The result has a settings block (click counts as consent, open tracking, the unsubscribe page, each with where it comes from): say them in plain words, explain with comms_get_workspace_settings if asked, and remember they are workspace settings the person decides, never yours to change. hasRecipients false means NOT ready: no one would receive it, and the audience breakdown says why. The forecast is an estimate that assumes no other traffic. Any later change to the template, lists or settings makes it stale: run it again before scheduling. Requires OAuth scope: write:comms.content (see motorical_whoami for what it allows).

PropertyValue
Needs scopewrite:comms.content
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routePOST /comm-api/api/campaigns/{id}/compile
BehaviourChanges data; safe to repeat
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
idstring (uuid)YesThe campaign id.

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{"id":"<id>"}

comms_send_test​

Send a test email to the account owner. Send ONE test copy of a campaign to the ACCOUNT OWNER ONLY. There is no recipient input: it always goes to the account owner's own verified address, never to anyone else, and the address is shown masked. DRY RUN by default: says what would be sent (sender, subject) and sends nothing. Pass dryRun:false to send it; tell the person to check their own inbox. It is not a send to anyone else and is not a way to preview for a colleague. It is rate limited: a refusal comes with its wait time (retryAfter, in seconds); report it and do not retry in a loop. The optional sample fills the merge tags (name, identity_name) for the preview. Requires OAuth scope: write:comms.content (see motorical_whoami for what it allows).

PropertyValue
Needs scopewrite:comms.content
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routePOST /comm-api/api/campaigns/{id}/test-send
BehaviourChanges data
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
dryRunbooleanNoDefault true: validate and show exactly what would happen, and change nothing. Pass false to actually write.
idstring (uuid)YesThe campaign id.
sampleobjectNoSample first name for the merge tags.

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{"id":"<id>"}

comms_send_template_test​

Send a template test to the account owner. Send ONE test copy of a TEMPLATE to the ACCOUNT OWNER ONLY, so a design can be checked before any campaign, list or schedule exists. Same rules as comms_send_test: no recipient input, it goes to the owner's own verified address (shown masked), it is marked [TEST], nothing is stored, and it is rate limited (a refusal comes with retryAfter). It needs a campaign Motor Block of this workspace to send through (motorBlockId, from comms_list_marketing_blocks); its sending domain is the From address. DRY RUN by default. In the copy the unsubscribe and consent links are placeholders that point to motorical.com and links are not tracked: that is expected, not a fault, and the result says so. The result also carries the workspace settings that apply to real sends. Check real links with comms_check_links. Requires OAuth scope: write:comms.content (see motorical_whoami for what it allows).

PropertyValue
Needs scopewrite:comms.content
Available onHosted servers: main, communications only (no local server)
Acts onOne Motor Block (the motorBlockId input)
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routePOST /comm-api/api/templates/{id}/test-send
BehaviourChanges data
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
dryRunbooleanNoDefault true: validate and show exactly what would happen, and change nothing. Pass false to actually write.
idstring (uuid)YesThe template id.
motorBlockIdstring (uuid)YesA campaign Motor Block of this workspace to send the test through (comms_list_marketing_blocks).
sampleobjectNoSample first name for the merge tags.

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{"id":"<id>","motorBlockId":"<motorBlockId>"}

comms_schedule_campaign​

Schedule a campaign (this emails people). Schedule a campaign draft to be SENT to its audience at a time. This is what actually emails people. PROCEDURE, in this order: (1) run comms_preflight_campaign and show the person its numbers; (2) call this tool WITHOUT dryRun:false to get a DRY RUN: a summary of the campaign, the subject, the sender, exactly how many people, the send time in the person's timezone with the weekday and in UTC, every warning, the settings sentence (click counts as consent, open tracking, where people go after unsubscribing) and a confirmToken; (3) read that summary to the person and get a clear YES to exactly that summary; (4) only then call again with the same arguments plus dryRun:false, confirm:true and the confirmToken. Never pass confirm:true or a token the person has not just seen the summary for. If anything changed since the preview (the numbers, the time, the template, a workspace setting) the token is refused: preview again and show the new numbers. Give the time as sendAtLocal (for example 2026-11-06T09:00) WITH its IANA timezone (for example Europe/Riga), or as sendAtUtc; ask the person for the timezone, never assume it. There is no sending now: the time must be at least 15 minutes ahead and at most 90 days. preflightVersion is the version comms_preflight_campaign returned; it must still describe exactly what would be sent and be less than 30 minutes old. A connection can schedule at most 50 campaigns a day (a runaway guard, not a working limit), and the account owner is emailed about every one. Cancel with comms_cancel_campaign. Requires OAuth scope: send:comms.campaign (see motorical_whoami for what it allows).

PropertyValue
Needs scopesend:comms.campaign
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routePOST /comm-api/api/campaigns/{id}/schedule
BehaviourDestructive: asks the person to confirm
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
dryRunbooleanNoDefault true: validate and show exactly what would happen, and change nothing. Pass false to actually write.
idstring (uuid)YesThe campaign id.
preflightVersionintegerYesThe version returned by comms_preflight_campaign for this campaign.
sendAtLocalstringNoLocal date and time, YYYY-MM-DDTHH:MM, with no offset. Needs timezone.
timezonestringNoIANA timezone the local time is in, for example Europe/Riga.
sendAtUtcstringNoInstead of sendAtLocal: a full UTC timestamp with Z or an offset.
confirmbooleanNotrue only after the person said yes to the summary of the dry run.
confirmTokenstringNoThe confirmToken from the matching dry run.

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{"id":"<id>","preflightVersion":1}

comms_cancel_campaign​

Cancel a campaign (final). Cancel a draft, scheduled or sending campaign. Cancelling is FINAL: the campaign can never be restarted; to send it again, duplicate it (comms_duplicate_campaign) and schedule the copy. It stops anything not yet sent; mail already sent cannot be recalled. Use it at once when the person says to stop. Pass confirm:true after the person has said to cancel. The account owner is emailed. Requires OAuth scope: send:comms.campaign (see motorical_whoami for what it allows).

PropertyValue
Needs scopesend:comms.campaign
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routePOST /comm-api/api/campaigns/{id}/cancel
BehaviourDestructive: asks the person to confirm; safe to repeat
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
idstring (uuid)YesThe campaign id.
confirmbooleanNotrue after the person has said to cancel it.

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{"id":"<id>"}

comms_get_campaign_report​

How a campaign did. The result of one campaign: handed off, accepted, delivered, bounced, failed, complained, opened and clicked, per recipient, with rates and the denominator of each, the time the numbers are from, and whether delivery outcomes are still syncing. The plain array has the same numbers as sentences with the denominators written out; quote those. Open counts are ESTIMATES (Apple Mail Privacy Protection and the Gmail image proxy inflate them): always say so when you quote one, and prefer clicks. With open tracking off the open numbers are null (unknown, not zero): never quote an open rate then. The plain array also says how many people were recorded as consenting because of this campaign (and how: the confirm button or a click) and how many unsubscribed, each out of delivered. A campaign that has not sent returns sent:false and no rates; say there is no data yet. Read-only. Requires OAuth scope: read:comms (see motorical_whoami for what it allows).

PropertyValue
Needs scoperead:comms
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routeGET /comm-api/api/campaigns/{id}/report
BehaviourRead-only; safe to repeat
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
idstring (uuid)YesThe campaign id.

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{"id":"<id>"}

Which links were clicked. Clicks per link for one campaign: total and unique clicks, most clicked first. The query string and fragment of every link are replaced with ... because they can carry personal tokens; the path is enough to tell links apart. Read-only. Requires OAuth scope: read:comms (see motorical_whoami for what it allows).

PropertyValue
Needs scoperead:comms
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routeGET /comm-api/api/campaigns/{id}/click-breakdown
BehaviourRead-only; safe to repeat
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
idstring (uuid)YesThe campaign id.

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{"id":"<id>"}

comms_get_campaign_timeline​

A campaign day by day. A campaign activity per day for the last days: a summary, a daily breakdown and the 25 most recent events. Recipient addresses in the recent events are masked (j***@example.com). days is 1 to 30, default 7. Use it to answer "when did people open?" or "is it still moving?". Read-only. Requires OAuth scope: read:comms (see motorical_whoami for what it allows).

PropertyValue
Needs scoperead:comms
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routeGET /comm-api/api/campaigns/{id}/analytics
BehaviourRead-only; safe to repeat
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
idstring (uuid)YesThe campaign id.
daysintegerNoHow many days back (1 to 30, default 7).

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{"id":"<id>"}

comms_list_campaign_events​

Campaign events. Individual events of one campaign, newest first, at most 50 per page: type, time and the contact as an id. Never an address, an IP address or a user agent. Use it only to answer a specific question (for example the bounces); for the overall result use comms_get_campaign_report. Filter with type; read the next page with page. Read-only. Requires OAuth scope: read:comms (see motorical_whoami for what it allows).

PropertyValue
Needs scoperead:comms
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routeGET /comm-api/api/campaigns/{id}/events
BehaviourRead-only; safe to repeat
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
idstring (uuid)YesThe campaign id.
typeone of queued, sending, sent, delivered, bounced, complained, failed, blocked, opened, clicked, unsubscribedNoOnly events of this type.
pageintegerNoPage number, starting at 1 (default 1).
pageSizeintegerNoEvents per page (default 50, at most 50).

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{"id":"<id>"}

comms_get_analytics_overview​

Results across all campaigns. The workspace event totals and its top campaigns for the last days: events by type with the number of campaigns and unique recipients, and the ten campaigns with the most clicks. days is 1 to 365, default 30. Open counts are estimates. For one campaign use comms_get_campaign_report. Read-only. Requires OAuth scope: read:comms (see motorical_whoami for what it allows).

PropertyValue
Needs scoperead:comms
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routeGET /comm-api/api/analytics/overview
BehaviourRead-only; safe to repeat
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
daysintegerNoHow many days back (1 to 365, default 30).

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{}

comms_get_workspace_settings​

Workspace settings. The three settings of one workspace, each with a plain explanation: whether a click counts as consent (click_consent_enabled), whether opens are tracked (open_tracking_enabled), and the page recipients land on after unsubscribing (unsubscribe_landing_url, or null for the default). They are workspace settings: they apply to every campaign and a campaign cannot override them. The person decides each one; never change one on your own. Read this before drafting templates or campaigns, and use the explanations (what it does, what recipients experience, what the person decides) when you talk about them. Note that click consent is separate from a consent-request campaign (the {{consent_url}} button), which works whether click consent is on or off. Read-only. Requires OAuth scope: read:comms (see motorical_whoami for what it allows).

PropertyValue
Needs scoperead:comms
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routeGET /comm-api/api/workspaces/{id}/settings
BehaviourRead-only; safe to repeat
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{}

comms_list_webhooks​

Webhooks. The webhooks of one workspace: id, where it sends (host only; the path and query string are hidden because they can hold a token), the events it listens to, whether it is enabled, how many deliveries failed in a row and the status of the last one. Never a signing secret. Read-only. Requires OAuth scope: read:comms (see motorical_whoami for what it allows).

PropertyValue
Needs scoperead:comms
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routeGET /comm-api/api/workspaces/{id}/webhooks
BehaviourRead-only; safe to repeat
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{}

comms_create_workspace​

Create a workspace. Create an additional marketing workspace. Most customers need only their default workspace: create one only when the person asks to keep a brand, client or sender separate. DRY RUN by default. A name that already exists is reported, not created again (so a retry is safe). The account owner is emailed when an assistant creates a workspace. A new workspace has no sending identity: give it one with comms_add_sending_identity (needs a verified domain). Requires OAuth scope: manage:comms.workspace (see motorical_whoami for what it allows).

PropertyValue
Needs scopemanage:comms.workspace
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routePOST /comm-api/api/workspaces
BehaviourChanges data
InputTypeRequiredMeaning
dryRunbooleanNoDefault true: validate and show exactly what would happen, and change nothing. Pass false to actually write.
namestringYesThe workspace name, for example the brand or client.
slugstringNoOptional URL-safe short name.

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{"name":"<name>"}

comms_update_workspace​

Rename a workspace. Rename a workspace or change its short name. DRY RUN by default: shows the previous and new values. Making a workspace the default is not possible here: only a person can do that in the dashboard. Requires OAuth scope: manage:comms.workspace (see motorical_whoami for what it allows).

PropertyValue
Needs scopemanage:comms.workspace
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routePATCH /comm-api/api/workspaces/{id}
BehaviourChanges data; safe to repeat
InputTypeRequiredMeaning
dryRunbooleanNoDefault true: validate and show exactly what would happen, and change nothing. Pass false to actually write.
idstring (uuid)YesThe workspace id.
namestringNo-
slugstringNo-

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{"id":"<id>"}

comms_update_workspace_settings​

Change workspace settings. Change the settings of one workspace: clickConsentEnabled (a click on a campaign link counts as the recipient giving consent), openTracking (whether opens are tracked) and unsubscribeLandingUrl (the https page recipients are sent to after they confirm an unsubscribe; null restores the default). DRY RUN by default: shows each setting from and to, with its plain explanation. Show the person every change and what it means for their recipients, and get a clear yes before dryRun:false; click consent in particular affects how consent is recorded for the people you email. A change voids any preflight made before it: preflight again before scheduling. Only the settings you pass are touched; ones already at that value are left alone. Requires OAuth scope: manage:comms.workspace (see motorical_whoami for what it allows).

PropertyValue
Needs scopemanage:comms.workspace
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routePATCH /comm-api/api/workspaces/{id}/settings/consent
BehaviourChanges data; safe to repeat
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
dryRunbooleanNoDefault true: validate and show exactly what would happen, and change nothing. Pass false to actually write.
clickConsentEnabledbooleanNotrue: a click counts as consent. false: it does not.
openTrackingbooleanNoTrack opens, or not.
unsubscribeLandingUrlstringNoAn https address on a domain the account owns, or null for the default page.

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{}

comms_add_sending_identity​

Add a sending identity to a workspace. Give a workspace the marketing sending identity of a verified domain: finds or creates the sending identity (a marketing Motor Block) for that domain and ADDS it to the workspace. It never replaces or removes anything. The domain must be the account's own and verified (DOMAIN_NOT_VERIFIED otherwise; add and verify domains with the domain tools). DRY RUN by default. Campaigns of that workspace can then send from addresses on the domain. Requires OAuth scope: manage:comms.workspace (see motorical_whoami for what it allows).

PropertyValue
Needs scopemanage:comms.workspace
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routePOST /comm-api/api/workspaces/{id}/motor-blocks/add
BehaviourChanges data; safe to repeat
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
dryRunbooleanNoDefault true: validate and show exactly what would happen, and change nothing. Pass false to actually write.
domainIdstring (uuid)YesThe id of a verified domain of this account.
namestringNoOptional name for a newly created sending identity.

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{"domainId":"<domainId>"}

comms_update_webhook​

Change a webhook. Change a webhook: its events, whether it is enabled, or where it sends (url, https only). DRY RUN by default. CHANGING WHERE IT SENDS is guarded: campaign events carry recipient email addresses (unsubscribes, consent, bounces, deliveries), so the dry run names the old and new host, warns, and returns a confirmToken; after the person has said yes to that, call again with the same arguments plus dryRun:false, confirm:true and the token. The account owner is emailed about every address change, and if they cannot be emailed the change is refused. Events and pausing need only the dry run and the person's yes. You cannot create a webhook (its signing secret is shown once, to a person, in the dashboard) and you never see a secret. Requires OAuth scope: manage:comms.webhooks (see motorical_whoami for what it allows).

PropertyValue
Needs scopemanage:comms.webhooks
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routePATCH /comm-api/api/workspaces/{id}/webhooks/{wid}
BehaviourChanges data; safe to repeat
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
dryRunbooleanNoDefault true: validate and show exactly what would happen, and change nothing. Pass false to actually write.
webhookIdstring (uuid)YesThe webhook id (from comms_list_webhooks).
eventsarray of one of campaign.completed, message.delivered, message.bounced, message.complained, contact.unsubscribed, contact.consent_givenNoThe events it listens to (replaces the current list).
enabledbooleanNofalse pauses it, true resumes it.
urlstringNoA new https address to send to. Needs the confirmed preview.
confirmbooleanNotrue only after the person has said yes to what the dry run showed.
confirmTokenstringNoThe confirmToken from the matching dry run (address changes only).

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{"webhookId":"<webhookId>"}

comms_delete_webhook​

Delete a webhook (final). Delete a webhook for good. It cannot be undone and its signing secret cannot be recovered: re-creating it is done by a person in the dashboard. To stop events without losing it, pause it with comms_update_webhook (enabled:false). DRY RUN by default; the real call needs dryRun:false and confirm:true after a clear yes. Requires OAuth scope: manage:comms.webhooks (see motorical_whoami for what it allows).

PropertyValue
Needs scopemanage:comms.webhooks
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routeDELETE /comm-api/api/workspaces/{id}/webhooks/{wid}
BehaviourDestructive: asks the person to confirm; safe to repeat
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
dryRunbooleanNoDefault true: validate and show exactly what would happen, and change nothing. Pass false to actually write.
webhookIdstring (uuid)YesThe webhook id.
confirmbooleanNotrue only after the person has said yes to what the dry run showed.

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{"webhookId":"<webhookId>"}

comms_test_webhook​

Send a test event to a webhook. Queue one test event to a webhook. The event carries no personal data. DRY RUN by default. It is limited per webhook per hour (WEBHOOK_TEST_LIMIT says when to retry). Use it after creating or changing a webhook to show it works; check the result in the receiving system. Requires OAuth scope: manage:comms.webhooks (see motorical_whoami for what it allows).

PropertyValue
Needs scopemanage:comms.webhooks
Available onHosted servers: main, communications only (no local server)
Acts onSee the description
Not listedWhen the connection does not hold the scope (the narrow servers hide it; the main server lists it marked "Needs permission")
REST routePOST /comm-api/api/workspaces/{id}/webhooks/{wid}/test
BehaviourChanges data
InputTypeRequiredMeaning
workspaceIdstring (uuid)NoThe Communications workspace. Optional when the authorization covers exactly one; otherwise required (the error lists the choices, the account default first).
dryRunbooleanNoDefault true: validate and show exactly what would happen, and change nothing. Pass false to actually write.
webhookIdstring (uuid)YesThe webhook id.

Returns the JSON of the REST route above.

Example arguments (placeholders in angle brackets, required inputs only):

{"webhookId":"<webhookId>"}