Bellaso Agent API

Tools that only read data


Data coverage

POST
https://dtrgbxembnbwlmpvhhms.supabase.co/functions/v1/cortex-mcp
/api/v1/tools/get_data_coverage
Bearer (ck_ endpoint token)

Which analytics modules this organization has (entitlements) and which actually have data flowing, with the latest date per surface. CALL THIS FIRST in a new session, and any time you are unsure whether a data surface exists for this org — entitled-but-empty and has-data-but-lapsed are both real states, and every other tool's availability follows from what this returns.

Data coverage › Request Body

Data coverage › Responses

The tool ran

ok
​boolean · const · required
Const value:
tool
​string · required
data
​required

The tool's payload — byte-identical to what the same tool returns over MCP.


Metric definitions

POST
https://dtrgbxembnbwlmpvhhms.supabase.co/functions/v1/cortex-mcp
/api/v1/tools/get_metric_definitions
Bearer (ck_ endpoint token)

What this organization's custom metric slots (metric_1..metric_10) count, with each metric's name, abbreviation, description, type and display format — plus whether its conversion numbers come from its CRM or from ad-platform pixels. Read this BEFORE interpreting or ranking by any metric_N column: the slots mean different things per organization (for CRM-source orgs metric_1 is typically MQLs from Salesforce/HubSpot, not a platform pixel conversion).

Metric definitions › Request Body

Metric definitions › Responses

The tool ran

ok
​boolean · const · required
Const value:
tool
​string · required
data
​required

The tool's payload — byte-identical to what the same tool returns over MCP.


Context pack

POST
https://dtrgbxembnbwlmpvhhms.supabase.co/functions/v1/cortex-mcp
/api/v1/tools/get_context_pack
Bearer (ck_ endpoint token)

The full operating contract for this API as one markdown document: how the platform defines its metrics (Monday-start weeks, ROAS as total revenue over total spend, rate metrics recomputed from summed components rather than averaged, the display-format and ad-network vocabularies), the grounding rules your answers must follow, the BigQuery marts behind each tool with their documented columns and grains, and the full tool reference. LOAD THIS ONCE at the start of a session, before answering any question about this organization's numbers — it is what stops a correct-looking figure from being computed the wrong way. It is static per deployment: cache it against the returned meta.version and re-fetch only when that changes.

Context pack › Request Body

Context pack › Responses

The tool ran

ok
​boolean · const · required
Const value:
tool
​string · required
data
​required

The tool's payload — byte-identical to what the same tool returns over MCP.


Ad performance summary

POST
https://dtrgbxembnbwlmpvhhms.supabase.co/functions/v1/cortex-mcp
/api/v1/tools/get_performance_summary
Bearer (ck_ endpoint token)

Organization-wide paid-ad totals for one window: spend, impressions, clicks, ctr, cpm, cpc, roas, fatigue_score and this organization's custom metrics (metric_1..metric_10). This is the grounding call for "how are we doing" — start here, then drill in with the per-entity tools. Optional filters narrow to one product, network, ad account or campaign. Omit both dates for the default window: the last 30 complete days ending yesterday. Recompute rates (ctr, cpc, cpm, roas) from summed numerators and denominators — ROAS is total revenue ÷ total spend over the window. Never average the per-row rate columns. Read get_metric_definitions before interpreting or comparing any metric_N column: the slots mean different things per organization.

Ad performance summary › Request Body

start_date
​string · pattern: ^\d{4}-\d{2}-\d{2}$

Window start, YYYY-MM-DD (inclusive). Omit both dates for the default window: the last 30 complete days ending yesterday.

end_date
​string · pattern: ^\d{4}-\d{2}-\d{2}$

Window end, YYYY-MM-DD (inclusive).

product_id
​string · minLength: 1 · maxLength: 128

Filter to one product id from the org context.

ad_network_id
​string · minLength: 1 · maxLength: 64

Filter to one network: facebook_ads | google_ads | tiktok_ads | linkedin_ads | bingads.

account_id
​string · minLength: 1 · maxLength: 128

Filter to one ad account id.

campaign_id
​string · minLength: 1 · maxLength: 128

Filter to one campaign id.

Ad performance summary › Responses

The tool ran

ok
​boolean · const · required
Const value:
tool
​string · required
data
​required

The tool's payload — byte-identical to what the same tool returns over MCP.


Daily ad performance

POST
https://dtrgbxembnbwlmpvhhms.supabase.co/functions/v1/cortex-mcp
/api/v1/tools/get_daily_performance
Bearer (ck_ endpoint token)

Per-day paid-ad performance series for a window, filterable to one product, network, ad account, campaign, ad set or ad. Use it for trends, pacing and "what changed on ". Omit both dates for the default window: the last 30 complete days ending yesterday. Rows are complete days. If you bucket days into weeks, use MONDAY-start weeks — that is the week boundary the Bellaso app and every other report in this product use. Recompute rates (ctr, cpc, cpm, roas) from summed numerators and denominators — ROAS is total revenue ÷ total spend over the window. Never average the per-row rate columns.

Daily ad performance › Request Body

start_date
​string · pattern: ^\d{4}-\d{2}-\d{2}$

Window start, YYYY-MM-DD (inclusive). Omit both dates for the default window: the last 30 complete days ending yesterday.

end_date
​string · pattern: ^\d{4}-\d{2}-\d{2}$

Window end, YYYY-MM-DD (inclusive).

product_id
​string · minLength: 1 · maxLength: 128

Filter to one product id from the org context.

ad_network_id
​string · minLength: 1 · maxLength: 64

Filter to one network: facebook_ads | google_ads | tiktok_ads | linkedin_ads | bingads.

account_id
​string · minLength: 1 · maxLength: 128

Filter to one ad account id.

campaign_id
​string · minLength: 1 · maxLength: 128

Filter to one campaign id.

adset_id
​string · minLength: 1 · maxLength: 128

Filter to one ad set id.

