Contacts
Create, search, and update contacts and their tags, notes, tasks, and workflow enrollments.
topline_add_contact_tags
#
Add one or more tags to a contact.
Parameters
| Field | Type | Description |
contactId required |
string |
Contact ID |
tags required |
array<string> |
Tag names to add |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_add_contact_tags",
"arguments": {
"contactId": "string",
"tags": [
"string"
]
}
}
}
topline_add_contact_to_workflow
#
Enroll a contact in a workflow.
Parameters
| Field | Type | Description |
contactId required |
string |
Contact ID |
workflowId required |
string |
Workflow ID |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_add_contact_to_workflow",
"arguments": {
"contactId": "string",
"workflowId": "string"
}
}
}
Create a new contact. At minimum provide a name or email or phone. Custom fields go in customFields as {id, value} pairs.
Parameters
| Field | Type | Description |
firstName |
string |
|
lastName |
string |
|
name |
string |
Full name (use instead of firstName+lastName if you prefer) |
email |
string |
|
phone |
string |
E.164 format preferred, e.g. +14155551212 |
tags |
array<string> |
|
source |
string |
Attribution source (e.g. 'claude', 'website') |
customFields |
array<object> |
item properties| Field | Type | Description |
id |
string |
|
value |
any |
|
|
locationId |
string |
Location (sub-account) ID. Defaults to TOPLINE_LOCATION_ID env var if omitted. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_create_contact",
"arguments": {
"firstName": "string",
"lastName": "string"
}
}
}
Permanently delete a contact. Irreversible.
Parameters
| Field | Type | Description |
contactId required |
string |
Contact ID |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_delete_contact",
"arguments": {
"contactId": "string"
}
}
}
Fetch a single contact by ID. Returns all standard fields and custom fields.
Parameters
| Field | Type | Description |
contactId required |
string |
Contact ID |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_get_contact",
"arguments": {
"contactId": "string"
}
}
}
topline_list_contact_notes
#
List all notes on a contact.
Parameters
| Field | Type | Description |
contactId required |
string |
Contact ID |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_list_contact_notes",
"arguments": {
"contactId": "string"
}
}
}
topline_list_contact_tasks
#
List all tasks for a contact.
Parameters
| Field | Type | Description |
contactId required |
string |
Contact ID |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_list_contact_tasks",
"arguments": {
"contactId": "string"
}
}
}
topline_remove_contact_from_workflow
#
Remove a contact from a workflow.
Parameters
| Field | Type | Description |
contactId required |
string |
Contact ID |
workflowId required |
string |
Workflow ID |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_remove_contact_from_workflow",
"arguments": {
"contactId": "string",
"workflowId": "string"
}
}
}
topline_remove_contact_tags
#
Remove one or more tags from a contact.
Parameters
| Field | Type | Description |
contactId required |
string |
Contact ID |
tags required |
array<string> |
|
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_remove_contact_tags",
"arguments": {
"contactId": "string",
"tags": [
"string"
]
}
}
}
topline_search_contacts
#
Search contacts by free-text query (name, email, phone) and/or tag. Returns up to 100 per call with a cursor for pagination.
Parameters
| Field | Type | Description |
query |
string |
Free-text search: name, email, or phone |
tags |
array<string> |
Filter to contacts with ALL of these tags |
limit |
number |
Results per page (max 100, default 25) |
startAfterId |
string |
Cursor from a previous page |
locationId |
string |
Location (sub-account) ID. Defaults to TOPLINE_LOCATION_ID env var if omitted. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_search_contacts",
"arguments": {
"query": "string",
"tags": [
"string"
]
}
}
}
Update fields on an existing contact.
Parameters
| Field | Type | Description |
contactId required |
string |
Contact ID |
firstName |
string |
|
lastName |
string |
|
email |
string |
|
phone |
string |
|
tags |
array<string> |
REPLACES the tag list. Use add/remove tag tools for incremental changes. |
customFields |
array<object> |
item properties| Field | Type | Description |
id |
string |
|
value |
any |
|
|
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_update_contact",
"arguments": {
"contactId": "string"
}
}
}
Create a contact, or update the existing one if email/phone matches. Use this when you're not sure whether the contact already exists.
Parameters
| Field | Type | Description |
firstName |
string |
|
lastName |
string |
|
email |
string |
|
phone |
string |
|
tags |
array<string> |
|
source |
string |
|
customFields |
array<object> |
item properties| Field | Type | Description |
id |
string |
|
value |
any |
|
|
locationId |
string |
Location (sub-account) ID. Defaults to TOPLINE_LOCATION_ID env var if omitted. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_upsert_contact",
"arguments": {
"firstName": "string",
"lastName": "string"
}
}
}
Opportunities & pipelines
Move deals through pipeline stages, mark won/lost, set value.
topline_create_opportunity
#
Create a new opportunity in a pipeline stage, associated with a contact.
Parameters
| Field | Type | Description |
pipelineId required |
string |
Pipeline ID |
pipelineStageId required |
string |
Pipeline stage ID |
contactId required |
string |
Contact ID |
name required |
string |
Opportunity name / title |
monetaryValue |
number |
Deal value in USD |
status |
"open" | "won" | "lost" | "abandoned" |
|
assignedTo |
string |
User ID to assign to |
tags |
array<string> |
|
locationId |
string |
Location (sub-account) ID. Defaults to TOPLINE_LOCATION_ID env var if omitted. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_create_opportunity",
"arguments": {
"pipelineId": "string",
"pipelineStageId": "string",
"contactId": "string",
"name": "string"
}
}
}
topline_delete_opportunity
#
Delete an opportunity.
Parameters
| Field | Type | Description |
opportunityId required |
string |
Opportunity ID |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_delete_opportunity",
"arguments": {
"opportunityId": "string"
}
}
}
topline_get_opportunity
#
Fetch a single opportunity by ID.
Parameters
| Field | Type | Description |
opportunityId required |
string |
Opportunity ID |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_get_opportunity",
"arguments": {
"opportunityId": "string"
}
}
}
List all opportunity pipelines in the sub-account with their stages.
Parameters
| Field | Type | Description |
locationId |
string |
Location (sub-account) ID. Defaults to TOPLINE_LOCATION_ID env var if omitted. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_list_pipelines",
"arguments": {
"locationId": "string"
}
}
}
topline_search_opportunities
#
Search opportunities. Filter by pipeline, stage, status, contact, or free text. PAGINATION: the cursor is COMPOUND — to advance past page 1 you must send BOTH `startAfter` and `startAfterId` from the previous response's `meta` object. Sending only one silently returns the same page.
Parameters
| Field | Type | Description |
query |
string |
Free-text search |
pipelineId |
string |
Restrict to one pipeline |
pipelineStageId |
string |
Restrict to one stage |
assignedTo |
string |
User ID |
contactId |
string |
|
status |
"open" | "won" | "lost" | "abandoned" | "all" |
|
limit |
number |
Results per page (max 100, default 25) |
startAfter |
string |
Cursor timestamp (ms epoch) from the previous response's `meta.startAfter`. Required together with `startAfterId` to advance the page — sending only one silently returns the same page. |
startAfterId |
string |
Cursor row id from the previous response's `meta.startAfterId`. Required together with `startAfter` to advance the page. |
locationId |
string |
Location (sub-account) ID. Defaults to TOPLINE_LOCATION_ID env var if omitted. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_search_opportunities",
"arguments": {
"query": "string",
"pipelineId": "string"
}
}
}
topline_update_opportunity
#
Update an opportunity — move stages, change value, mark won/lost, etc.
Parameters
| Field | Type | Description |
opportunityId required |
string |
Opportunity ID |
name |
string |
|
pipelineStageId |
string |
|
monetaryValue |
number |
|
status |
"open" | "won" | "lost" | "abandoned" |
|
assignedTo |
string |
|
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_update_opportunity",
"arguments": {
"opportunityId": "string"
}
}
}
Calendars & appointments
Read calendar config, find slots, book appointments.
topline_create_appointment
#
Book an appointment on a calendar for a contact.
Parameters
| Field | Type | Description |
calendarId required |
string |
Calendar ID |
contactId required |
string |
Contact ID |
startTime required |
string |
ISO 8601 start time, e.g. '2026-04-20T15:00:00-04:00' |
endTime |
string |
ISO 8601 end time (optional — inferred from calendar if omitted) |
title |
string |
Appointment title |
appointmentStatus |
"new" | "confirmed" | "cancelled" | "showed" | "noshow" | "invalid" |
|
assignedUserId |
string |
User ID to assign |
address |
string |
Location or meeting link |
locationId |
string |
Location (sub-account) ID. Defaults to TOPLINE_LOCATION_ID env var if omitted. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_create_appointment",
"arguments": {
"calendarId": "string",
"contactId": "string",
"startTime": "string"
}
}
}
topline_delete_appointment
#
Cancel and delete an appointment.
Parameters
| Field | Type | Description |
appointmentId required |
string |
Appointment ID |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_delete_appointment",
"arguments": {
"appointmentId": "string"
}
}
}
topline_delete_calendar
#
Delete a calendar. All future appointments on this calendar are cancelled. Past appointments are retained as historical records.
Parameters
| Field | Type | Description |
calendarId required |
string |
Calendar ID |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_delete_calendar",
"arguments": {
"calendarId": "string"
}
}
}
Get the full calendar definition (availability rules, team members, slot duration, etc.).
Parameters
| Field | Type | Description |
calendarId required |
string |
Calendar ID |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_get_calendar",
"arguments": {
"calendarId": "string"
}
}
}
topline_get_calendar_slots
#
Get available time slots for a calendar within a date range (ms epoch).
Parameters
| Field | Type | Description |
calendarId required |
string |
Calendar ID |
startDate required |
number |
Start timestamp (ms since epoch) |
endDate required |
number |
End timestamp (ms since epoch) |
timezone |
string |
IANA timezone (e.g. 'America/New_York') |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_get_calendar_slots",
"arguments": {
"calendarId": "string",
"startDate": 0,
"endDate": 0
}
}
}
List all calendars configured on the sub-account.
Parameters
| Field | Type | Description |
locationId |
string |
Location (sub-account) ID. Defaults to TOPLINE_LOCATION_ID env var if omitted. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_list_calendars",
"arguments": {
"locationId": "string"
}
}
}
topline_update_appointment
#
Update an appointment (reschedule, change status, reassign).
Parameters
| Field | Type | Description |
appointmentId required |
string |
Appointment ID |
startTime |
string |
ISO 8601 |
endTime |
string |
ISO 8601 |
title |
string |
|
appointmentStatus |
"new" | "confirmed" | "cancelled" | "showed" | "noshow" | "invalid" |
|
assignedUserId |
string |
|
address |
string |
|
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_update_appointment",
"arguments": {
"appointmentId": "string"
}
}
}
topline_update_calendar
#
Update a calendar's name, description, slot duration, availability, team members, or event title. Pass only the fields you want to change. The calendar must already exist — calendar CREATE is not available under PIT (marketplace OAuth only).
Parameters
| Field | Type | Description |
calendarId required |
string |
Calendar ID |
name |
string |
New calendar name |
description |
string |
New description |
slug |
string |
URL slug (shows in public booking URLs) |
isActive |
boolean |
Enable / disable the calendar |
slotDuration |
number |
Appointment length in minutes |
slotBuffer |
number |
Buffer (minutes) between appointments |
eventTitle |
string |
Default event title template |
eventColor |
string |
Hex color shown in the UI |
appoinmentPerSlot |
number |
Max concurrent bookings per slot |
allowReschedule |
boolean |
|
allowCancellation |
boolean |
|
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_update_calendar",
"arguments": {
"calendarId": "string"
}
}
}
Social planner
Manage social posts, connected accounts, OAuth flows, and CSV imports.
Manage connected social-media accounts for a location. Actions: `list` (returns connected accounts + groups), `delete` (disconnect an account by id). Note: connecting (oauth) lives on the topline_social_oauth tool.
Parameters
| Field | Type | Description |
action required |
"list" | "delete" |
Which operation to perform. |
id |
string |
Account id — required for delete. |
locationId |
string |
Location (sub-account) ID. Defaults to TOPLINE_LOCATION_ID env var if omitted. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_social_account",
"arguments": {
"action": "list"
}
}
}
Bulk-import social posts via CSV. Workflow: upload → assign_accounts → finalize. Actions: `upload` (POST a CSV file or URL in the body), `list` (all imports), `get` (single import by id), `assign_accounts` (link the upload to one or more connected accounts), `finalize` (PATCH to schedule all posts from the import), `delete` (remove an import).
Parameters
| Field | Type | Description |
action required |
"upload" | "list" | "get" | "finalize" | "delete" | "assign_accounts" |
Which operation to perform. |
id |
string |
CSV import id — required for get / finalize / delete. |
body |
object |
nested properties |
locationId |
string |
Location (sub-account) ID. Defaults to TOPLINE_LOCATION_ID env var if omitted. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_social_csv",
"arguments": {
"action": "upload"
}
}
}
Connect a social-media account via OAuth. Three-step flow per platform: `start` returns a URL the user must open in a browser to authorize; `get_accounts` fetches the accounts/pages available after the user authorizes (call with the `accountId` returned by the platform's callback); `attach_accounts` finalizes the connection by attaching one or more of those accounts/pages to this location. Supported platforms: `facebook`, `instagram`, `linkedin`, `twitter` (deprecated — X access is best-effort).
Parameters
| Field | Type | Description |
action required |
"start" | "get_accounts" | "attach_accounts" |
Which step of the OAuth flow. |
platform required |
"facebook" | "instagram" | "linkedin" | "twitter" |
Which platform to connect. |
accountId |
string |
Platform-side account id returned by the OAuth callback — required for get_accounts and attach_accounts. |
body |
object |
nested properties |
locationId |
string |
Location (sub-account) ID. Defaults to TOPLINE_LOCATION_ID env var if omitted. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_social_oauth",
"arguments": {
"action": "start",
"platform": "facebook"
}
}
}
Manage scheduled and published social media posts across connected accounts (Facebook, Instagram, LinkedIn, X, Google Business Profile, TikTok). Actions: `list` (search posts by date / account / status, POSTs the filter body), `get` (single post by id), `create` (schedule a new post; provide `accountIds`, `summary`, optional `scheduleDate`, attachments, etc. in the body), `update` (edit an existing post), `delete` (remove a single post), `bulk_delete` (remove multiple posts by `postIds`). Pass `action` plus the action's required params.
Parameters
| Field | Type | Description |
action required |
"list" | "get" | "create" | "update" | "delete" | "bulk_delete" |
Which operation to perform. |
id |
string |
Post id — required for get / update / delete. |
postIds |
array<string> |
Array of post ids — required for bulk_delete. |
body |
object |
nested properties |
locationId |
string |
Location (sub-account) ID. Defaults to TOPLINE_LOCATION_ID env var if omitted. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_social_post",
"arguments": {
"action": "list"
}
}
}
Email campaigns
Manage email templates, campaigns, recipients, and campaign reporting.
Manage email campaigns (broadcasts / scheduled sends). Actions: `list` (all campaigns for the location), `get` (single campaign by `campaignId`), `create` (new campaign — provide `body` with name, subject, recipients, template/html, etc.), `update` (edit an existing campaign), `delete` (remove a campaign), `send` (send immediately), `schedule` (schedule for a future timestamp — pass `sendAt` in body). NOTE: endpoint path is best-effort (/campaigns/); live PIT smoke test pending.
Parameters
| Field | Type | Description |
action required |
"list" | "get" | "create" | "update" | "delete" | "send" | "schedule" |
Which operation to perform. |
campaignId |
string |
Campaign id — required for get / update / delete / send / schedule. |
body |
object |
nested properties |
locationId |
string |
Location (sub-account) ID. Defaults to TOPLINE_LOCATION_ID env var if omitted. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_email_campaign",
"arguments": {
"action": "list"
}
}
}
topline_email_campaign_recipients
#
List recipients of an email campaign (with per-recipient delivery / engagement status if available). Action: `list` by `campaignId`.
Parameters
| Field | Type | Description |
action required |
"list" |
Which operation to perform. |
campaignId required |
string |
Campaign id. |
locationId |
string |
Location (sub-account) ID. Defaults to TOPLINE_LOCATION_ID env var if omitted. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_email_campaign_recipients",
"arguments": {
"action": "list",
"campaignId": "string"
}
}
}
topline_email_campaign_stats
#
Aggregated performance stats for an email campaign — sends, opens, clicks, bounces, unsubscribes. Action: `get` by `campaignId`.
Parameters
| Field | Type | Description |
action required |
"get" |
Which operation to perform. |
campaignId required |
string |
Campaign id. |
locationId |
string |
Location (sub-account) ID. Defaults to TOPLINE_LOCATION_ID env var if omitted. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_email_campaign_stats",
"arguments": {
"action": "get",
"campaignId": "string"
}
}
}
Manage saved email templates. Actions: `list` (all templates for the location), `get` (single template by `templateId`), `create` (new template — provide `body` with name, subject, html, etc.), `update` (edit an existing template by `templateId`), `delete` (remove a template). NOTE: endpoint path is best-effort (/emails/builder/); live PIT smoke test pending. If a call returns 404, update the path or open an issue.
Parameters
| Field | Type | Description |
action required |
"list" | "get" | "create" | "update" | "delete" |
Which operation to perform. |
templateId |
string |
Template id — required for get / update / delete. |
body |
object |
nested properties |
locationId |
string |
Location (sub-account) ID. Defaults to TOPLINE_LOCATION_ID env var if omitted. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_email_template",
"arguments": {
"action": "list"
}
}
}
Ad publishing
Manage Facebook, Google, and LinkedIn ad integrations, campaigns, targeting, and reporting.
Manage Facebook ad creatives. Actions: `upsert` (create or update — provide ad in `body`), `pause`, `resume`, `duplicate`, `delete` (by `adId`).
Parameters
| Field | Type | Description |
action required |
"upsert" | "pause" | "resume" | "duplicate" | "delete" |
Which operation to perform. |
adId |
string |
Ad id — required for pause / resume / duplicate / delete. |
body |
object |
nested properties |
locationId |
string |
Location (sub-account) ID. Defaults to TOPLINE_LOCATION_ID env var if omitted. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_fb_ad",
"arguments": {
"action": "upsert"
}
}
}
Manage connected Facebook ad accounts. Actions: `list` (all connected), `get` (by `adAccountId`), `delete` (disconnect).
Parameters
| Field | Type | Description |
action required |
"list" | "get" | "delete" |
Which operation to perform. |
adAccountId |
string |
Ad account id — required for get / delete. |
locationId |
string |
Location (sub-account) ID. Defaults to TOPLINE_LOCATION_ID env var if omitted. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_fb_ad_account",
"arguments": {
"action": "list"
}
}
}
Manage Facebook ad sets. Actions: `upsert` (create or update — provide ad set in `body`), `pause`, `resume`, `duplicate`, `delete` (by `adSetId`).
Parameters
| Field | Type | Description |
action required |
"upsert" | "pause" | "resume" | "duplicate" | "delete" |
Which operation to perform. |
adSetId |
string |
Ad set id — required for pause / resume / duplicate / delete. |
body |
object |
nested properties |
locationId |
string |
Location (sub-account) ID. Defaults to TOPLINE_LOCATION_ID env var if omitted. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_fb_adset",
"arguments": {
"action": "upsert"
}
}
}
Manage Facebook ad campaigns. Actions: `get` (single campaign with entities by `campaignId`), `upsert` (create or update — provide full campaign in `body`), `publish` (publish a draft by `campaignId`), `pause`, `resume`, `duplicate`, `delete` (by `campaignId`).
Parameters
| Field | Type | Description |
action required |
"get" | "upsert" | "publish" | "pause" | "resume" | "duplicate" | "delete" |
Which operation to perform. |
campaignId |
string |
Campaign id — required for get / publish / pause / resume / duplicate / delete. |
body |
object |
nested properties |
locationId |
string |
Location (sub-account) ID. Defaults to TOPLINE_LOCATION_ID env var if omitted. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_fb_campaign",
"arguments": {
"action": "get"
}
}
}
topline_fb_custom_audience
#
Manage Facebook custom audiences and their members. Actions: `list`, `update` (by `audienceId`), `delete` (by `audienceId`), `add_member` (single — by `audienceId` + member info in `body`), `remove_member` (single — by `audienceId` + member info in `body`), `batch_update_members` (bulk — by `audienceId` + member array in `body`).
Parameters
| Field | Type | Description |
action required |
"list" | "update" | "delete" | "add_member" | "remove_member" | "batch_update_members" |
Which operation to perform. |
audienceId |
string |
Audience id — required for update / delete / add_member / remove_member / batch_update_members. |
body |
object |
nested properties |
locationId |
string |
Location (sub-account) ID. Defaults to TOPLINE_LOCATION_ID env var if omitted. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_fb_custom_audience",
"arguments": {
"action": "list"
}
}
}
Generic Facebook entity lookup endpoint. Action: `get` (returns the requested entity — pass identifying params in `query`).
Parameters
| Field | Type | Description |
action required |
"get" |
Which operation to perform. |
query |
object |
nested properties |
locationId |
string |
Location (sub-account) ID. Defaults to TOPLINE_LOCATION_ID env var if omitted. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_fb_entity",
"arguments": {
"action": "get"
}
}
}
Manage the location's Facebook integration (also surfaces Instagram via FB Pages). Actions: `get` / `create` / `delete` (the integration itself); `get_me` (the authenticated FB user); `list_pages` (FB pages available on the integration); `get_page_instagram` (Instagram accounts attached to a page — provide `pageId`); `delete_page` (remove a page connection); `set_default_page` (mark a page as default for publishing); `get_lead_form` (single lead form by `leadFormId`).
Parameters
| Field | Type | Description |
action required |
"get" | "create" | "delete" | "get_me" | "list_pages" | "get_page_instagram" | "delete_page" | "set_default_page" | "get_lead_form" |
Which operation to perform. |
pageId |
string |
Facebook Page id — required for get_page_instagram. |
leadFormId |
string |
Lead form id — required for get_lead_form. |
body |
object |
nested properties |
locationId |
string |
Location (sub-account) ID. Defaults to TOPLINE_LOCATION_ID env var if omitted. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_fb_integration",
"arguments": {
"action": "get"
}
}
}
Manage Facebook lead forms (page-level + conversation-level). Actions: `list_page_forms` (by `pageId`), `create_page_form` (by `pageId` + `body`), `list_conversation_forms`, `create_conversation_form` (provide `body`).
Parameters
| Field | Type | Description |
action required |
"list_page_forms" | "create_page_form" | "list_conversation_forms" | "create_conversation_form" |
Which operation to perform. |
pageId |
string |
Facebook Page id — required for list_page_forms / create_page_form. |
body |
object |
nested properties |
locationId |
string |
Location (sub-account) ID. Defaults to TOPLINE_LOCATION_ID env var if omitted. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_fb_lead_form",
"arguments": {
"action": "list_page_forms"
}
}
}
Manage Facebook conversion pixels for the location. Actions: `list`, `upsert` (create or update — provide pixel config in `body`).
Parameters
| Field | Type | Description |
action required |
"list" | "upsert" |
Which operation to perform. |
body |
object |
nested properties |
locationId |
string |
Location (sub-account) ID. Defaults to TOPLINE_LOCATION_ID env var if omitted. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_fb_pixel",
"arguments": {
"action": "list"
}
}
}
Facebook ads reporting. Actions: `data` (aggregated metrics across campaigns / ad sets / ads — pass `level` + date range), `campaign` (metrics for a specific campaign by `campaignId`), `list` (list entities with their reporting data — pass `type` + `listType` + optional `fields`). ALL actions take `dateFrom` and `dateTo` as ISO date strings (YYYY-MM-DD). Common values for `level` / `type`: `account`, `campaign`, `adset`, `ad`. Common values for `listType`: `active`, `paused`, `all`. `fields` is a comma-separated list of metric column names (e.g. `spend,impressions,clicks,conversions`). If the endpoint rejects your values with 422, surface that to the operator — the valid enum set isn't stably published in CRM docs and can shift.
Parameters
| Field | Type | Description |
action required |
"data" | "campaign" | "list" |
Which operation to perform. |
campaignId |
string |
Campaign id — required for action='campaign'. |
dateFrom |
string |
ISO date string (YYYY-MM-DD). Inclusive. |
dateTo |
string |
ISO date string (YYYY-MM-DD). Inclusive. |
level |
string |
Aggregation level: 'account' | 'campaign' | 'adset' | 'ad'. Used by action='data'. |
type |
string |
Entity type for list: 'campaign' | 'adset' | 'ad'. Used by action='list'. |
listType |
string |
List filter: 'active' | 'paused' | 'all'. Used by action='list'. |
fields |
string |
Comma-separated metric columns (e.g. 'spend,impressions,clicks'). Used by action='list'. |
breakdown |
string |
Optional dimensional breakdown ('date', 'age', 'gender', 'device', etc.). |
extra |
object |
nested properties |
locationId |
string |
Location (sub-account) ID. Defaults to TOPLINE_LOCATION_ID env var if omitted. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_fb_reporting",
"arguments": {
"action": "data"
}
}
}
Search Facebook targeting options — geo locations, interests, behaviors, demographics. Action: `search` (pass search params like `query`, `type`, `country` in `body` or `query`).
Parameters
| Field | Type | Description |
action required |
"search" |
Which operation to perform. |
query |
object |
nested properties |
locationId |
string |
Location (sub-account) ID. Defaults to TOPLINE_LOCATION_ID env var if omitted. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_fb_targeting",
"arguments": {
"action": "search"
}
}
}
topline_google_ad_account
#
Manage connected Google ad accounts. Actions: `list` (all connected), `get` (by `adAccountId`), `delete` (disconnect).
Parameters
| Field | Type | Description |
action required |
"list" | "get" | "delete" |
Which operation to perform. |
adAccountId |
string |
Ad account id — required for get / delete. |
locationId |
string |
Location (sub-account) ID. Defaults to TOPLINE_LOCATION_ID env var if omitted. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_google_ad_account",
"arguments": {
"action": "list"
}
}
}
topline_google_audience
#
Manage Google Ads audiences. Actions: `list` (all combined audiences), `get` (by `audienceId`), `upsert` (create or update — provide audience config in `body`), `create_offline_user_list_job` (offline-conversion user-list upload job — provide job config in `body`).
Parameters
| Field | Type | Description |
action required |
"list" | "get" | "upsert" | "create_offline_user_list_job" |
Which operation to perform. |
audienceId |
string |
Audience id — required for get. |
body |
object |
nested properties |
locationId |
string |
Location (sub-account) ID. Defaults to TOPLINE_LOCATION_ID env var if omitted. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_google_audience",
"arguments": {
"action": "list"
}
}
}
topline_google_campaign
#
Manage Google Ads campaigns (creates or updates the full structure: campaign, ad groups, ads, keywords). Actions: `upsert` (provide full campaign in `body`), `get` (by `adId`), `publish_ad` (publish a draft ad by `adId`).
Parameters
| Field | Type | Description |
action required |
"upsert" | "get" | "publish_ad" |
Which operation to perform. |
adId |
string |
Ad id — required for get / publish_ad. |
body |
object |
nested properties |
locationId |
string |
Location (sub-account) ID. Defaults to TOPLINE_LOCATION_ID env var if omitted. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_google_campaign",
"arguments": {
"action": "upsert"
}
}
}
topline_google_conversion
#
Manage Google Ads conversion actions and conversion goals. Actions: `list` (all conversions), `upsert` (create or update — provide conversion config in `body`), `get` (by `conversionId`), `delete` (by `conversionId`), `list_goals` (available conversion goals for the location).
Parameters
| Field | Type | Description |
action required |
"list" | "upsert" | "get" | "delete" | "list_goals" |
Which operation to perform. |
conversionId |
string |
Conversion id — required for get / delete. |
body |
object |
nested properties |
locationId |
string |
Location (sub-account) ID. Defaults to TOPLINE_LOCATION_ID env var if omitted. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_google_conversion",
"arguments": {
"action": "list"
}
}
}
topline_google_integration
#
Manage the location's Google Ads integration. Actions: `get`, `create` (provide auth payload in `body`), `get_me` (authenticated Google user).
Parameters
| Field | Type | Description |
action required |
"get" | "create" | "get_me" |
Which operation to perform. |
body |
object |
nested properties |
locationId |
string |
Location (sub-account) ID. Defaults to TOPLINE_LOCATION_ID env var if omitted. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_google_integration",
"arguments": {
"action": "get"
}
}
}
topline_google_reporting
#
Google Ads reporting. Actions: `data` (aggregated metrics — pass `level` + date range), `list` (list entities with reporting data — pass `type` + `listType` + optional `fields`), `campaign` (metrics for a specific campaign by `campaignId`). ALL actions take `dateFrom` and `dateTo` as ISO date strings (YYYY-MM-DD). Common `level` / `type`: `account`, `campaign`, `ad_group`, `ad`. Google Ads reports cost in micros internally; this MCP forwards the CRM's normalized values.
Parameters
| Field | Type | Description |
action required |
"data" | "list" | "campaign" |
Which operation to perform. |
campaignId |
string |
Campaign id — required for action='campaign'. |
dateFrom |
string |
ISO date string (YYYY-MM-DD). |
dateTo |
string |
ISO date string (YYYY-MM-DD). |
level |
string |
Aggregation level: 'account' | 'campaign' | 'ad_group' | 'ad'. |
type |
string |
Entity type for list: 'campaign' | 'ad_group' | 'ad'. |
listType |
string |
List filter: 'active' | 'paused' | 'all'. |
fields |
string |
Comma-separated metric columns (e.g. 'cost,impressions,clicks'). |
breakdown |
string |
Optional dimensional breakdown. |
extra |
object |
nested properties |
locationId |
string |
Location (sub-account) ID. Defaults to TOPLINE_LOCATION_ID env var if omitted. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_google_reporting",
"arguments": {
"action": "data"
}
}
}
topline_google_targeting
#
Search Google Ads targeting options. Action: `search` (pass search params in `query`).
Parameters
| Field | Type | Description |
action required |
"search" |
Which operation to perform. |
query |
object |
nested properties |
locationId |
string |
Location (sub-account) ID. Defaults to TOPLINE_LOCATION_ID env var if omitted. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_google_targeting",
"arguments": {
"action": "search"
}
}
}
topline_linkedin_ad_account
#
Manage connected LinkedIn ad accounts. Actions: `list`, `get` (current/details), `delete` (disconnect).
Parameters
| Field | Type | Description |
action required |
"list" | "get" | "delete" |
Which operation to perform. |
locationId |
string |
Location (sub-account) ID. Defaults to TOPLINE_LOCATION_ID env var if omitted. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_linkedin_ad_account",
"arguments": {
"action": "list"
}
}
}
topline_linkedin_campaign
#
Manage LinkedIn ad campaign groups (with nested campaigns and ads). Actions: `upsert` (create or update — provide full campaign group in `body`), `get` (by `adId` — returns the campaign group + nested campaigns / ad groups / ads), `publish` (publish a draft by `adId`), `update_status` (pause, resume, archive an ad or campaign by `adId` — provide status in `body`).
Parameters
| Field | Type | Description |
action required |
"upsert" | "get" | "publish" | "update_status" |
Which operation to perform. |
adId |
string |
Campaign-group ad id — required for get / publish / update_status. |
body |
object |
nested properties |
locationId |
string |
Location (sub-account) ID. Defaults to TOPLINE_LOCATION_ID env var if omitted. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_linkedin_campaign",
"arguments": {
"action": "upsert"
}
}
}
topline_linkedin_integration
#
Manage the location's LinkedIn Ads integration. Actions: `get`, `create` (provide auth payload in `body`), `get_me` (authenticated LinkedIn user).
Parameters
| Field | Type | Description |
action required |
"get" | "create" | "get_me" |
Which operation to perform. |
body |
object |
nested properties |
locationId |
string |
Location (sub-account) ID. Defaults to TOPLINE_LOCATION_ID env var if omitted. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_linkedin_integration",
"arguments": {
"action": "get"
}
}
}
topline_linkedin_lead_form
#
Manage LinkedIn lead forms per ad account. Actions: `list` (by `accountId`), `create` (by `accountId` + form config in `body`).
Parameters
| Field | Type | Description |
action required |
"list" | "create" |
Which operation to perform. |
accountId required |
string |
LinkedIn ad account id. |
body |
object |
nested properties |
locationId |
string |
Location (sub-account) ID. Defaults to TOPLINE_LOCATION_ID env var if omitted. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_linkedin_lead_form",
"arguments": {
"action": "list",
"accountId": "string"
}
}
}
topline_linkedin_reporting
#
LinkedIn Ads reporting. Actions: `data` (aggregated metrics — pass `level` + date range), `list` (list entities with reporting data — pass `type` + `listType` + optional `fields`), `campaign` (metrics for a specific campaign group by `campaignId`). ALL actions take `dateFrom` and `dateTo` as ISO date strings (YYYY-MM-DD). Common `level` / `type`: `account`, `campaign_group`, `campaign`, `ad`. LinkedIn's campaign-group is the equivalent of Meta's campaign — the top of the hierarchy.
Parameters
| Field | Type | Description |
action required |
"data" | "list" | "campaign" |
Which operation to perform. |
campaignId |
string |
Campaign id — required for action='campaign'. |
dateFrom |
string |
ISO date string (YYYY-MM-DD). |
dateTo |
string |
ISO date string (YYYY-MM-DD). |
level |
string |
Aggregation level: 'account' | 'campaign_group' | 'campaign' | 'ad'. |
type |
string |
Entity type for list: 'campaign_group' | 'campaign' | 'ad'. |
listType |
string |
List filter: 'active' | 'paused' | 'all'. |
fields |
string |
Comma-separated metric columns (e.g. 'spend,impressions,clicks'). |
breakdown |
string |
Optional dimensional breakdown. |
extra |
object |
nested properties |
locationId |
string |
Location (sub-account) ID. Defaults to TOPLINE_LOCATION_ID env var if omitted. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_linkedin_reporting",
"arguments": {
"action": "data"
}
}
}
topline_linkedin_targeting
#
Search LinkedIn targeting options (location, industry, job title facets). Action: `search` (pass search params in `query`).
Parameters
| Field | Type | Description |
action required |
"search" |
Which operation to perform. |
query |
object |
nested properties |
locationId |
string |
Location (sub-account) ID. Defaults to TOPLINE_LOCATION_ID env var if omitted. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_linkedin_targeting",
"arguments": {
"action": "search"
}
}
}
Marketing configuration & UTM
Configure attribution fields and create, register, retrieve, and validate campaign UTMs.
Build a fully-attributable URL by appending UTM params to a website URL. Validates source + medium against the tenant's configured taxonomy and throws on unknown values. Either pass explicit UTM params, or pass a registered campaign `slug` to resolve from the campaign UTM registry.
Parameters
| Field | Type | Description |
websiteUrl required |
string |
Full destination URL (https://...). |
slug |
string |
Optional: resolve UTMs from a registered campaign slug. |
source |
string |
utm_source. Required if slug not provided. |
medium |
string |
utm_medium. Required if slug not provided. |
campaign |
string |
utm_campaign. |
campaignId |
string |
utm_id. |
term |
string |
utm_term. |
content |
string |
utm_content. |
locationId |
string |
Location (sub-account) ID. Defaults to TOPLINE_LOCATION_ID env var if omitted. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_build_utm_url",
"arguments": {
"websiteUrl": "string"
}
}
}
topline_get_campaign_utm
#
Get a registered campaign's canonical UTM set by `slug`. Returns null if not registered. Use this before emitting a link in any surface to ensure consistency.
Parameters
| Field | Type | Description |
slug required |
string |
Campaign slug. |
locationId |
string |
Location (sub-account) ID. Defaults to TOPLINE_LOCATION_ID env var if omitted. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_get_campaign_utm",
"arguments": {
"slug": "string"
}
}
}
topline_get_marketing_config
#
Returns this location's marketing config — the channel taxonomy (allowed utm_source / utm_medium values), attribution rules (qualified-pipeline name, closed-won stage names, stage probabilities for forecast MRR), spend-classification rules, dashboard layout, and Slack webhook target. Stored as a JSON-encoded custom value named `_topline_marketing_config` in the location. Falls back to generic defaults if the value doesn't exist yet.
Parameters
| Field | Type | Description |
locationId |
string |
Location (sub-account) ID. Defaults to TOPLINE_LOCATION_ID env var if omitted. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_get_marketing_config",
"arguments": {
"locationId": "string"
}
}
}
topline_init_attribution_fields
#
Ensure the six attribution custom fields exist on contacts for this location: utm_source_first, utm_medium_first, utm_campaign_first, utm_source_last, utm_medium_last, utm_campaign_last. Idempotent — creates each that's missing, skips ones that already exist. Run once during marketing setup so the homepage form snippet can populate them.
Parameters
| Field | Type | Description |
locationId |
string |
Location (sub-account) ID. Defaults to TOPLINE_LOCATION_ID env var if omitted. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_init_attribution_fields",
"arguments": {
"locationId": "string"
}
}
}
Lint a URL (or explicit UTM params) against the tenant's marketing config. Returns an array of warnings: missing required fields, non-canonical source/medium values, common typos. Empty array if everything looks good. Useful for sanity-checking links before they ship in a post / email / ad.
Parameters
| Field | Type | Description |
url |
string |
URL to lint. |
source |
string |
utm_source (if not parsing from URL). |
medium |
string |
utm_medium. |
campaign |
string |
utm_campaign. |
campaignId |
string |
utm_id. |
term |
string |
utm_term. |
content |
string |
utm_content. |
locationId |
string |
Location (sub-account) ID. Defaults to TOPLINE_LOCATION_ID env var if omitted. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_lint_utm",
"arguments": {
"url": "string",
"source": "string"
}
}
}
topline_list_campaign_utms
#
List all registered campaign UTM entries for this location.
Parameters
| Field | Type | Description |
locationId |
string |
Location (sub-account) ID. Defaults to TOPLINE_LOCATION_ID env var if omitted. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_list_campaign_utms",
"arguments": {
"locationId": "string"
}
}
}
topline_register_campaign_utm
#
Register or update a campaign's canonical UTM set. Same campaign slug always emits the same utm_source / utm_medium / utm_campaign / utm_id / utm_term / utm_content across every surface (social planner, email campaign, ad publishing). Validates source + medium against the tenant's marketing config. Stored in the `_topline_campaign_utms` custom value on this location.
Parameters
| Field | Type | Description |
slug required |
string |
Campaign slug — short stable identifier, e.g. '2026-q2-lp-funnel'. |
source required |
string |
utm_source. Must be in the tenant's configured sources. |
medium required |
string |
utm_medium. Must be in the tenant's configured mediums. |
campaign |
string |
utm_campaign — human-readable name. One of campaign or campaignId required. |
campaignId |
string |
utm_id — ad-network campaign id. One of campaign or campaignId required. |
term |
string |
utm_term — paid keywords (Google Ads search). |
content |
string |
utm_content — A/B differentiator. |
locationId |
string |
Location (sub-account) ID. Defaults to TOPLINE_LOCATION_ID env var if omitted. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_register_campaign_utm",
"arguments": {
"slug": "string",
"source": "string",
"medium": "string"
}
}
}
topline_set_marketing_config
#
Write the location's marketing config. WHOLE-BLOB REPLACE — pass the complete config object you want stored. To do a partial update, call topline_get_marketing_config first, merge your changes, then call this. Validates that `sources` and `mediums` are non-empty arrays of strings. Stored as JSON in the `_topline_marketing_config` custom value on this location.
Parameters
| Field | Type | Description |
config required |
object |
nested properties| Field | Type | Description |
sources required |
array<string> |
Allowed utm_source values (channels). |
mediums required |
array<string> |
Allowed utm_medium values. |
attribution |
object |
nested properties |
spend_rules |
array<object> |
item properties |
dashboard_layout |
object |
nested properties |
slack |
object |
nested properties |
|
locationId |
string |
Location (sub-account) ID. Defaults to TOPLINE_LOCATION_ID env var if omitted. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_set_marketing_config",
"arguments": {
"config": {
"sources": [
"string"
],
"mediums": [
"string"
],
"attribution": {},
"spend_rules": [
{}
],
"dashboard_layout": {},
"slack": {}
}
}
}
}
Spend
Read and reconcile channel spend and manage spend classification rules.
topline_add_spend_classification_rule
#
Append a spend classification rule. Each rule has a `when` matcher (merchant_regex / memo_regex / account_regex — at least one required) and a `classify_as` value (one of the tenant's configured sources). Rules are evaluated top-to-bottom; first match wins. To reorder or replace, use topline_set_marketing_config with the full rules array.
Parameters
| Field | Type | Description |
when required |
object |
nested properties| Field | Type | Description |
merchant_regex |
string |
Case-insensitive regex matched against merchant name. |
memo_regex |
string |
Case-insensitive regex matched against memo / description. |
account_regex |
string |
Case-insensitive regex matched against accounting category. |
|
classify_as required |
string |
Channel to assign — must be one of the tenant's configured sources. |
locationId |
string |
Location (sub-account) ID. Defaults to TOPLINE_LOCATION_ID env var if omitted. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_add_spend_classification_rule",
"arguments": {
"when": {
"merchant_regex": "string",
"memo_regex": "string",
"account_regex": "string"
},
"classify_as": "string"
}
}
}
topline_get_channel_spend
#
Per-channel spend rollup for a date range. Pulls transactions from configured providers, applies the tenant's spend classification rules from marketing_config, and aggregates by canonical channel. Unclassified transactions land in the 'needs_review' bucket and need either a rule (topline_add_spend_classification_rule) or manual reclassification.
Parameters
| Field | Type | Description |
since required |
string |
ISO date string (inclusive). |
until required |
string |
ISO date string (exclusive). |
provider |
string |
Filter to a single provider name. |
locationId |
string |
Location (sub-account) ID. Defaults to TOPLINE_LOCATION_ID env var if omitted. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_get_channel_spend",
"arguments": {
"since": "string",
"until": "string"
}
}
}
topline_list_spend_classification_rules
#
List the tenant's spend classification rules (from marketing_config.spend_rules).
Parameters
| Field | Type | Description |
locationId |
string |
Location (sub-account) ID. Defaults to TOPLINE_LOCATION_ID env var if omitted. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_list_spend_classification_rules",
"arguments": {
"locationId": "string"
}
}
}
topline_list_spend_providers
#
List all spend providers compiled into the MCP. Spend is sourced from the CRM's ad-publishing reporting endpoints — no third-party expense integration is required. Bundled providers: meta_ads, google_ads, linkedin_ads. Each provider is `configured: true` as long as PIT auth is present; whether it actually returns spend depends on the network being connected in the CRM Integrations UI for this location. Returns { providers: [{ name, configured }], configured_count }.
No parameters.
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_list_spend_providers",
"arguments": {}
}
}
topline_list_spend_transactions
#
Fetch raw spend transactions across configured providers within a date range. Each transaction includes provider, amount, merchant, date, memo, etc. Pass `provider` to filter to a single source (otherwise all configured providers are queried). Does NOT apply channel classification — use topline_get_channel_spend for the per-channel rollup.
Parameters
| Field | Type | Description |
since required |
string |
ISO date string (inclusive). |
until required |
string |
ISO date string (exclusive). |
provider |
string |
Filter to a single provider name (meta_ads / google_ads / linkedin_ads). Omit to query all configured. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_list_spend_transactions",
"arguments": {
"since": "string",
"until": "string"
}
}
}
topline_reconcile_spend
#
Reconcile totals across two providers for a date range — useful for cross-checking spend totals between ad networks or against an external source. Returns per-channel totals from each provider plus delta and a list of transactions present in one but not the other (best-effort match by date + amount + merchant).
Parameters
| Field | Type | Description |
since required |
string |
ISO date string (inclusive). |
until required |
string |
ISO date string (exclusive). |
provider_a required |
string |
First provider name (e.g. 'meta_ads'). |
provider_b required |
string |
Second provider name (e.g. 'google_ads'). |
locationId |
string |
Location (sub-account) ID. Defaults to TOPLINE_LOCATION_ID env var if omitted. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_reconcile_spend",
"arguments": {
"since": "string",
"until": "string",
"provider_a": "string",
"provider_b": "string"
}
}
}
Analytics (SQL)
Read-only SQL surface over the sub-account data warehouse. Worker-only.
Standard contact activity audit in a single call. Replaces the legacy fan-out of search_contacts → get_contact → search_opportunities → search_conversations → get_messages. Accepts an opaque contact ID OR a fuzzy identifier (email like 'jane@acme.com', phone like '+15551234567', or name like 'Jane Smith'); resolves it internally and echoes how it matched. Accepts since/until as 'this-week-et', 'now', RFC3339, YYYY-MM-DD, or relative shorthand (e.g. '90d', '24h'). Default since = 90d, until = now. Returns { contact, contactResolution, window, freshness, opportunities, activity, timeline, messages } where opportunities lists all deals for the contact with pipeline_name/stage_name/value/status (via opportunity_funnel), activity is a counts rollup by event_kind+direction over the window, timeline is per-event rows from contact_timeline within the window (messages + opportunities-created + appointments), and messages is the last N raw message bodies for context. PREFER THIS over topline_execute_query, topline_search_contacts, topline_search_conversations, or topline_get_messages for any 'what's going on with contact X' / 'what did Y say this month' / 'give me a brief on Z' question — it is faster, cheaper, and prevents the agent from inventing SQL the warehouse views already cover. Tasks and notes are NOT included (they are REST-only); drill down with topline_list_contact_tasks / topline_list_contact_notes if the user asks.
Parameters
| Field | Type | Description |
contact required |
string |
Contact identifier. Accepts opaque contact ID, email (jane@acme.com), phone (+15551234567 or local-format), or fuzzy name (e.g. 'Jane Smith', 'Acme Corp'). |
since |
string |
Window start. Default: 90 days ago. Accepts 'this-week-et', 'now', RFC3339, YYYY-MM-DD, or Nd/Nh shorthand. |
until |
string |
Window end. Default: now. Same format as `since`. |
message_limit |
number |
Max raw messages returned in the `messages` section. Default 20, max 100. |
timeline_limit |
number |
Max timeline events returned. Default 50, max 200. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_contact_audit",
"arguments": {
"contact": "string"
}
}
}
topline_describe_data_catalog
#
COMPLETE catalog of every Topline object that exists upstream — including objects we sync (queryable via SQL), objects we've catalogued but haven't built sync for yet, objects that require OAuth/agency scopes our PIT auth can't reach, and objects we've declined to sync. Call this when topline_describe_schema doesn't show something the user is asking about — it will tell you whether the data lives on disk (queryable now), is pending (answer will lag a sync cycle), or is inaccessible (tell the user to request it instead of inventing a workaround). Contrast with topline_describe_schema, which is SCHEMA-only and hides everything not currently exposed. Returns { entries: [{ name, category, status, description, sql_table?, endpoint?, notes? }...] } with status in {exposed, syncing, catalogued, requires_oauth, inaccessible, declined}.
No parameters.
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_describe_data_catalog",
"arguments": {}
}
}
topline_describe_schema
#
Overview of every table currently exposed to SQL queries in this sub-account's data warehouse. Returns table names, one-line descriptions, row counts, and a short SQLite-dialect cheat sheet. Call this FIRST when the user asks anything analytics-flavored ('how many', 'group by', 'trend', 'compare', 'duplicate'). It's cheap and tells you what's queryable. Follow up with topline_explain_tables on the ones you want to use, then topline_execute_query with the SQL.
No parameters.
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_describe_schema",
"arguments": {}
}
}
Run a read-only SQL query against this sub-account's SQLite warehouse. ONE SELECT or WITH...SELECT statement at a time. DDL, DML, PRAGMA, ATTACH, and admin commands are rejected by the parser before they reach the database. Results are capped at 5000 rows; larger result sets come back with truncated: true. Returns { columns, rows, elapsed_ms, truncated, effective_limit, rewritten_sql }. SQLite dialect — no DATE_TRUNC (use strftime), JSON columns need json_extract / json_each, timestamps are ISO 8601 strings that compare lexicographically.
Parameters
| Field | Type | Description |
query required |
string |
A single SELECT or WITH ... SELECT statement. Example: "SELECT status, COUNT(*) AS n FROM opportunities GROUP BY status ORDER BY n DESC" |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_execute_query",
"arguments": {
"query": "string"
}
}
}
Per-column detail for one or more tables returned by topline_describe_schema. Gives column names, SQLite types, nullability, JSON-column flags, enum values for closed-set text columns, foreign-key hints for joins, and approximate row counts. Call this before writing a SELECT so your WHERE / JOIN clauses use real column names and valid enum values. Rejects tables that aren't in the exposed set.
Parameters
| Field | Type | Description |
tables required |
array<string> |
One or more table names to explain |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_explain_tables",
"arguments": {
"tables": [
"string"
]
}
}
}
topline_find_references
#
Answer 'what uses X?' across synced CRM objects. Closed-enum dispatcher — runs hard-coded SQL per kind; no arbitrary SQL accepted. Supported kinds: tag, custom_field, custom_value, pipeline, pipeline_stage, calendar, user, contact, opportunity, form, survey. WORKFLOWS are NOT supported: the upstream platform's public API does not expose workflow internals, so we cannot know which workflows reference any given object. kind=opportunity returns ONLY direct references (the opportunity itself, its pipeline, stage, and contact) — it does NOT include downstream activity like messages or calls, since those belong to the contact and may span multiple opportunities. To get a contact's full activity, call this tool again with kind=contact using the contact_id from the opportunity's extra payload. Results are capped at 500 rows total (not per kind); truncated=true means upstream had more. For tags, accepts either the tag id or the tag name.
Parameters
| Field | Type | Description |
kind required |
"tag" | "custom_field" | "custom_value" | "pipeline" | "pipeline_stage" | "calendar" | "user" | "contact" | "opportunity" | "form" | "survey" |
|
id required |
string |
ID of the object to search references for (or name, for tags) |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_find_references",
"arguments": {
"kind": "tag",
"id": "string"
}
}
}
Owner-scoped activity audit in a single call. THE tool for any 'how is rep X doing' / 'rep snapshot for X' / 'what did X work on this week' / 'X's book' / 'who's most active' / 'is X caught up on their book' question. Replaces the legacy fan-out of topline_list_users → topline_search_opportunities(assignedTo=...) → topline_execute_query on pipeline_activity_window. Accepts an opaque user_id, email, or fuzzy name; resolves via REST /users/ once and echoes how it matched. Accepts since/until as 'this-week-et' (default since = 7d), 'now', RFC3339, YYYY-MM-DD, or relative shorthand. Optional `pipeline` arg (id or fuzzy name) scopes everything to one pipeline. Optional `stale_days` (default 14) defines the stale-ownership threshold. Returns { userId, ownerResolution, user, window, pipelineFilter, status, staleDays, freshness, book, bookByStage, activity, deals, staleOwnedDeals, crossAssignedTouches, movement }. TWO OWNERSHIP LENSES: `book` / `bookByStage` / `staleOwnedDeals` / `movement` use opportunities.assigned_to (deals owned by this user). `activity` / `deals` / `crossAssignedTouches` use messages.user_id / call_events.user_id (touches THIS USER personally logged). AUTOMATION FILTER: activity/deals/staleOwnedDeals/crossAssignedTouches all exclude messages where raw_payload.$.source IN ('campaign','workflow') — those are workflow blasts and bulk campaigns, not personal rep touches. Calls and appointments are always counted as rep activity (no automation noise there). staleOwnedDeals = opps in book with no rep-attributed touch in the last `stale_days` days, ordered by monetary_value DESC — this is the 'what's rotting in the rep's book' surface. crossAssignedTouches = deals THIS USER personally touched in window where assigned_to is someone else, ordered by unique_touches DESC — this is the 'helping someone else's book' surface. PREFER THIS over topline_execute_query for any owner-scoped question. NEVER hand-write CTEs for owner book + touches + stale + cross-assignment when this tool returns all four in one call.
Parameters
| Field | Type | Description |
owner required |
string |
Owner identifier. Accepts opaque user_id, email (jane@topline.com), or fuzzy name (e.g. 'Joey Skatell', 'paul'). |
pipeline |
string |
Optional pipeline filter (id or fuzzy name). When set, scopes everything to one pipeline. |
since |
string |
Window start. Default: 7 days ago. Accepts 'this-week-et', 'now', RFC3339, YYYY-MM-DD, or Nd/Nh shorthand. |
until |
string |
Window end. Default: now. Same format as `since`. |
status |
string |
Opportunity status filter for book/deals/movement/staleOwnedDeals: 'open' (default), 'won', 'lost', 'abandoned', or 'all'/'any' to skip filtering. |
limit |
number |
Max deals returned in `deals` / `staleOwnedDeals` / `crossAssignedTouches` sections. Default 25, max 100. (`book` is capped at 200, `bookByStage` is unbounded.) |
stale_days |
number |
Stale-ownership threshold in days. Default 14. A deal is 'stale' when no rep-attributed touch (excluding campaign/workflow automation) has landed within this many days. Set to 7 for a stricter cadence, 30 for low-velocity pipelines. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_owner_audit",
"arguments": {
"owner": "string"
}
}
}
Standard pipeline activity audit in a single call. Replaces the legacy 3-step flow (describe_schema → resolve pipeline name → hand-write SQL across pipeline_snapshot / pipeline_activity_window / pipeline_movement_window / warehouse_freshness). Accepts an opaque pipeline ID or a fuzzy name ('flex triage', 'qualified'); resolves the name internally and echoes how it matched. Accepts since/until as 'this-week-et' (default since = 7d), 'now', RFC3339, YYYY-MM-DD, or relative shorthand (e.g. '7d', '24h'). Returns { pipelineId, pipelineResolution, window, status, freshness, snapshot, activity, deals, movement } where activity uses unique_touches (deduped against source_id), deals carries per-deal touch breakdowns, and movement is stage/status changes inside the window. PREFER THIS over topline_execute_query for any 'what happened in pipeline X over window W' question — it is faster, cheaper, and prevents the agent from inventing SQL the audit views already cover.
Parameters
| Field | Type | Description |
pipeline required |
string |
Pipeline ID (opaque 20-char) or fuzzy name. |
since |
string |
Window start. Default: 7 days ago. Accepts 'this-week-et', 'now', RFC3339, YYYY-MM-DD, or Nd/Nh shorthand. |
until |
string |
Window end. Default: now. Same format as `since`. |
status |
string |
Opportunity status filter: 'open' (default), 'won', 'lost', 'abandoned', or 'all'/'any' to skip filtering. |
limit |
number |
Max deals returned in the `deals` section. Default 25, max 100. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_pipeline_audit",
"arguments": {
"pipeline": "string"
}
}
}
topline_pipeline_snapshot
#
Open opportunity count, pipeline value, and stage distribution for one pipeline. Single-call equivalent of `topline --agent query snapshot --pipeline ... --status open`. Accepts either an opaque 20-char pipeline ID or a fuzzy pipeline name (e.g. 'flex triage', 'qualified'); on 0 or >1 matches it errors with the candidate list. Use this when the user wants a snapshot without activity/movement detail. Returns { pipelineId, pipelineResolution, status, snapshot }.
Parameters
| Field | Type | Description |
pipeline required |
string |
Pipeline ID (opaque 20-char) or fuzzy name (e.g. 'flex triage', 'qualified'). |
status |
string |
Opportunity status filter: 'open' (default), 'won', 'lost', 'abandoned', or 'all'/'any' to skip filtering. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_pipeline_snapshot",
"arguments": {
"pipeline": "string"
}
}
}
Deterministic readiness probe for the SQL warehouse surface. Confirms the schema endpoint is reachable, lists which expected tables are present, and reports any coverage gaps as actionable bugs (not as a reason to fall back to REST). Run this once at the start of any standard pipeline audit; if the report is green, proceed to topline_pipeline_audit. Returns { schemaReachable, tableCount, expectedTables, missingTables, recommendation }.
No parameters.
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_query_doctor",
"arguments": {}
}
}
Describes the HTTP query API you can point Looker Studio, Retool, Lovable, Claude Code, n8n, or curl at for live-data dashboards. Returns URL shapes, auth format, example curl commands, and guidance for wiring up a dashboard. Use this when the user asks about building dashboards, embedding the data in another tool, or when a query is too complex for chat and they'd rather save it as a saved view.
No parameters.
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_utilize_api",
"arguments": {}
}
}
topline_warehouse_freshness
#
Per-table sync freshness probe for the warehouse tables that drive pipeline audits. Returns row_count, last_synced_at, and lag_seconds for each tracked table. Call this when the user asks whether warehouse data is current, or when a pipeline audit shows stale numbers and you need to attribute it to sync lag versus coverage gaps. Cheap, no arguments.
No parameters.
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "topline_warehouse_freshness",
"arguments": {}
}
}