ad_id
​string · minLength: 1 · maxLength: 128

Filter to one ad id.

Daily ad performance › Responses

The tool ran

ok
​boolean · const · required
Const value:
tool
​string · required
data
​required

The tool's payload — byte-identical to what the same tool returns over MCP.


Performance by ad account

POST
https://dtrgbxembnbwlmpvhhms.supabase.co/functions/v1/cortex-mcp
/api/v1/tools/get_accounts_performance
Bearer (ck_ endpoint token)

Paid-ad performance rolled up per ad account, including this organization's custom KPI counts and values. Use it to compare accounts or to find which account carries the spend. For any 'top / most / best by X' question pass sort_by AND limit: the full row set is ranked server-side before the slice, so the answer arrives in one call instead of several narrowing ones. An invalid sort_by comes back with the list of valid columns, so you can retry in one step. Omit both dates for the default window: the last 30 complete days ending yesterday. Recompute rates (ctr, cpc, cpm, roas) from summed numerators and denominators — ROAS is total revenue ÷ total spend over the window. Never average the per-row rate columns.

Performance by ad account › Request Body

start_date
​string · pattern: ^\d{4}-\d{2}-\d{2}$

Window start, YYYY-MM-DD (inclusive). Omit both dates for the default window: the last 30 complete days ending yesterday.

end_date
​string · pattern: ^\d{4}-\d{2}-\d{2}$

Window end, YYYY-MM-DD (inclusive).

product_id
​string · minLength: 1 · maxLength: 128

Filter to one product id from the org context.

ad_network_id
​string · minLength: 1 · maxLength: 64

Filter to one network: facebook_ads | google_ads | tiktok_ads | linkedin_ads | bingads.

account_id
​string · minLength: 1 · maxLength: 128

Filter to one ad account id.

campaign_id
​string · minLength: 1 · maxLength: 128

Filter to one campaign id.

sort_by
​string · minLength: 1 · maxLength: 64

Sort rows by this column, descending, before returning. Best on numeric metric columns: spend, impressions, clicks, ctr, cpc, cpm, roas, metric_1..metric_10 (for CRM-source orgs metric_1 = MQLs — see get_metric_definitions). An invalid value returns the list of valid columns so you can retry in one step.

limit
​integer · min: 1 · max: 200

Max rows to return after sorting (default 50, max 200).

Performance by ad account › Responses

The tool ran

ok
​boolean · const · required
Const value:
tool
​string · required
data
​required

The tool's payload — byte-identical to what the same tool returns over MCP.


Performance by campaign

POST
https://dtrgbxembnbwlmpvhhms.supabase.co/functions/v1/cortex-mcp
/api/v1/tools/get_campaigns_performance
Bearer (ck_ endpoint token)

Paid-ad performance rolled up per campaign — "top campaigns", "which campaigns are underperforming", "where did the spend go". Filter to one network or account first when the question is scoped that way. For any 'top / most / best by X' question pass sort_by AND limit: the full row set is ranked server-side before the slice, so the answer arrives in one call instead of several narrowing ones. An invalid sort_by comes back with the list of valid columns, so you can retry in one step. Omit both dates for the default window: the last 30 complete days ending yesterday. Recompute rates (ctr, cpc, cpm, roas) from summed numerators and denominators — ROAS is total revenue ÷ total spend over the window. Never average the per-row rate columns.

Performance by campaign › Request Body

start_date
​string · pattern: ^\d{4}-\d{2}-\d{2}$

Window start, YYYY-MM-DD (inclusive). Omit both dates for the default window: the last 30 complete days ending yesterday.

end_date
​string · pattern: ^\d{4}-\d{2}-\d{2}$

Window end, YYYY-MM-DD (inclusive).

product_id
​string · minLength: 1 · maxLength: 128

Filter to one product id from the org context.

ad_network_id
​string · minLength: 1 · maxLength: 64

Filter to one network: facebook_ads | google_ads | tiktok_ads | linkedin_ads | bingads.

account_id
​string · minLength: 1 · maxLength: 128

Filter to one ad account id.

campaign_id
​string · minLength: 1 · maxLength: 128

Filter to one campaign id.

sort_by
​string · minLength: 1 · maxLength: 64

Sort rows by this column, descending, before returning. Best on numeric metric columns: spend, impressions, clicks, ctr, cpc, cpm, roas, metric_1..metric_10 (for CRM-source orgs metric_1 = MQLs — see get_metric_definitions). An invalid value returns the list of valid columns so you can retry in one step.

limit
​integer · min: 1 · max: 200

Max rows to return after sorting (default 50, max 200).

Performance by campaign › Responses

The tool ran

ok
​boolean · const · required
Const value:
tool
​string · required
data
​required

The tool's payload — byte-identical to what the same tool returns over MCP.


Performance by ad set

POST
https://dtrgbxembnbwlmpvhhms.supabase.co/functions/v1/cortex-mcp
/api/v1/tools/get_adsets_performance
Bearer (ck_ endpoint token)

Paid-ad performance rolled up per ad set, optionally inside one campaign (campaign_id) or for one ad set (adset_id). Use it after a campaign-level answer, to see which audience or placement inside the campaign is doing the work. For any 'top / most / best by X' question pass sort_by AND limit: the full row set is ranked server-side before the slice, so the answer arrives in one call instead of several narrowing ones. An invalid sort_by comes back with the list of valid columns, so you can retry in one step. Omit both dates for the default window: the last 30 complete days ending yesterday. Recompute rates (ctr, cpc, cpm, roas) from summed numerators and denominators — ROAS is total revenue ÷ total spend over the window. Never average the per-row rate columns.

Performance by ad set › Request Body

start_date
​string · pattern: ^\d{4}-\d{2}-\d{2}$

Window start, YYYY-MM-DD (inclusive). Omit both dates for the default window: the last 30 complete days ending yesterday.

end_date
​string · pattern: ^\d{4}-\d{2}-\d{2}$

Window end, YYYY-MM-DD (inclusive).

product_id
​string · minLength: 1 · maxLength: 128

Filter to one product id from the org context.

ad_network_id
​string · minLength: 1 · maxLength: 64

Filter to one network: facebook_ads | google_ads | tiktok_ads | linkedin_ads | bingads.

account_id
​string · minLength: 1 · maxLength: 128

Filter to one ad account id.

campaign_id
​string · minLength: 1 · maxLength: 128

Filter to one campaign id.

adset_id
​string · minLength: 1 · maxLength: 128

Filter to one ad set id.

sort_by
​string · minLength: 1 · maxLength: 64

Sort rows by this column, descending, before returning. Best on numeric metric columns: spend, impressions, clicks, ctr, cpc, cpm, roas, metric_1..metric_10 (for CRM-source orgs metric_1 = MQLs — see get_metric_definitions). An invalid value returns the list of valid columns so you can retry in one step.

limit
​integer · min: 1 · max: 200

Max rows to return after sorting (default 50, max 200).

Performance by ad set › Responses

The tool ran

ok
​boolean · const · required
Const value:
tool
​string · required
data
​required

The tool's payload — byte-identical to what the same tool returns over MCP.


Performance by ad

POST
https://dtrgbxembnbwlmpvhhms.supabase.co/functions/v1/cortex-mcp
/api/v1/tools/get_ads_performance
Bearer (ck_ endpoint token)

Paid-ad performance rolled up per individual ad. Ad grain exists for facebook_ads, linkedin_ads and tiktok_ads only — other networks do not report it, so an empty result for google_ads or bingads is expected rather than a data problem. For CRM-source organizations these rows are CRM-attributed at ad grain and match the platform's Ads page, which makes this THE authoritative source for per-ad and per-creative MQL ranking: rank by metric_1 (see get_metric_definitions). Never take that ranking from get_creative_fatigue or get_creative_leaderboard — their conversion columns are platform-pixel and near zero by design for those organizations. For any 'top / most / best by X' question pass sort_by AND limit: the full row set is ranked server-side before the slice, so the answer arrives in one call instead of several narrowing ones. An invalid sort_by comes back with the list of valid columns, so you can retry in one step. Omit both dates for the default window: the last 30 complete days ending yesterday.

Performance by ad › Request Body

start_date
​string · pattern: ^\d{4}-\d{2}-\d{2}$

Window start, YYYY-MM-DD (inclusive). Omit both dates for the default window: the last 30 complete days ending yesterday.

end_date
​string · pattern: ^\d{4}-\d{2}-\d{2}$

Window end, YYYY-MM-DD (inclusive).

product_id
​string · minLength: 1 · maxLength: 128

Filter to one product id from the org context.

ad_network_id
​string · minLength: 1 · maxLength: 64

Filter to one network: facebook_ads | google_ads | tiktok_ads | linkedin_ads | bingads.

account_id
​string · minLength: 1 · maxLength: 128

Filter to one ad account id.

campaign_id
​string · minLength: 1 · maxLength: 128

Filter to one campaign id.

adset_id
​string · minLength: 1 · maxLength: 128

Filter to one ad set id.

sort_by
​string · minLength: 1 · maxLength: 64

Sort rows by this column, descending, before returning. Best on numeric metric columns: spend, impressions, clicks, ctr, cpc, cpm, roas, metric_1..metric_10 (for CRM-source orgs metric_1 = MQLs — see get_metric_definitions). An invalid value returns the list of valid columns so you can retry in one step.

limit
​integer · min: 1 · max: 200

Max rows to return after sorting (default 50, max 200).

Performance by ad › Responses

The tool ran

ok
​boolean · const · required
Const value:
tool
​string · required
data
​required

The tool's payload — byte-identical to what the same tool returns over MCP.


Performance by keyword

POST
https://dtrgbxembnbwlmpvhhms.supabase.co/functions/v1/cortex-mcp
/api/v1/tools/get_keywords_performance
Bearer (ck_ endpoint token)

Keyword-level performance with match_type, for google_ads and bingads only (the social networks have no keyword grain, so filtering this to one of them returns nothing by design). Filter with campaign_id / adset_id to scope to one ad group, or keyword_id for a single keyword. For any 'top / most / best by X' question pass sort_by AND limit: the full row set is ranked server-side before the slice, so the answer arrives in one call instead of several narrowing ones. An invalid sort_by comes back with the list of valid columns, so you can retry in one step. Omit both dates for the default window: the last 30 complete days ending yesterday.

Performance by keyword › Request Body

start_date
​string · pattern: ^\d{4}-\d{2}-\d{2}$

Window start, YYYY-MM-DD (inclusive). Omit both dates for the default window: the last 30 complete days ending yesterday.

end_date
​string · pattern: ^\d{4}-\d{2}-\d{2}$

Window end, YYYY-MM-DD (inclusive).

product_id
​string · minLength: 1 · maxLength: 128

Filter to one product id from the org context.

ad_network_id
​string · minLength: 1 · maxLength: 64

Filter to one network: facebook_ads | google_ads | tiktok_ads | linkedin_ads | bingads.

account_id
​string · minLength: 1 · maxLength: 128

Filter to one ad account id.

campaign_id
​string · minLength: 1 · maxLength: 128

Filter to one campaign id.

adset_id
​string · minLength: 1 · maxLength: 128

Filter to one ad set id.

keyword_id
​string · minLength: 1 · maxLength: 128

Filter to one keyword id.

sort_by
​string · minLength: 1 · maxLength: 64

Sort rows by this column, descending, before returning. Best on numeric metric columns: spend, impressions, clicks, ctr, cpc, cpm, roas, metric_1..metric_10 (for CRM-source orgs metric_1 = MQLs — see get_metric_definitions). An invalid value returns the list of valid columns so you can retry in one step.

limit
​integer · min: 1 · max: 200

Max rows to return after sorting (default 50, max 200).

Performance by keyword › Responses

The tool ran

ok
​boolean · const · required
Const value:
tool
​string · required
data
​required

The tool's payload — byte-identical to what the same tool returns over MCP.


Performance by geography

POST
https://dtrgbxembnbwlmpvhhms.supabase.co/functions/v1/cortex-mcp
/api/v1/tools/get_geo_performance
Bearer (ck_ endpoint token)

Country-level spend, clicks and conversions, rolled up either by ad account (level="account", the default) or by campaign (level="campaign"). country_code narrows to a single country. Coverage depends on what each network reports geographically, so a country missing from the rows means "not reported", not "zero". Omit both dates for the default window: the last 30 complete days ending yesterday.

Performance by geography › Request Body

start_date
​string · pattern: ^\d{4}-\d{2}-\d{2}$

Window start, YYYY-MM-DD (inclusive). Omit both dates for the default window: the last 30 complete days ending yesterday.

end_date
​string · pattern: ^\d{4}-\d{2}-\d{2}$

Window end, YYYY-MM-DD (inclusive).

product_id
​string · minLength: 1 · maxLength: 128

Filter to one product id from the org context.

ad_network_id
​string · minLength: 1 · maxLength: 64

Filter to one network: facebook_ads | google_ads | tiktok_ads | linkedin_ads | bingads.

account_id
​string · minLength: 1 · maxLength: 128

Filter to one ad account id.

campaign_id
​string · minLength: 1 · maxLength: 128

Filter to one campaign id.

level
​string · enum

Rollup grain: 'account' (default) or 'campaign'.

Enum values:
account
campaign
country_code
​string · minLength: 2 · maxLength: 3 · pattern: ^[A-Za-z]{2,3}$

Filter to one country, as its 2- or 3-letter code (e.g. US).

Performance by geography › Responses

The tool ran

ok
​boolean · const · required
Const value:
tool
​string · required
data
​required

The tool's payload — byte-identical to what the same tool returns over MCP.


Fatigued ads

POST
https://dtrgbxembnbwlmpvhhms.supabase.co/functions/v1/cortex-mcp
/api/v1/tools/get_creative_fatigue
Bearer (ck_ endpoint token)

Ads whose creative fatigue score is elevated, highest first — the tool for "which ads are burning out / need a refresh". The score adds a CTR-decay component (up to 50), an impression-pressure component (up to 30) and a creative-age component (up to 20), and an ad younger than 7 days always scores 0. min_score defaults to 30; only ads with spend in the window are considered, and at most 200 rows come back. This reads engagement and delivery metrics plus PLATFORM-PIXEL conversions: for CRM-source organizations the conversion columns here are near zero by design, so never rank creatives by MQL or lead volume with this tool — use get_ads_performance. Omit both dates for the default window: the last 30 complete days ending yesterday.

Fatigued ads › Request Body

start_date
​string · pattern: ^\d{4}-\d{2}-\d{2}$

Window start, YYYY-MM-DD (inclusive). Omit both dates for the default window: the last 30 complete days ending yesterday.

end_date
​string · pattern: ^\d{4}-\d{2}-\d{2}$

Window end, YYYY-MM-DD (inclusive).

ad_network_id
​string · minLength: 1 · maxLength: 64

Filter to one network: facebook_ads | google_ads | tiktok_ads | linkedin_ads | bingads.

min_score
​number · min: 0 · max: 100

Minimum fatigue score to include, 0-100 (default 30).

Fatigued ads › Responses

The tool ran

ok
​boolean · const · required
Const value:
tool
​string · required
data
​required

The tool's payload — byte-identical to what the same tool returns over MCP.


Creative leaderboard

POST
https://dtrgbxembnbwlmpvhhms.supabase.co/functions/v1/cortex-mcp
/api/v1/tools/get_creative_leaderboard
Bearer (ck_ endpoint token)

Per-creative leaderboard with winner / mid / loser labels, trend, spend, CTR, KPI count, cost per KPI and the extracted creative attributes (visual style, messaging angle, density, specificity, human presence, subject elements) — the tool for "what is working creatively" and "what do our winners have in common". window_days accepts only 30, 60, 90 or 120 (attributes are precomputed nightly for those windows); it takes no start_date/end_date. Its metrics are ad-platform reported, so for CRM-source organizations the KPI columns are near zero by design — rank creatives by MQL with get_ads_performance instead. Requires the Creative module: without it this returns a clean "not part of this organization's plan" refusal rather than empty data.

Creative leaderboard › Request Body

window_days
​number · enum

Lookback window in days. Only 30, 60, 90 and 120 exist (the attributes are precomputed nightly for those windows); default 90.

Enum values:
30
60
90
120
sort
​string · enum

Ranking column (default cost_per_kpi). cost_per_kpi orders cheapest-first (best first); spend, ctr and kpis order highest-first.

Enum values:
cost_per_kpi
spend
ctr
kpis
limit
​integer · min: 1 · max: 100

Rows to return (default 25, max 100).

Creative leaderboard › Responses

The tool ran

ok
​boolean · const · required
Const value:
tool
​string · required
data
​required

The tool's payload — byte-identical to what the same tool returns over MCP.


All channels

POST
https://dtrgbxembnbwlmpvhhms.supabase.co/functions/v1/cortex-mcp
/api/v1/tools/get_channels
Bearer (ck_ endpoint token)

Cross-channel performance from the unified channel_daily mart, which unions paid ads, email, organic social, GA4 web sessions, ecommerce orders and Signal conversions onto ONE canonical channel grain: Paid Search, Paid Social, Paid Other, Organic Search, Organic Social, Email, Direct, Referral, Affiliate, Other. This is the tool for channel mix, blended CAC/ROAS and any "which channel" question — the per-platform tools cannot be added up into these numbers. mode=overview returns per-channel spend, impressions, clicks, sends, delivered, opens, reach, views, engagements, followers, sessions and key_events, plus a picked conversions and revenue with cac and roas, the native reach/engagement metric with its label, a per-platform breakdown and prior-period deltas, with a totals row spanning all channels. mode=daily returns the per-day, per-channel spend / sessions / conversions / revenue series. conversions is picked orders → Signal → GA4 key events and revenue order_revenue → signal_revenue → ga4_revenue, applied consistently across channels, so the comparison is like for like — say which basis you are quoting. There are no filters beyond the window. Omit both dates for the default window: the last 30 complete days ending yesterday. If you bucket the daily series into weeks, use MONDAY-start weeks, the boundary the rest of this product uses.

All channels › Request Body

mode
​string · enum · required

overview = per-channel totals with deltas and a totals row; daily = the per-day, per-channel series.

Enum values:
overview
daily
start_date
​string · pattern: ^\d{4}-\d{2}-\d{2}$

Window start, YYYY-MM-DD (inclusive). Omit both dates for the default window: the last 30 complete days ending yesterday.

end_date
​string · pattern: ^\d{4}-\d{2}-\d{2}$

Window end, YYYY-MM-DD (inclusive).

All channels › Responses

The tool ran

ok
​boolean · const · required
Const value:
tool
​string · required
data
​required

The tool's payload — byte-identical to what the same tool returns over MCP.


GA4 web analytics

POST
https://dtrgbxembnbwlmpvhhms.supabase.co/functions/v1/cortex-mcp
/api/v1/tools/get_ga4
Bearer (ck_ endpoint token)

Google Analytics 4 web analytics for this organization. Pick the mode for the question: summary (sessions / users / conversions totals), daily (per-day series), traffic_sources (by source and medium), campaigns (by GA4 campaign), channels (GA4's default channel grouping), engagement (sessions, bounce and duration by channel), key_events (GA4 conversion events), landing_pages, or geo_devices (device category and geography). These are GA4's own session-scoped, GA4-attributed numbers: they will NOT tie out to ad-platform clicks or to the paid-ads tools, and GA4 channel groupings are not the Bellaso channel groupings — use get_channels for cross-channel comparison and say which source you are quoting. property_id limits to one property when several are connected. Omit both dates for the default window: the last 30 complete days ending yesterday. Weeks are MONDAY-start if you bucket the daily series.

GA4 web analytics › Request Body

mode
​string · enum · required

Which GA4 cut to return — see the tool description for each.

Enum values:
summary
daily
traffic_sources
campaigns
channels
engagement
key_events
landing_pages
start_date
​string · pattern: ^\d{4}-\d{2}-\d{2}$

Window start, YYYY-MM-DD (inclusive). Omit both dates for the default window: the last 30 complete days ending yesterday.

end_date
​string · pattern: ^\d{4}-\d{2}-\d{2}$

Window end, YYYY-MM-DD (inclusive).

property_id
​string · minLength: 1 · maxLength: 64 · pattern: ^[A-Za-z0-9_-]+$

Limit to one GA4 property id. Omit (or pass "all") to cover every connected property.

GA4 web analytics › Responses

The tool ran

ok
​boolean · const · required
Const value:
tool
​string · required
data
​required

The tool's payload — byte-identical to what the same tool returns over MCP.


Email marketing

POST
https://dtrgbxembnbwlmpvhhms.supabase.co/functions/v1/cortex-mcp
/api/v1/tools/get_email
Bearer (ck_ endpoint token)

Email marketing analytics from the email_campaigns mart. Pick the mode: summary (sends, delivered, opens, clicks, unsubscribes, bounces with prior-period deltas), daily (per-day series), campaigns (the per-campaign table — sortable with sort_by/sort_dir, searchable with search over subject and campaign name, paged with limit/offset), subject_lines (subject leaderboard plus open/click rates broken out by subject feature, length bucket, weekday, hour and split test; min_sends gates who reaches the leaderboard), or filter_options (all-time campaign types, lists, sources and the available date range — call this first when you need a valid filter value). Filters: campaign_type (exact), list_name (substring), source (exact). Open rates are inflated by privacy proxies on some clients — treat click-through and CTOR as the reliable engagement signals, and never present open rate as a deliverability measure. Omit both dates for the default window: the last 30 complete days ending yesterday.

Email marketing › Request Body

mode
​string · enum · required

Which email cut to return — see the tool description for each.

Enum values:
summary
daily
campaigns
subject_lines
filter_options
start_date
​string · pattern: ^\d{4}-\d{2}-\d{2}$

Window start, YYYY-MM-DD (inclusive). Omit both dates for the default window: the last 30 complete days ending yesterday.

end_date
​string · pattern: ^\d{4}-\d{2}-\d{2}$

Window end, YYYY-MM-DD (inclusive).

campaign_type
​string · minLength: 1 · maxLength: 200 · pattern: ^[^'\\]+$

Filter to one campaign type (exact match; get the available values from mode=filter_options).

list_name
​string · minLength: 1 · maxLength: 200 · pattern: ^[^'\\]+$

Filter to campaigns sent to a list whose name CONTAINS this text (substring match).

source
​string · minLength: 1 · maxLength: 200 · pattern: ^[^'\\]+$

Filter to one email source/connector (exact match).

sort_by
​string · minLength: 1 · maxLength: 64

campaigns mode: sort column — sent_at | sends | delivered | unique_opens | unique_clicks | open_rate | click_rate | ctor | unsub_rate | bounce_rate | campaign_name | subject (default sent_at). An invalid value returns the allowed list.

sort_dir
​string · enum

Sort direction for the table mode (default desc).

Enum values:
asc
desc
limit
​integer · min: 1 · max: 500

Table mode: rows to return, 1-500 (default 25).

offset
​integer · min: 0 · max: 100000

Table mode: rows to skip, for paging (default 0).

search
​string · minLength: 1 · maxLength: 200

campaigns mode: case-insensitive match on the subject or campaign name.

min_sends
​integer · min: 0 · max: 100000

subject_lines mode: minimum total sends before a subject enters the leaderboard (default 100; 0 removes the gate). Lower it for a low-volume sender.

Email marketing › Responses

The tool ran

ok
​boolean · const · required
Const value:
tool
​string · required
data
​required

The tool's payload — byte-identical to what the same tool returns over MCP.


Organic social

POST
https://dtrgbxembnbwlmpvhhms.supabase.co/functions/v1/cortex-mcp
/api/v1/tools/get_organic
Bearer (ck_ endpoint token)

Organic (unpaid) social analytics from the organic_social_daily and organic_social_posts marts — Facebook Pages and Instagram Business accounts today. Pick the mode: summary (followers, follower_change, reach, views, engagements, likes/comments/shares/saves, link_clicks, posts_published and engagement_rate, with prior-period deltas), daily (per-day series), accounts (per-account rollup with the latest follower count, ordered by reach), posts (the per-post table — sortable with sort_by/sort_dir, searchable with search over the caption, filterable by media_type, paged with limit/offset), or filter_options (all-time platforms, accounts, media types and the available date range). followers is the LATEST per-account count inside the window, never a sum — do not add it across days or accounts. These are unpaid metrics only: paid social lives in the ads tools, and get_channels is what compares the two. Filters: platform (facebook | instagram), account_id (exact). Omit both dates for the default window: the last 30 complete days ending yesterday.

Organic social › Request Body

mode
​string · enum · required

Which organic-social cut to return — see the tool description for each.

Enum values:
summary
daily
accounts
posts
filter_options
start_date
​string · pattern: ^\d{4}-\d{2}-\d{2}$

Window start, YYYY-MM-DD (inclusive). Omit both dates for the default window: the last 30 complete days ending yesterday.

end_date
​string · pattern: ^\d{4}-\d{2}-\d{2}$

Window end, YYYY-MM-DD (inclusive).

platform
​string · enum

Filter to one platform.

Enum values:
facebook
instagram
account_id
​string · minLength: 1 · maxLength: 200 · pattern: ^[^'\\]+$

Filter to one social account id (exact; get ids from mode=accounts or mode=filter_options).

sort_by
​string · minLength: 1 · maxLength: 64

posts mode: sort column — published_at | reach | views | likes | comments | shares | saves | engagements | engagement_rate (default published_at). An invalid value returns the allowed list.

sort_dir
​string · enum

Sort direction for the table mode (default desc).

Enum values:
asc
desc
limit
​integer · min: 1 · max: 500

Table mode: rows to return, 1-500 (default 25).

offset
​integer · min: 0 · max: 100000

Table mode: rows to skip, for paging (default 0).

search
​string · minLength: 1 · maxLength: 200

posts mode: case-insensitive match on the post caption.

media_type
​string · minLength: 1 · maxLength: 200 · pattern: ^[^'\\]+$

posts mode: filter to one media type (e.g. IMAGE, VIDEO, CAROUSEL_ALBUM, REEL, STORY).

Organic social › Responses

The tool ran

ok
​boolean · const · required
Const value:
tool
​string · required
data
​required

The tool's payload — byte-identical to what the same tool returns over MCP.


Performance forecast

POST
https://dtrgbxembnbwlmpvhhms.supabase.co/functions/v1/cortex-mcp
/api/v1/tools/get_forecast
Bearer (ck_ endpoint token)

Projected daily performance from the forecast mart (BigQuery AI.FORECAST fitted over recent actuals), organization-wide or filtered to one product, network, account or campaign. mode=summary (default) returns projected totals for the window; mode=daily returns the projected per-day series. These are MODEL PROJECTIONS, not observed data: label them as forecasts, never add them into an actuals total, and do not present a projected value as something that happened. The mart holds a short FORWARD horizon (about a week ahead, rebuilt nightly), and the window simply selects which of those days come back — a window entirely in the past returns nothing, which is expected rather than a failure. Omit both dates for the default window: the last 30 complete days ending yesterday.

Performance forecast › Request Body

start_date
​string · pattern: ^\d{4}-\d{2}-\d{2}$

Window start, YYYY-MM-DD (inclusive). Omit both dates for the default window: the last 30 complete days ending yesterday.

end_date
​string · pattern: ^\d{4}-\d{2}-\d{2}$

Window end, YYYY-MM-DD (inclusive).

product_id
​string · minLength: 1 · maxLength: 128

Filter to one product id from the org context.

ad_network_id
​string · minLength: 1 · maxLength: 64

Filter to one network: facebook_ads | google_ads | tiktok_ads | linkedin_ads | bingads.

account_id
​string · minLength: 1 · maxLength: 128

Filter to one ad account id.

campaign_id
​string · minLength: 1 · maxLength: 128

Filter to one campaign id.

mode
​string · enum

summary (default) = projected totals for the window; daily = the projected per-day series.

Enum values:
summary
daily

Performance forecast › Responses

The tool ran

ok
​boolean · const · required
Const value:
tool
​string · required
data
​required

The tool's payload — byte-identical to what the same tool returns over MCP.


Signal CAC by channel

POST
https://dtrgbxembnbwlmpvhhms.supabase.co/functions/v1/cortex-mcp
/api/v1/tools/get_signal_cac
Bearer (ck_ endpoint token)

Cost per attributed conversion from Signal's spend-attribution mart, by date, attribution model, channel and campaign: spend, credited_conversions and CAC. Use it for "what does a conversion cost by channel" once Signal is tracking conversions. Rows exist ONLY where credited conversions join ad spend on matching campaign names, so an empty result is a valid state — it means nothing has joined yet, not that CAC is zero and not that the tool failed. Because credit is split by attribution model, always state which model a CAC figure comes from. Requires the Signal spend/CAC mart: without the entitlement this returns a plan refusal rather than empty rows.

Signal CAC by channel › Request Body

start_date
​string · pattern: ^\d{4}-\d{2}-\d{2}$

Since date, YYYY-MM-DD (default: 90 days ago). The window always runs from here through the latest available day; there is no end_date.

Signal CAC by channel › Responses

The tool ran

ok
​boolean · const · required
Const value:
tool
​string · required
data
​required

The tool's payload — byte-identical to what the same tool returns over MCP.


Financials (books)

POST
https://dtrgbxembnbwlmpvhhms.supabase.co/functions/v1/cortex-mcp
/api/v1/tools/get_finance
Bearer (ck_ endpoint token)

Financials read straight from this organization's books (QuickBooks or Xero). Pick the report: kpis (monthly revenue, COGS and margins), pl (P&L rows by account), balances (balance-sheet lines including cash), ar_aging (receivables by age bucket), ap_aging (payables by age bucket), or marketing_bridge (ad spend against revenue: MER, blended CAC, spend as a percentage of revenue). since sets the earliest month, default 13 months back. These are ACCOUNTING numbers on the organization's own calendar and recognition rules — they will not match ad-platform revenue columns, and marketing_bridge is the intended place to compare the two. Requires the Margin module and a synced accounting connector; without it you get a plan refusal, and with no synced books an explicit "no accounting data" answer.

Financials (books) › Request Body

report
​string · enum · required

Which financial report to return — see the tool description for each.

Enum values:
kpis
pl
balances
ar_aging
ap_aging
marketing_bridge
since
​string · pattern: ^\d{4}-\d{2}-\d{2}$

Earliest month to include, YYYY-MM-DD (default: 13 months back).

Financials (books) › Responses

The tool ran

ok
​boolean · const · required
Const value:
tool
​string · required
data
​required

The tool's payload — byte-identical to what the same tool returns over MCP.


Marketing mix model results

POST
https://dtrgbxembnbwlmpvhhms.supabase.co/functions/v1/cortex-mcp
/api/v1/tools/get_mmm_results
Bearer (ck_ endpoint token)

The latest COMPLETED marketing-mix-model run per outcome KPI and model type (Meridian and/or Robyn): model fit (R², NRMSE), per-channel contribution share, ROI and marginal ROI, plus any stored budget-optimization output. outcome_variable filters to one KPI. These are MODEL ESTIMATES over a training window, not measured attribution: report them as modeled contribution, quote the fit statistics alongside any ROI you cite, and note the run's completed_at — a stale run describes an old media mix. Contribution shares answer "what is driving outcomes", while get_channels answers "what did each channel actually spend and produce". Requires Compass.

Marketing mix model results › Request Body

outcome_variable
​string · minLength: 1 · maxLength: 128

Filter to one outcome variable (the KPI the model was trained to explain). Omit to get every outcome the org has trained.

Marketing mix model results › Responses

The tool ran

ok
​boolean · const · required
Const value:
tool
​string · required
data
​required

The tool's payload — byte-identical to what the same tool returns over MCP.


Run a report template

POST
https://dtrgbxembnbwlmpvhhms.supabase.co/functions/v1/cortex-mcp
/api/v1/tools/run_report
Bearer (ck_ endpoint token)

Run a versioned, deterministic report template. The same template over the same window always produces identical tables — the fetches are fixed and the math is precomputed — so prefer this over assembling the same story by hand from several tools. Templates: performance_recap (this period against the previous one, top campaigns, biggest movers), budget_pacing (expected vs actual spend for the current budget period), signal_attribution (credit by channel and model plus CAC), creative_review (winners and losers with attribute insights), finance_snapshot (P&L KPIs plus the marketing bridge). Each template reads the same gated tools you would call yourself: a multi-source template (performance_recap, creative_review, finance_snapshot) fills the sections it can and leaves the rest empty, while a single-source one (budget_pacing) comes back as a plain failure carrying the reason — for example "no budget period covers this date". The payload is designed to be rendered as tables: summarize the headline movements and name the window, do not restate every row. Omit both dates for the default window: the last 30 complete days ending yesterday.

Run a report template › Request Body

template
​string · enum · required

Which report template to run.

Enum values:
performance_recap
budget_pacing
signal_attribution
creative_review
finance_snapshot
start_date
​string · pattern: ^\d{4}-\d{2}-\d{2}$

Window start, YYYY-MM-DD (inclusive). Omit both dates for the default window: the last 30 complete days ending yesterday.

end_date
​string · pattern: ^\d{4}-\d{2}-\d{2}$

Window end, YYYY-MM-DD (inclusive).

Run a report template › Responses

The tool ran

ok
​boolean · const · required
Const value:
tool
​string · required
data
​required

The tool's payload — byte-identical to what the same tool returns over MCP.


List management connections

POST
https://dtrgbxembnbwlmpvhhms.supabase.co/functions/v1/cortex-mcp
/api/v1/tools/list_management_connections
Bearer (ck_ endpoint token)

The ad-platform connections this organization can apply changes through, as { id, platform, name }. Call this BEFORE changes_draft: a draft must name one of these ids, and any other id is refused. Returns identifiers only — never tokens, credentials or account contents.

List management connections › Request Body

List management connections › Responses

The tool ran

ok
​boolean · const · required
Const value:
tool
​string · required
data
​required

The tool's payload — byte-identical to what the same tool returns over MCP.


List change sets

POST
https://dtrgbxembnbwlmpvhhms.supabase.co/functions/v1/cortex-mcp
/api/v1/tools/list_change_sets
Bearer (ck_ endpoint token)

This organization's change sets, newest first, with their workflow status — including ones drafted by people in the app, not just by this endpoint. Use it to check whether a set you submitted has been approved, rejected or applied. Optionally filter by status.

List change sets › Request Body

status
​string · enum

Only return change sets in this workflow state.

Enum values:
DRAFT
PENDING_FINANCE
PENDING_ADMIN
APPROVED
APPLYING
APPLIED
PARTIAL_FAILED
FAILED
limit
​integer · min: 1 · max: 200

Max change sets to return, newest first (default 50, max 200).

List change sets › Responses

The tool ran

ok
​boolean · const · required
Const value:
tool
​string · required
data
​required

The tool's payload — byte-identical to what the same tool returns over MCP.


Get a change set

POST
https://dtrgbxembnbwlmpvhhms.supabase.co/functions/v1/cortex-mcp
/api/v1/tools/get_change_set
Bearer (ck_ endpoint token)

One change set with its proposed items and its approval history (who approved or rejected it, and any comment). Use it after list_change_sets to read exactly what a set contains, or to see why a reviewer sent it back.

Get a change set › Request Body

change_set_id
​string · pattern: ^[0-9a-fA-F]{8}-[0-9… · required

The change set to read.

Get a change set › Responses

The tool ran

ok
​boolean · const · required
Const value:
tool
​string · required
data
​required

The tool's payload — byte-identical to what the same tool returns over MCP.


List audiences

POST
https://dtrgbxembnbwlmpvhhms.supabase.co/functions/v1/cortex-mcp
/api/v1/tools/list_audiences
Bearer (ck_ endpoint token)

This organization's saved intent audiences, newest first, with the query each was built from, its filters, its status and its ContactBased feed id. Call this before creating one: audiences are capped per organization, and an existing audience can usually be refined with audience_update_filters instead.

List audiences › Request Body

List audiences › Responses

The tool ran

ok
​boolean · const · required
Const value:
tool
​string · required
data
​required

The tool's payload — byte-identical to what the same tool returns over MCP.


List conversion page rules

POST
https://dtrgbxembnbwlmpvhhms.supabase.co/functions/v1/cortex-mcp
/api/v1/tools/signal_page_rule_list
Bearer (ck_ endpoint token)

This organization's conversion page rules: URL patterns that make a pageview count as a conversion (for thank-you pages and other no-form conversions). Read these before adding one — a rule name must be unique per site, and an overlapping pattern double-counts.

List conversion page rules › Request Body

site_id
​string · pattern: ^[0-9a-fA-F]{8}-[0-9…

Only return rules for this tracked site.

List conversion page rules › Responses

The tool ran

ok
​boolean · const · required
Const value:
tool
​string · required
data
​required

The tool's payload — byte-identical to what the same tool returns over MCP.


List form groups

POST
https://dtrgbxembnbwlmpvhhms.supabase.co/functions/v1/cortex-mcp
/api/v1/tools/signal_form_group_list
Bearer (ck_ endpoint token)

This organization's form groups — sets of step form names treated as ONE form, so a multi-step form counts as a single conversion instead of one per step. Read these before grouping, to see which step names are already claimed.

List form groups › Request Body

List form groups › Responses

The tool ran

ok
​boolean · const · required
Const value:
tool
​string · required
data
​required

The tool's payload — byte-identical to what the same tool returns over MCP.


List attribution models

POST
https://dtrgbxembnbwlmpvhhms.supabase.co/functions/v1/cortex-mcp
/api/v1/tools/signal_attribution_model_list
Bearer (ck_ endpoint token)

This organization's Signal attribution models, with each model's type, lookback window and whether it is active or the default. Read this before adding one — models are computed side by side, so a near-duplicate mostly adds noise.

List attribution models › Request Body

List attribution models › Responses

The tool ran

ok
​boolean · const · required
Const value:
tool
​string · required
data
​required

The tool's payload — byte-identical to what the same tool returns over MCP.


List Signal sessions

POST
https://dtrgbxembnbwlmpvhhms.supabase.co/functions/v1/cortex-mcp
/api/v1/tools/signal_sessions_list
Bearer (ck_ endpoint token)

List recent Signal sessions for the organization (operational Supabase state). Optional site_id filter. recorded_only limits to playable replays (ready/partial). Does not return signed playback URLs.

List Signal sessions › Request Body

site_id
​string · uuid · pattern: ^([0-9a-fA-F]{8}-[0-…
recorded_only
​boolean
limit
​integer · min: 1 · max: 200
cursor_started_at
​string · minLength: 1
cursor_id
​string · uuid · pattern: ^([0-9a-fA-F]{8}-[0-…
device_class
​string · enum
Enum values:
mobile
tablet
desktop
client_os
​string · enum
Enum values:
ios
android
macos
windows
linux
chromeos
page_contains
​string · minLength: 1 · maxLength: 120
landing_only
​boolean
has_form_submit
​boolean

List Signal sessions › Responses

The tool ran

ok
​boolean · const · required
Const value:
tool
​string · required
data
​required

The tool's payload — byte-identical to what the same tool returns over MCP.


Get Signal session

POST
https://dtrgbxembnbwlmpvhhms.supabase.co/functions/v1/cortex-mcp
/api/v1/tools/signal_session_get
Bearer (ck_ endpoint token)

Fetch one Signal session plus its chunk index (hashes and sizes, no signed URLs). Playback grant is a separate tool.

Get Signal session › Request Body

session_id
​string · uuid · pattern: ^([0-9a-fA-F]{8}-[0-… · required

Get Signal session › Responses

The tool ran

ok
​boolean · const · required
Const value:
tool
​string · required
data
​required

The tool's payload — byte-identical to what the same tool returns over MCP.


Grant Signal session playback URLs

POST
https://dtrgbxembnbwlmpvhhms.supabase.co/functions/v1/cortex-mcp
/api/v1/tools/signal_session_playback_grant
Bearer (ck_ endpoint token)

Mint short-lived signed GET URLs for every chunk of a playable session. Expiry is at most 5 minutes and never past recording_expires_at. Deleted/expired/unavailable sessions return denied.

Grant Signal session playback URLs › Request Body

session_id
​string · uuid · pattern: ^([0-9a-fA-F]{8}-[0-… · required

Grant Signal session playback URLs › Responses

The tool ran

ok
​boolean · const · required
Const value:
tool
​string · required
data
​required

The tool's payload — byte-identical to what the same tool returns over MCP.