You're reading the docs for v2, an older version that is still live. The current version is v3: read its docs.
Two APIs, one way of working
Metric Sensei has two public APIs. They do different jobs, but they are laid out the same way and take the same token, so what you learn on one works on the other.
| Admin API this guide | API/MCP Gateway | |
|---|---|---|
| Use it to | Manage your account: clients, people and their access, data sources and connections, website tracking, services and billing. Everything the admin page does. | Use a client's data: run reports and tools on Google Analytics, Ads, Shopify, Meta and the other connected sources, from your scripts and from AI apps. |
| Address | https://api.metricsensei.com | https://gateway.api.metricsensei.com |
| REST | https://api.metricsensei.com/clients and so on | https://gateway.api.metricsensei.com/tools and so on |
| AI apps (MCP) | https://api.metricsensei.com/mcp | https://gateway.api.metricsensei.com/mcp |
| Guide | /docs | /docs |
| OpenAPI | /openapi.json | https://gateway.api.metricsensei.com/openapi.json |
| Versions | /versions | /versions |
Connect an AI app: /mcp and sign in
AI apps such as Claude and ChatGPT connect to /mcp on either API and sign in with your Metric Sensei account: no token to copy. On the Admin API you choose read only or read and change; on the gateway you pick the client. The app then acts as you, with your own access. A sign-in for one API never works on the other, so connect each one the app should use. Sign apps out in the admin page.
One token for both
Create a personal API token in the admin page (it starts with msat_) and send it as Authorization: Bearer <token>. It acts as you, with your own role, on both APIs. A token names a person, not a client, so on the gateway also say which client you mean with the Metric-Sensei-Client: <client ID> header. A read-only token can read on both and change nothing.
export MS_TOKEN=msat_...
# Admin API: the clients you manage
curl -s https://api.metricsensei.com/clients -H "Authorization: Bearer $MS_TOKEN"
# API/MCP Gateway: the tools you can run for the client acme
curl -s https://gateway.api.metricsensei.com/tools -H "Authorization: Bearer $MS_TOKEN" -H "Metric-Sensei-Client: acme"The gateway also takes a gateway API key (mcpgw_), which belongs to one client and needs no header.
The same on both
- REST lives at the root of the address, AI apps connect at
/mcp, and this guide is at/docs. - Without a version you get the latest. Put
/v<N>first in the path, or sendMetric-Sensei-Version: <N>, to stay on one version;/versionslists them. - Answers are JSON. Errors have an
errorcode and a plainmessage.
Getting started
The Admin API lets you manage your agency and clients from your own code: clients and their people, data sources and connections to Google Analytics 4, Tag Manager, Search Console, Business Profile, Merchant Center, Ads, AdSense, PageSpeed Insights, Shopify, Meta Ads, Facebook Pages, Instagram and Meta Business, API/MCP Gateway keys, connected apps, sign-in settings, website tracking and billing. Anything an agency or client admin can do in the admin page you can do here. There are 264 operations, and AI agents can use the same operations as MCP tools.
| What | Address |
|---|---|
| REST API | https://api.metricsensei.com (latest version) |
| MCP server for AI apps and agents | https://api.metricsensei.com/mcp (sign in from the app, or use a token) |
| OpenAPI 3.1 spec | https://api.metricsensei.com/openapi.json (or .yaml) |
Using an AI app such as Claude or ChatGPT? Add https://api.metricsensei.com/mcp as a remote MCP server
and sign in when it asks: no token needed. See AI agents (MCP). For scripts, start here:
1. Create a token
Sign in to the admin page, open Admin API keys (bottom of the left menu), and choose Create Admin API key.
Pick Read only or Read and change and how long it lasts. Copy the token now: it starts with
msat_ and is shown only once.
2. Make a call
export MS_TOKEN=msat_...
curl -s https://api.metricsensei.com/me -H "Authorization: Bearer $MS_TOKEN"
That shows your clients, your role in each, the connections you can use, and which token you called with. Then, for example:
# List clients
curl -s https://api.metricsensei.com/clients -H "Authorization: Bearer $MS_TOKEN"
# Invite someone to a client as a client admin
curl -s -X POST https://api.metricsensei.com/clients/acme/users \
-H "Authorization: Bearer $MS_TOKEN" -H "Content-Type: application/json" \
-d '{"email": "dana@example.com", "manager": true}'
# Give them read access to one connection
curl -s -X PUT https://api.metricsensei.com/clients/acme/users/USERNAME/access \
-H "Authorization: Bearer $MS_TOKEN" -H "Content-Type: application/json" \
-d '{"grants": {"ga4/main-site": "read"}}'
# Let them see GA4 and manage Shopify connections in the admin (separate from the grants above)
curl -s -X PUT https://api.metricsensei.com/clients/acme/users/USERNAME/access \
-H "Authorization: Bearer $MS_TOKEN" -H "Content-Type: application/json" \
-d '{"grants": {"ga4/main-site": "read"}, "services": {"ga4": "read", "shopify": "write"}}'
Any OpenAPI tool can read the spec: import https://api.metricsensei.com/openapi.json into Postman, Insomnia or a client generator.
Tokens and sign-in
Every request needs a personal API token in the Authorization header:
Authorization: Bearer msat_...
The same token works for every version. On /mcp, AI apps can instead sign in with your
Metric Sensei account (OAuth): see Sign in from an AI app.
- A token acts as you. It has the role you have in the admin page right now. If your role changes or your account is disabled, your tokens follow at once.
- Read only or read and change. Read-only tokens can call
GEToperations only. Agents with a read-only token see only the read tools. - Tokens always expire, after 1 to 365 days (90 by default). You can have up to 20.
- Revoke a token in the admin page. It stops working at once.
- API keys are changed only in the admin page. For security, this API can list your tokens and API/MCP Gateway keys (never their secret values) but can't create, change or revoke any of them. In the admin page, creating or revoking a key needs you to confirm it's you with your passkey or authenticator code first.
- Your password, authenticator app and passkeys are changed only on the admin page's Profile tab, which uses your own sign-in. A token can read your profile (
GET /me/profile) and change your details: first and last name, phone and address (PATCH /me/profile). They are all required.time_zonesets where the admin page shows dates and times (for exampleAmerica/Chicago, or empty for your browser's time zone); the API always gives times in UTC.
msat_) are for this Admin API. API/MCP Gateway keys are different: they let a
person or an app use a client's analytics data through the API/MCP Gateway. This API can list them; create and revoke them in the admin page.Roles
| Role | What the API lets you do |
|---|---|
| Global admin | Every operation below, for every agency and client. Platform administration (all accounts, environment settings, pricing, invites and billing runs) is in the admin page only. |
| Agency admin | Client admin in every client your agency owns, plus your agency's people, creating clients in it, and reading the prices. |
| Agency member | Client user in every client your agency owns. |
| Client admin | The client operations (data sources, connections, listing API/MCP Gateway keys, inviting and removing users and setting their access, connected apps, sign-in, tracking) for the clients you manage, plus everything under Me. |
| Client user | Everything under Me: see your access and connected apps, and list your own API/MCP Gateway keys and tokens. With admin service access from a client admin, also see a service's connections (view), or add, change and remove them (view and edit). |
A client user has two separate kinds of access, both set with set_user_access: connection grants
(grants) decide which data they can use through the API/MCP Gateway and their API/MCP Gateway keys; admin service
access (services) decides what they can see and change per service in the admin and this API. Neither gives the other.
Every client belongs to one agency, which owns it and is billed for it. A customer with a single client has a solo agency of its own. The admins of a solo agency run its agency-level work, such as turning services on and managing billing (a customer's first admin becomes one when they accept their invite). To manage more clients, they can upgrade it to an agency account (Settings › Account type, or POST /agencies/{agency_id}/upgrade); its admins then become the agency's admins.
Each operation below says who can use it. Calls outside your role get 403.
Billing
Each agency is on a billing plan. On the Standard plan, each client pays a monthly base fee for every service it has on (charged by the day), plus usage above what the fee includes. On a cost plus plan there are no base fees: every unit used is charged at our cost plus the plan's markup. On the 1st, each agency gets one invoice for the month before, broken down by client, and its default saved card is charged. Unpaid invoices are retried daily, up to three times.
See the agency's plan and the plans you can choose with GET /agencies/{agency_id}/plans, and switch with PUT /agencies/{agency_id}/plan. Your switch starts on the 1st of next month; until then the current plan applies. Some plans can only be assigned by Metric Sensei; an agency on one of those can't switch itself.
To save a card through the API, get a token from GET /agencies/{agency_id}/card-form-token, collect the card with Braintree's client SDK (Hosted Fields or Drop-in), and send the nonce it returns to POST /agencies/{agency_id}/cards. Card numbers never reach Metric Sensei.
Activity (audit) log
Every change is recorded, by every role: who made it, when, in which role, where (the admin page and its service screens, this API, an AI app through the API/MCP Gateway) and with which API token or API/MCP Gateway key. So is every sign-in and every super admin log-in to a client or agency. Normal reads are not recorded. Secrets such as credentials and keys are never recorded. Entries are kept for a year.
GET /clients/{client}/activity: one client's log (its admins).GET /agencies/{agency_id}/activity: an agency's log, including its clients (agency admins).GET /me/activity: your own sign-ins and changes (everyone).GET /audit: the audit log scoped to you. Super admins see everyone's, including platform settings and deploys; agency admins see their agency's trail including its clients; client admins see their client's; anyone else sees only their own.
All four are newest first, paged like other lists, and take the same filters: actor (an email),
via, kind (change, sign-in, session for a super
admin log-in, deploy), action, role, since and
until (dates, UTC) and q, a text search in which every word must appear.
/audit also takes client and agency, which must be ones you can see. A narrow
search of a super admin's /audit
may return a short page with a next_cursor: keep paging until it is null.
curl -s "https://api.metricsensei.com/clients/acme/activity?limit=20&q=google+ads" -H "Authorization: Bearer $MS_TOKEN"
# {"activity": [{"at": "...", "actor": "dana@example.com", "summary": "turned off Google Ads", "kind": "change", "via": "page", ...}], "next_cursor": null}
curl -s "https://api.metricsensei.com/me/activity?kind=sign-in&since=2026-11-01" -H "Authorization: Bearer $MS_TOKEN"
Usage
See how many API/MCP Gateway tool calls a client made, per day and per service, with
GET /clients/{client}/usage?days=30 (1 to 90 days, today included, in UTC). Successful calls are the
ones billed; failed calls are counted separately and never billed. month compares this month's calls
with the free calls the base fee includes. GET /agencies/{agency_id}/usage lists every client of an
agency, busiest first.
curl -s "https://api.metricsensei.com/clients/acme/usage?days=7" -H "Authorization: Bearer $MS_TOKEN"
# {"totals": {"count": 412, "by_service": {"ga4": 300, "gtm": 112}, "failed": 3}, "days": [...], "month": {"count": 1290, "included": 40000}}
Home summary
Read the numbers on a client's or an agency's Home with GET /clients/{client}/summary and
GET /agencies/{agency_id}/summary. There is one entry in tiles per Home tile, only for the
paid services that are on: API/MCP Gateway calls per day for the last 30 days, Attribution sessions, form submits
and people identified, data sources and how many need a new sign-in, live events received, Dashboards and AI
Services usage this month. An agency's summary adds each service up over its active clients and includes its free
trial (while one runs) and its bill. A client's share of this month's bill (client_bill) is for its
agency's admins. Add tiles=gateway,attribution to read only some tiles. A tile that couldn't be read has
an error instead of data.
curl -s "https://api.metricsensei.com/clients/acme/summary?tiles=gateway" -H "Authorization: Bearer $MS_TOKEN"
# {"home": "client", "period": "2026-11", "tiles": [{"key": "gateway", "data": {"calls": 412, "failed": 3, "daily": [...], "connections": 4, "api_keys": 2}}]}
Tracked sites
A client's websites, iOS apps, Android apps and APIs are tracked sites, shared by services the way
data sources are. Each has a kind (website, ios_app, android_app
or api), the services turned on for it, and each service's settings. A website
gets one snippet; its tag loads only the code of the services turned on for it (and on for the client).
Apps and APIs are identified by their site ID. Today the only service is Attribution, for websites.
curl -s -X POST "https://api.metricsensei.com/clients/acme/tracked-sites" -H "Authorization: Bearer $MS_TOKEN" \
-H "content-type: application/json" -d '{"kind": "website", "domain": "acme.com", "services": ["attribution"]}'
# {"site_id": "MS-7KQ2M9XP", "kind": "website", "services": ["attribution"], "running": ["attribution"], "snippet": "<script>...", ...}
curl -s -X PATCH "https://api.metricsensei.com/clients/acme/tracked-sites/MS-7KQ2M9XP" -H "Authorization: Bearer $MS_TOKEN" \
-H "content-type: application/json" -d '{"settings": {"attribution": {"debug": true}}}'
settings merges per service, and a service's settings are kept while it is off. The older
/clients/{client}/attribution/sites endpoints still work: they show the websites with Attribution on.
Custom tracking domains
A website can load its tag, its code and visitor IDs from a host on its own domain, like t.acme.com,
instead of our CDN. Ad blockers then treat it as part of the website, and visitor IDs are also kept in a cookie
that host sets on the website's domain, which browsers keep longer than cookies set by page scripts. Set it up,
add the four NS records from the answer at the domain's DNS provider, and it goes live by itself (we check
every hour; .../domain/check checks now). The snippet then loads from the new host, and the old
snippet keeps working.
curl -s -X PUT "https://api.metricsensei.com/clients/acme/tracked-sites/MS-7KQ2M9XP/domain" -H "Authorization: Bearer $MS_TOKEN" \
-H "content-type: application/json" -d '{"host": "t.acme.com"}'
# {"available": true, "domain": {"host": "t.acme.com", "status": "waiting_for_dns",
# "records": [{"name": "t.acme.com", "type": "NS", "value": "ns1.ns.metricsensei.com"}, ...], ...}}
curl -s -X POST "https://api.metricsensei.com/clients/acme/tracked-sites/MS-7KQ2M9XP/domain/check" -H "Authorization: Bearer $MS_TOKEN"
# status: waiting_for_dns -> issuing_certificate -> connecting -> active (or failed, with a message saying what to fix)
DELETE .../domain moves the tag back to our CDN first, so the website keeps working.
Looking up a visitor
Admins of a client can look up everything Attribution knows about one visitor: by browser, device, person
or household ID (32 characters, as the website tag gives them out), email address, phone number, IP address,
or another platform's ID pasted as it is (every ID type we collect is tried, and matched_ids says
which matched; write _ga=GA1.1.123.456 to search one cookie only). Emails and phone
numbers are hashed before searching, the same way the tag hashes them. The answer has the linked browsers,
people and households, other platforms' IDs, hashed contact details, websites, visits, where visits came from,
and recent activity. Only that client's visitors are searched. Looking someone up is not logged.
curl -s "https://api.metricsensei.com/clients/acme/attribution/lookup?q=ann@example.com" -H "Authorization: Bearer $MS_TOKEN"
# {"query": {"kind": "email", ...}, "found": true, "matched": ["person"], "people": [...], "browsers": [...], ...}
When a website has keep_contact on (with Attribution's contact capture), the tag also sends one
readable copy of the contact details it hashes, encrypted in the visitor's browser. Our servers store only the
encrypted copy; it is decrypted for the answer's people[].readable and never stored readable.
days (1 to 95, default 95) limits how far back the visit history goes.
Ad-driven lift
A standard Analytics report: the direct visits, organic-search visits and branded searches a client's ads
brought (people who saw an ad, then typed the address or searched), by ad channel (Google Ads YouTube,
Display/Demand Gen/PMax, Search; Meta; MNTN TV) and by campaign, with extra visits, share, cost per extra visit
and a confidence for each. Visits are the website's own Analytics numbers; ad accounts and search sources (Search
Console, Google Ads, Microsoft Advertising) are read with your own access, so use a personal token. Brand terms,
ad accounts and flights bought elsewhere are the website's Analytics settings (ad_lift, saved with
the website); query parameters override them for one request. Websites that also run Attribution add the
visits that came back after an ad click, per campaign. It replaced the TV impact report and its operations. It
is a correlation, not proof: MNTN's holdout tests are on the gateway's mntn_incrementality tool.
When the answer has retry, Microsoft is still building its report: call again about 20 seconds later
with ms_ads_report_id from it.
curl -s "https://api.metricsensei.com/clients/acme/analytics/sites/MS-AB12CD34/reports/ad_lift?range=last_90_days&compare=previous" \
-H "Authorization: Bearer $MS_TOKEN"
# {"summary": "Ads brought about 412 direct visits (6.1%) ...", "by_channel": [...], "by_campaign": [...]}
curl -s "https://api.metricsensei.com/clients/acme/analytics/sites/MS-AB12CD34/reports/attribution?range=last_month" \
-H "Authorization: Bearer $MS_TOKEN" # people, devices, form submits by channel, visits after ad clicks
Versions
Every deploy of the API is a new version, numbered 1, 2, 3 and so on. Old versions keep working, so an integration you pin to a version behaves the same until that version is retired.
- Latest: without a version you always get the newest one:
https://api.metricsensei.com/clients,https://api.metricsensei.com/mcp. - Pin with the path: put
/v<N>first:https://api.metricsensei.com/v2/clients,https://api.metricsensei.com/v2/mcp. - Or pin with a header:
Metric-Sensei-Version: 2. - Every response says which version answered, in the
Metric-Sensei-Versionheader. - Each version has its own docs and spec:
/v<N>/docsand/v<N>/openapi.json. - When an old version can't be kept working any more, it is retired and answers
410 Gone.GET /versionslists every version and its status.
| Version | Released | Status | Pin with |
|---|---|---|---|
| 3 latest | 2026-11-12 | Live | https://api.metricsensei.com/v3 |
| 2 | 2026-11-12 | Live | https://api.metricsensei.com/v2 |
| 1 | 2026-11-11 | Live | https://api.metricsensei.com/v1 |
Requests, lists and errors
- Send and receive JSON (
Content-Type: application/json). Bodies are at most 64 KB. - Everything a client owns is under
/clients/{client}, and everything an agency owns under/agencies/{agency_id}. - Deletes answer
204 No Contentwith an empty body. - Changes are logged with your username and the token's ID.
- Credentials you send (service account keys, client secrets) are stored in AWS Secrets Manager and never returned.
- Calls are rate limited. On
429, wait a moment and retry.
Lists
List operations return one page: up to limit items (default 100, max 500) and a next_cursor.
To get the next page, call again with cursor set to it. On the last page next_cursor is null.
curl -s "https://api.metricsensei.com/clients?limit=50" -H "Authorization: Bearer $MS_TOKEN"
# {"clients": [...], "next_cursor": "NTA"}
curl -s "https://api.metricsensei.com/clients?limit=50&cursor=NTA" -H "Authorization: Bearer $MS_TOKEN"
Errors
Errors have a stable error code, a message for people, and a request_id (also in the
X-Request-Id header of every response) to quote if you contact us:
{"error": "forbidden", "message": "You can't manage that client.", "request_id": "c0ffee12"}
| Status | Code | Meaning |
|---|---|---|
| 400 | bad_request | Something in the request is wrong. message says what. |
| 401 | unauthorized | No token, or the token is unknown, revoked or expired, or the account is disabled. On /mcp the WWW-Authenticate header also says where AI apps sign in. |
| 402 | payment_failed | A card was declined. |
| 403 | forbidden | Your role doesn't allow it, or the token is read-only. |
| 404 | not_found | No such client, person, connection or path. |
| 405 | method_not_allowed | The path exists but not with this method. The Allow header lists the right ones. |
| 410 | version_retired | You pinned a retired API version. GET /versions lists the live ones. |
| 429 | Too many requests (sent by the rate limiter, without a code). Wait a moment and retry. |
AI agents (MCP)
AI apps and agents connect to https://api.metricsensei.com/mcp (MCP Streamable HTTP). They either sign in
with your Metric Sensei account, or send a personal API token. Each operation in the
reference is a tool with the same name, for example list_clients or invite_client_user.
Read tools are marked read-only and delete tools destructive, so agents can ask before changing anything.
Sign in from an AI app
Apps that support sign-in for remote MCP servers (Claude, ChatGPT, Claude Code, Cursor, VS Code and others) need only the address. You sign in on Metric Sensei's login page (with your passkey or authenticator code) and choose Read only or Read and change. The app then acts as you, with your current role, like a token with that access.
- Claude (claude.ai, Desktop and mobile): Settings → Connectors → Add custom connector, paste
https://api.metricsensei.com/mcp, then Connect. - Claude Code:
claude mcp add --transport http metricsensei-admin https://api.metricsensei.com/mcp, then run/mcpand choose Authenticate. - Other apps: add a remote server with the Streamable HTTP transport and choose OAuth sign-in. No client ID is needed: apps find the sign-in through
https://api.metricsensei.com/.well-known/oauth-protected-resource/mcpand register themselves (dynamic client registration, PKCE).
Signed-in apps act as you until you sign them out. They are listed by list_my_connected_apps (with api
admin) and in the admin page under Connect an AI app › My connected apps. Sign one out with
sign_out_my_admin_api_app or the admin page; it stops working at once. Sign-in works on /mcp only; REST calls use a token.
The same login also signs AI apps in to the API/MCP Gateway's /mcp, but a sign-in for one API never works on the other.
With a token (Claude Code)
claude mcp add --transport http metricsensei-admin https://api.metricsensei.com/mcp \
--header "Authorization: Bearer msat_..."
With a token (Cursor, VS Code and other clients)
Add a remote (HTTP) server with an Authorization header. For example in mcp.json:
{
"mcpServers": {
"metricsensei-admin": {
"url": "https://api.metricsensei.com/mcp",
"headers": { "Authorization": "Bearer msat_..." }
}
}
}
get_my_access returns its address.Tips for agents: start with get_my_access; use list_client_users or list_agency_users
to find a username; start_data_source_sign_in returns a link the person must open.
Connecting Google, Shopify, Meta, WordPress, CallRail, Microsoft, Supermetrics, MNTN, NetSuite, TechShip, Mailchimp, Gorgias and Blazeo
Credentials live in a client's data sources: one per Google account, Shopify store, Facebook or Microsoft sign-in, WordPress site, or CallRail, Bing Webmaster or Supermetrics API key, as many as you need, each with a name you choose. Services then use a data source through a connection, which holds the service's own settings.
Two ways to add a data source:
- Sign in:
POST /clients/{client}/data-sources/{source}/sign-inwithtype(google,shopifyormeta) returns aurl. For Google,usespicks the services to ask permission for (ga4,gtm,gsc,gbp,merchant,ads,datamanager; defaultga4andgtm); for Meta,usespicks frommeta_ads,facebook,instagramandmeta_business(default all four); for Shopify, send theshop. Open the link in a browser and sign in to Google or Facebook, or approve the Shopify app. Facebook asks which businesses, Pages, Instagram accounts and ad accounts to share. The data source is saved when you finish. The link works once and expires. - Shopify tracking: add
"tracking": trueto a Shopify sign-in to also ask for the pixel's permissions. When the store owner approves, the store's tracked website (its main domain) is created or reused and the Metric Sensei pixel is turned on. Turn it on or off later withPUT/DELETE /clients/{client}/data-sources/{source}/shopify-tracking. The pixel follows the website's custom tracking domain when one is set up. Store owners can also install the Metric Sensei app from Shopify and pick the client in the admin page. - Paste credentials:
PUT /clients/{client}/data-sources/{source}withtypeand a service account key or Shopify token incredentials. - Install app: WordPress sites, Shopify stores, HubSpot, Gorgias and Klaviyo accounts and Salesforce orgs have a Metric Sensei app. Choose
Install the Metric Sensei app when adding the data source, or
POST /clients/{client}/data-sources/{source}/app, and open the link it returns. WordPress (site_url): an administrator of the site presses Approve on WordPress's own Authorize Application screen; Metric Sensei then installs and turns on the plugin, connects it, adds the tracking tag and, withauto_update(on by default), lets WordPress update the plugin by itself. If the site can't install plugins over its REST API, the data source is still saved: download the plugin, upload it under Plugins › Add New › Upload Plugin, then press Finish setup in the source's App dialog (POST .../app/update). Shopify: the store's approve screen (Shopify updates the app and its pixel by itself; App shows when the store must approve new permissions). HubSpot: the account's install link (HubSpot updates the app by itself; App shows missing scopes; until our Marketplace listing is approved HubSpot allows 25 installs). Gorgias (domain): the account's approve screen for an admin (Gorgias runs the app; App shows a sign-in that stopped working or missing permissions). Klaviyo: the account's authorize link (the app lives in Klaviyo, so it is always current; App shows when it was uninstalled or is missing permissions). Salesforce: our package's install link for a Salesforce admin, then sign in. App (GET .../data-sources/{source}/app) shows whether the app is installed and current; for Salesforce, Update installs the newest package version with the data source's sign-in when that user may install packages, otherwise it gives the install link for a Salesforce admin. - WordPress: use Install app (above), or install the Metric Sensei plugin on the site and press Connect under Settings › Metric Sensei. It opens
/connect/wordpresson this page, where you pick the client; with the API, pass the link'ssite,callback,stateandchallengetoPOST /clients/{client}/wordpress/approveand open theredirect_urlit returns. The plugin then saves awordpressdata source and connection and a tracked website, and adds the tag to every page (switching to the site's custom tracking domain when one goes live). You can also paste a site address, username and Application Password withPUT .../data-sources/{source}(typewordpress). With WPForms, Gravity Forms, Contact Form 7, Ninja Forms, Formidable, Fluent Forms, Forminator or Elementor Pro on the site, the plugin (1.1.0+) saves each accepted submission with its traffic source, only accepted submissions are counted on the Attribution dashboard, and AI apps can read forms and entries withwordpress_list_formsandwordpress_list_form_entries. - CallRail: in CallRail open Settings › Integrations › API Keys and create an API v3 key. On the Data Sources tab choose
CallRail and paste the key; with the API, send
PUT .../data-sources/{source}withtypecallrailandapi_key. The key is tried with CallRail before it is saved. One key reaches every account and company its CallRail user can see, so press Accounts (or sendallowed, for example{"callrail": ["company:COM123"]}) to limit it to one client's company. Then add acallrailconnection: its tools read calls, tracking numbers, form submissions, texts, tags and call reports, and, with changes allowed, tag or annotate calls, add tags and send texts (each asks forconfirm=truefirst). - Snapfulfil: Snapfulfil gives you an API address (
https://<name>.snapfulfil.net, one for live and one for test) and sets up an API user for it (Snapfulfil › Users › Permissions: the API host and your Biz). On the Data Sources tab choose Snapfulfil and enter the address, username and password; with the API, sendPUT .../data-sources/{source}withtypesnapfulfil,api_url,usernameandpassword. The sign-in is tried before it is saved. Press Accounts (or sendallowed, for example{"snapfulfil": ["biz:BIZ1"]}; levelsbiz>owner) to limit it to one client's business or stock owner. Then add asnapfulfilconnection: its tools read shipments, sales and purchase orders, receipts, returns, stock totals and locations, products, customers, suppliers, 3PL invoices, open and closed summaries, warehouse tasks and lookup codes, and, with changes allowed, create, update or delete shipments, sales and purchase orders, receipts, customer returns, products, customers and suppliers, change a shipment's status (hold or cancel) or its tracking and reference fields (each asks forconfirm=truefirst; a record's Biz can't change, and a limited data source only writes inside its Bizs). For live despatch, receipt and stock-move events, open Live events and send the address shown to the Snapfulfil Service Desk; Snapfulfil signs nothing, so keep it private. Shipments are linked to visitors by the web store's order number. - Microsoft Advertising (Bing Ads): on the Data Sources tab choose Microsoft Advertising › Sign in with Microsoft; with the API,
POST .../data-sources/{source}/sign-inwithtypemicrosoft_ads. Sign in with a Microsoft account that has a Microsoft Advertising user. It reaches every customer (manager account) and ad account that user can, so choose which ones with Accounts (orallowed, for example{"microsoft_ads": ["account:123456"]}; levelscustomer>account). Then add amicrosoft_adsconnection: its tools list accounts, campaigns, ad groups, ads, keywords, budgets, conversion goals and UET tags and run performance reports (account, campaign, ad group, keyword, search terms, geography); with changes allowed they create paused campaigns, pause or turn on campaigns, ad groups and keywords, change budgets and bids, and add keywords and negative keywords (each asks forconfirm=truefirst). The sign-in is renewed by our daily check, so it keeps working as long as the Microsoft account keeps access. - Bing Webmaster Tools: in Bing Webmaster Tools open Settings › API access › API Key and generate a key. On the Data Sources tab choose
Bing Webmaster Tools and paste it; with the API, send
PUT .../data-sources/{source}withtypebing_webmasterandapi_key. The key is tried before it is saved and reaches every site in that Bing Webmaster account, so limit it with Accounts (or{"bing_webmaster": ["site:https://www.example.com/"]}). Abing_webmasterconnection reads Bing search queries, top pages, clicks and impressions, crawl stats and issues, URL info, inbound links, sitemaps and keyword research, and, with changes allowed, submits URLs and submits or removes sitemaps (each asks forconfirm=truefirst). - Supermetrics: reaches the 170+ platforms your Supermetrics team has signed in to (Google Ads, Facebook Ads, LinkedIn, TikTok and more).
In Supermetrics Hub create an API key (the team needs Supermetrics' API product). On the Data Sources tab choose Supermetrics and paste it; with the API,
send
PUT .../data-sources/{source}withtypesupermetricsandapi_key. The key is tried before it is saved. If the key can't list the team's logins, also sendconnectors(connector IDs, for example["AW", "FA"]). Press Accounts (or sendallowed, for example{"supermetrics": ["connector:FA", "account:AW/1234567890"]}) to limit it to chosen connectors or accounts. Then add asupermetricsconnection: its tools list connectors, accounts and fields and run reports. It only reads; nothing is changed in Supermetrics. - MNTN (Mountain): Performance TV (connected TV) campaigns. In MNTN open My Account › API and copy the Reporting API key
(anyone on the MNTN account can see it; Rotate key turns the old one off). On the Data Sources tab choose MNTN (Mountain) and paste it; with the API,
send
PUT .../data-sources/{source}withtypemntnandapi_key. The key is tried before it is saved. Press Accounts (or sendallowed, for example{"mntn": ["campaign:12345"]}; levelsadvertiser>campaign) to limit it to chosen advertisers or campaigns; a limited data source's tools must then name the advertiser or campaigns they read. Then add anmntnconnection: its tools list advertisers, campaigns and report columns, show performance (spend, impressions, households reached, verified visits, conversions, revenue, ROAS) by day, campaign, creative or channel, list individual conversions with their order and lead IDs, show attribution paths, run any report and start CSV exports for large ones. It only reads; visitor IPs and street addresses are never fetched. MNTN's data is about 36 hours behind. To see which campaign sent a visitor in Attribution, addmntn_campaign_id=${cagid}&mntn_ad_id=${crid}to the ads' visit URL tracking in MNTN. - Oracle NetSuite: customers, leads, contacts, sales orders, invoices and sales totals, through NetSuite's machine-to-machine sign-in (nobody signs in again; a certificate lasts up to two years).
A NetSuite administrator of the client's account turns on REST Web Services and OAuth 2.0 (Setup › Company › Enable Features › SuiteCloud), makes a role for us (read-only is safest) and a user with it,
and makes an integration record with the Client Credentials (Machine to Machine) grant and the REST Web Services scope. On the Data Sources tab choose Oracle NetSuite and enter the account ID and the
integration's client ID; with the API, send
PUT .../data-sources/{source}withtypenetsuite,account_idandclient_id. We make a certificate: upload it in NetSuite (Setup › Integration › OAuth 2.0 Client Credentials Setup, mapped to that user, role and integration), then save thecertificate_idNetSuite shows (it is tried before it is saved).GET .../netsuiteshows where setup stands;POST .../netsuite/certificatemakes a new certificate before the old one expires (the data source warns a month ahead). Press Subsidiaries (or sendallowed, for example{"netsuite": ["subsidiary:3"]}) to limit a OneWorld account; a limited source's tools must then name asubsidiary_id, and free-form SuiteQL, items and campaigns are off. Then add anetsuiteconnection: its tools list customers, leads, contacts and transactions, summarize sales by period, read any record, run SuiteQL queries and, on connections that allow changes, create or update customers, leads, prospects, contacts and notes (never delete). For live events, turn on Live events and upload our SuiteScript (GET .../netsuite/script, with the address built in) in NetSuite. - Blazeo (formerly ApexChat): chat leads. Blazeo has no API; it sends each lead to a webhook URL. On the Data Sources tab choose Blazeo and press Add;
with the API, send
PUT .../data-sources/{source}withtypeblazeoand no credentials. The reply holdswebhook_url(shown only once: it is stored as a hash), the method (POST, JSON) and the field names. Send them to Blazeo support, who set up the "CRM integration". Webhook on the data source (GET .../data-sources/{source}/blazeo) shows whether leads arrive;POST .../blazeo/teststores a test lead andPOST .../blazeo/rotatemakes a new URL (the old one stops at once). Then add ablazeoconnection: its tools list, read and count leads. Leads are kept for 25 months; deleting the data source deletes them. - TechShip (Techdinamics): shipments, freight costs, carriers, clients, boxes and manifests. Ask your Techdinamics contact for the portal's
API key and secret key (one key set per portal). On the Data Sources tab choose TechShip, pick the portal's region (US, Canada, Europe) or enter its own
TechShip address, and paste both keys; with the API, send
PUT .../data-sources/{source}withtypetechship,api_key,secret_keyandapi_url(us,ca,euor an https host on techship.io or techship.ca). The keys are tried before they are saved. One portal holds many TechShip clients, so press Accounts (or sendallowed, for example{"techship": ["client:ACME"]}) to limit it to one client; a limited data source's reports must then name that client, and manifests (which span clients) are off. Then add atechshipconnection: its tools list and count shipments, total freight costs by day, service, carrier account or client, read carriers, boxes and manifests, and quote rates (a dry run). With changes allowed on the connection it can also create, update, void and delete shipments and finalize manifests, each after a preview andconfirm. TechShip lets one key run 10 requests at once, shared with the customer's own systems, so long date ranges are read one day at a time. Shipments are linked to visitors in Attribution by their order number. TechShip has no webhooks, so there are no live events; deleting the client deletes the saved keys (ask Techdinamics to retire them too). - Live events (webhooks): Shopify, Meta (Facebook Pages and Instagram), CallRail, WordPress (form submissions with the
Metric Sensei plugin 1.3.0+, and WooCommerce) and Google (Business Profile reviews, Merchant Center product status, Google Ads lead forms) and MNTN (verified visits) can push events as
they happen. Metric Sensei registers the webhooks with the platform itself when the data source is connected (on by default) and removes them when it is
deleted. Live events on the data source (
GET|PUT .../data-sources/{source}/live-events) shows the status and switches topics on or off;POST .../live-events/syncchecks now (it also runs daily),POST .../live-events/teststores a test event, andGET .../live-events/eventslists what arrived (kept 25 months). AI apps read them with each service's*_list_live_events,*_get_live_eventand*_live_events_statustools. Google Ads lead forms and MNTN are the manual steps: paste the URL and key shown there into each lead form, and paste MNTN's URL (macros included) once into MNTN › My Account › Creative Tracking › Default Macro-Enabled Visit Tracking. MNTN visitor IPs are never stored, only a one-way hash. Facebook sign-ins need thepages_manage_metadataandleads_retrievalpermissions, so sign in again once. - Salesforce: on the Data Sources tab choose Salesforce › Sign in with Salesforce and pick the org's login (production, sandbox or its
My Domain); with the API,
POST .../data-sources/{source}/sign-inwithtypesalesforce,loginand, for a My Domain,my_domain. One data source is one org, and it sees and changes only what the Salesforce user who signs in can, so sign in as a dedicated integration user (read-only if AI apps should never change records). That user needs the API Enabled permission. First, a Salesforce admin of the org installs Metric Sensei once from the install link shown in the Add data source dialog (salesforce_oauth.install_linksinGET /meta; choose Install for Admins Only), and keeps its refresh token policy at valid until revoked. Press Objects (or sendallowed, for example{"salesforce": ["object:Lead", "object:Opportunity"]}) to limit it further: queries, searches and record changes then stay inside those objects, including lookups such asContact.Account.Name, and reports and dashboards are switched off. Asalesforceconnection describes objects, runs SOQL queries and text searches, reads records, runs reports and dashboards, and summarizes leads, the opportunity pipeline and campaigns; with changes allowed it creates, updates and deletes records (deleted ones go to the Recycle Bin for 15 days), adds or removes campaign members and logs tasks and calls, one record at a time (each asks forconfirm=truefirst). - RingCentral: on the Data Sources tab choose RingCentral › Sign in with RingCentral; with the API,
POST .../data-sources/{source}/sign-inwithtyperingcentral. Sign in as an admin of the client's RingCentral account: the company call log, call analytics and RingCX need admin rights. One sign-in serves two services. Aringexconnection (phone system) lists users, call queues and phone numbers, reads the call log and single calls with their legs, recording details (never the audio), call totals and timelines from RingCentral's Business Analytics, and text messages; with changes allowed it sends a text from the signed-in person's number. Aringcxconnection (contact center) lists sub-accounts, dial groups, campaigns, queues and agents, searches leads, shows calls in progress and finished interactions (needs WEM access); with changes allowed it loads leads into a campaign and pauses, readies, resets, cancels, suppresses or deletes leads. Every change asks forconfirm=truefirst. Press Accounts (or sendallowed) to limit RingEX to some users or queues ({"ringex": ["extension:62912345008"]}) and RingCX to some sub-accounts, campaigns or queues ({"ringcx": ["campaign:1234"]}). Live events record each finished call company-wide and texts to the person who signed in. Metric Sensei refreshes RingCentral sign-ins every 15 minutes (RingCentral's refresh tokens work once and expire after a week unused), and deleting the data source or the client revokes the sign-in at RingCentral. - HubSpot: on the Data Sources tab choose HubSpot › Connect HubSpot; with the API,
POST .../data-sources/{source}/sign-inwithtypehubspot. The link installs Metric Sensei in the HubSpot account picked when it is opened (someone who can install apps there approves), and one data source is one HubSpot account. Accounts that can't install apps can paste a private app's access token instead (api_key, startingpat-); live events then aren't available. Press Objects (or sendallowed, for example{"hubspot": ["object:contacts", "object:deals", "object:forms"]}) to limit it to object types (custom objects too) and marketing tools (forms, marketing emails, campaigns, lists). Ahubspotconnection searches and reads records with their links, lists properties, pipelines, owners, forms and their submissions, marketing emails with their stats, campaigns and lists, and summarizes the deal pipeline and new contacts; with changes allowed it creates, updates and archives records (restorable in HubSpot for 90 days), links records, logs notes, tasks and calls, and adds or removes static list members (each asks forconfirm=truefirst). Live events: contacts, companies, deals and tickets created, changed, deleted or merged. - Google AdSense: on the Data Sources tab add (or edit) a Google data source and tick Google AdSense;
with the API,
POST .../data-sources/{source}/sign-inwithtypegoogleandusesincludingadsense(the sign-in asks for AdSense only when it is ticked). Anadsenseconnection reads earnings reports (by date, page, site, ad unit, country, device and more), a quick overview, saved reports, sites and their approval state, ad units and their code, custom and URL channels, payments, alerts and policy issues, and checks each site's ads.txt for Google's line. Google lets the API create and rename ad units and custom channels only for AdSense for Platforms accounts; archiving an ad unit or deleting a channel asks forconfirm=truefirst. Setup checks say when the account or a site needs attention, ads.txt is missing Google's line, a policy issue limits ads or Google raised an alert (such as a payment hold). Link a website to an AdSense account in its Analytics settings (sources.adsense) to see its earnings next to its page views. - Google Data Manager: on the Data Sources tab add (or edit) a Google data source and tick Google Data Manager;
with the API,
usesincludingdatamanager. It sends the client's own data to Google Ads: Customer Match audiences (create, add and remove people) and offline conversions. Emails and phone numbers are normalized and hashed before they leave Metric Sensei and are never stored. Every change asks forconfirm=truefirst and can run as a test (validate_only); Google processes uploads in the background, and the upload status (GET .../datamanager/statusordatamanager_get_upload_status) shows how it went and the match-rate range. Set the connection'scustomer_match_termstoacceptedonce the client accepted Google's Customer Match terms. Offline conversions for a Google Ads mapping go through Data Manager when the Google sign-in includes it. Deleting the client empties the audiences Metric Sensei created. - Mailchimp: on the Data Sources tab choose Mailchimp › Connect Mailchimp; with the API,
POST .../data-sources/{source}/sign-inwithtypemailchimp. Whoever opens the link signs in to Mailchimp and allows Metric Sensei; one data source is one Mailchimp account. You can paste an API key instead (Mailchimp › Profile › Extras › API keys;api_key, ending in the data center such as-us21); it is tried before it is saved. Press Audiences (or sendallowed, for example{"mailchimp": ["audience:abc123def4"]}) to limit it to some audiences. Amailchimpconnection lists audiences, campaigns, automations, segments, tags, ecommerce stores and orders; reports campaign results in the same rows as other email platforms (recipients, delivered, opens, clicks, rates, unsubscribes, bounces, spam complaints, orders, revenue), daily audience activity, monthly growth and clicks per link; and searches and reads subscribers. With changes allowed it adds or updates subscribers, adds or removes tags, unsubscribes or archives a subscriber, creates draft campaigns and sends tests (each asks forconfirm=truefirst; it never sends or schedules a real campaign and never deletes permanently). Live events (registered on each allowed audience): sign-ups, unsubscribes, profile and email changes, cleaned addresses and, if you choose, campaign sends. With Attribution on, subscribers who click a Mailchimp email are matched to their visits. Mailchimp sign-ins don't expire; to cut Metric Sensei off, remove it under Mailchimp › Profile › Integrations (deleting the client only deletes our copy, since Mailchimp has no way to revoke one). - Gorgias (customer service helpdesk): on the Data Sources tab choose Gorgias › Connect Gorgias and enter the account name
(the
acmein acme.gorgias.com); with the API,POST .../data-sources/{source}/sign-inwithtypegorgiasanddomain. An admin of the Gorgias account opens the link and approves our app; one data source is one Gorgias account. Accounts that can't install apps can paste a user's email and REST API key instead (Gorgias › Settings › REST API;PUT .../data-sources/{source}withtypegorgias,domain,emailandapi_key); the key has that user's permissions, and live events need an admin's key. Press Areas (or sendallowed, for example{"gorgias": ["area:customers", "area:statistics"]}) to limit it to tickets, customers, satisfaction surveys, statistics or voice calls. Agorgiasconnection lists and reads tickets with their messages, views, customers with the orders of stores linked in Gorgias, satisfaction surveys (CSAT), Gorgias's support statistics (response and resolution times, volume per channel, tag and agent, revenue), voice calls, users, teams, tags and macros; with changes allowed it adds internal notes, replies to customers on the ticket's channel, changes a ticket's status, priority or assignee, adds or removes tags and updates a customer (each asks forconfirm=truefirst; nothing is deleted). Live events (new tickets, new messages, tickets opened or closed, assignments) arrive through HTTP integrations we add in Gorgias named "Metric Sensei live events". With Attribution on, tickets and customers are linked to website visitors by email, phone and order. Gorgias has no way to cancel our sign-in from outside, so after deleting the data source or the client remove the Metric Sensei app in Gorgias too. - Klaviyo: on the Data Sources tab choose Klaviyo › Connect Klaviyo; with the API,
POST .../data-sources/{source}/sign-inwithtypeklaviyo. The link installs Metric Sensei in the Klaviyo account an owner, admin or manager approves, and one data source is one Klaviyo account. You can paste a private API key instead (api_key, startingpk_; Klaviyo › Settings › API keys; a read-only key can't make changes). Press Kinds of data (or sendallowed, for example{"klaviyo": ["data:reports", "data:campaigns"]}) to limit it to reports, campaigns, flows, lists and segments, profiles, events, sign-up forms or templates: withoutprofilesandeventsit never reads anyone's personal data. Aklaviyoconnection reports campaign, flow and sign-up form results (the same rows as other email platforms: recipients, opens, clicks, unsubscribes, bounces, orders, revenue), email activity over time and metric totals, and lists campaigns, flows, lists, segments, profiles, events, forms, templates and tags. Reports are kept for 30 minutes (6 hours for past days) because Klaviyo allows few report calls a day. With changes allowed it creates or updates profiles, subscribes (only people who agreed) and unsubscribes, adds or removes list members, makes lists, tags campaigns, flows, lists and segments, records custom events, and creates draft campaigns, which a person sends from Klaviyo (each asks forconfirm=truefirst). Live events (clicks, subscribes and unsubscribes, bounces, opens, SMS): set up automatically when the Klaviyo account may use webhooks (Klaviyo allows that for its app partners and Advanced KDP accounts); otherwise Live events shows an address and body to paste into a flow's Webhook action. Emails from live events are kept only as a one-way hash. Setup checks say when permissions, the Placed Order metric (store revenue) or webhooks are missing. Deleting the data source or the client removes our webhook, and deleting the client revokes the sign-in when no other client uses the same Klaviyo account.
Then add a connection that uses it: PUT /clients/{client}/connections/{service}/{name} with data_source.
Before adding it, list_source_setting_choices lists a setting's choices (for example the GA4 properties) with the data source's sign-in,
just like the admin page's Add connection. After, list_setting_choices does the same for a saved connection, and save_connection changes its settings.
Signing in again (or new credentials) on a data source updates every connection that uses it.
PageSpeed Insights (pagespeed) tests public pages, so its connections need no data source.
Limiting a data source to some accounts. A Google sign-in often sees many accounts. For each service you can
choose which ones a data source may reach: GA4 accounts and properties, Google Ads accounts (a manager includes the accounts under it),
Tag Manager accounts and containers, Search Console sites, Business Profile accounts and locations, Merchant Center accounts and AdSense accounts. A Facebook sign-in can be limited per service to business portfolios (which include everything they own or manage for clients),
ad accounts, Pages and Instagram accounts, for example {"allowed": {"meta_ads": ["business:123"], "instagram": ["ig_account:178414..."]}}.
list_data_source_scope_choices (GET /clients/{client}/data-sources/{source}/scope-options/{service}) lists what the
sign-in can see as a tree, with the current choice; save_data_source with allowed saves it, for example
{"allowed": {"ga4": ["account:123", "property:456"], "ads": ["customer:1234567890"]}}. Picking a parent includes everything under it,
also things added later. A service you leave out may reach everything. Tool calls through the API/MCP Gateway outside the choice are refused,
lists only show what is allowed, and connection defaults must be inside it. Shopify data sources are always exactly one store.
Health alerts. Once a day we check that each data source can still sign in to Google or Facebook, or read its Shopify store
(nothing is changed there). list_alerts (GET /alerts) lists the ones that stopped working, for example
a Google or Facebook sign-in that was revoked or expired, or a Shopify app that was uninstalled, in every client you manage.
check_data_sources (POST /clients/{client}/data-sources/check) checks a client's sources right away,
and each data source shows its last result in health. To fix one, call start_data_source_sign_in
for the same data source and sign in again: the alert clears and every connection using it works again.
Keeping it safe
- Treat a token like a password. Don't put it in code or chat; use an environment variable or a secret store.
- Use read-only tokens unless you need changes, and the shortest expiry that works.
- Make one token per tool or agent so you can revoke one without the others. Last used in the admin page shows which are active.
- If a token leaks, revoke it in the admin page right away.
Me
Your own access, API/MCP Gateway keys and API tokens (list only), and connected apps. Everyone can use these.
Show what you can use
/me
MCP tool get_my_access
Everyone
Your clients, your role in each, and the connections and tools you can use there.
List your API/MCP Gateway keys
/me/gateway-keys
MCP tool list_my_gateway_keys
Everyone
| Field | In | Type | About |
|---|---|---|---|
limit | query | integer | Most items to return (default 100, max 500). |
cursor | query | string | Where to continue: the |
List apps signed in as you
/me/connected-apps
MCP tool list_my_connected_apps
Everyone
Apps (such as AI assistants) you have signed in as you: to the API/MCP Gateway's /mcp in one client (api is gateway), or to this API's /mcp (api is admin, with access read or write).
| Field | In | Type | About |
|---|---|---|---|
limit | query | integer | Most items to return (default 100, max 500). |
cursor | query | string | Where to continue: the |
Sign out one of your connected apps
/me/connected-apps/{client}/{session_id}
MCP tool sign_out_my_connected_app
Everyone
For apps signed in to the API/MCP Gateway (api is gateway). Use sign_out_my_admin_api_app for this API's.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
session_id required | path | string |
Sign out an app signed in to this API
/me/admin-api-apps/{session_id}
MCP tool sign_out_my_admin_api_app
Everyone
For connected apps whose api is admin (signed in to this API's /mcp). Its tokens stop working at once.
| Field | In | Type | About |
|---|---|---|---|
session_id required | path | string |
Get your email notification settings
/me/notifications
MCP tool get_my_notifications
Everyone
setup_digest: whether you get the daily email listing data source setup problems that stop features in the clients and agencies you manage (on unless you turned it off).
Change your email notification settings
/me/notifications
MCP tool set_my_notifications
Everyone
| Field | In | Type | About |
|---|---|---|---|
setup_digest required | body | boolean | Daily email about data source setup problems |
Get your profile
/me/profile
MCP tool get_my_profile
Everyone
Your details (first and last name, email, phone and postal address), how you sign in, and which required details are still missing. Changing your password and adding or removing passkeys need your own sign-in, so they are done on the admin page's Profile tab.
Change your details
/me/profile
MCP tool update_my_profile
Everyone
Send only the details that change. First and last name, phone, street address (line1), city, postal code and country are required, so afterwards they must all be filled in (send the missing ones together). Your email is your sign-in and can't be changed here. time_zone (where the admin page shows dates and times) can be changed on its own.
| Field | In | Type | About |
|---|---|---|---|
first_name | body | string | |
last_name | body | string | |
name | body | string | Older way to send first and last name: split at the first space. |
phone | body | string | Saved in international form (+15551234567). Start with + and the country code, or give a local number and we use the country's code. |
line1 | body | string | Street address |
line2 | body | string | Apartment |
city | body | string | |
region | body | string | State |
postal_code | body | string | |
country | body | string | Two-letter country code (ISO 3166). |
time_zone | body | string | The time zone the admin page shows dates and times in, as an IANA name such as America/Chicago. Empty for automatic (the browser's time zone). Can be sent on its own. The API itself always gives times in UTC. |
List your API tokens
/me/tokens
MCP tool list_my_api_tokens
Everyone
Your personal tokens for this API and its MCP endpoint. Tokens are created and revoked only in the admin page.
| Field | In | Type | About |
|---|---|---|---|
limit | query | integer | Most items to return (default 100, max 500). |
cursor | query | string | Where to continue: the |
Agencies
An agency owns, manages and pays for a set of clients. A customer with one client has a solo agency of its own.
List agencies
/agencies
MCP tool list_agencies
Global admins, Agency admins
Global admins see every agency. Agency admins see the agencies they manage.
| Field | In | Type | About |
|---|---|---|---|
limit | query | integer | Most items to return (default 100, max 500). |
cursor | query | string | Where to continue: the |
Get an agency and its clients
/agencies/{agency_id}
MCP tool get_agency
Global admins, Agency admins
| Field | In | Type | About |
|---|---|---|---|
agency_id required | path | string |
The billing plans you may put the agency on
/agencies/{agency_id}/plans
MCP tool list_billing_plans
Global admins, Agency admins
The agency's plan this month (plan), any switch waiting for next month (next_plan) and the plans you may pick. Agency admins see the plans agencies can choose; some plans can only be assigned by a Metric Sensei admin and aren't listed. can_change is false while the agency is on such a plan. changes_start says when a change you make applies: next_month for agency admins.
| Field | In | Type | About |
|---|---|---|---|
agency_id required | path | string |
Switch the agency's billing plan
/agencies/{agency_id}/plan
MCP tool set_billing_plan
Global admins, Agency admins
Agency admins may pick a plan agencies can choose (see list_billing_plans). The switch starts on the 1st of next month and the current plan applies until then; picking the current plan cancels a planned switch. An agency on a plan only a Metric Sensei admin can assign can't switch itself (403).
| Field | In | Type | About |
|---|---|---|---|
agency_id required | path | string | |
plan required | body | string |
Upgrade a single-customer account to an agency account
/agencies/{agency_id}/upgrade
MCP tool upgrade_agency
Global admins, Agency admins
A single-customer (solo) account becomes a normal agency that can add and manage more clients. Its client's admins become admins of the agency, and the client stays as the agency's first client. An account that is already an agency gets 400.
| Field | In | Type | About |
|---|---|---|---|
agency_id required | path | string |
List an agency's people
/agencies/{agency_id}/users
MCP tool list_agency_users
Global admins, Agency admins
Agency admins (manager) manage every client the agency owns; members use them.
| Field | In | Type | About |
|---|---|---|---|
agency_id required | path | string | |
limit | query | integer | Most items to return (default 100, max 500). |
cursor | query | string | Where to continue: the |
Invite someone to an agency
/agencies/{agency_id}/users
MCP tool invite_agency_user
Global admins, Agency admins
Creates the account if needed (emailing a temporary password) and adds the agency role.
| Field | In | Type | About |
|---|---|---|---|
agency_id required | path | string | |
email required | body | string | |
manager | body | boolean | Make them an agency admin. |
Add someone to an agency, or change whether they're an agency admin
/agencies/{agency_id}/users/{username}
MCP tool update_agency_user
Global admins, Agency admins
| Field | In | Type | About |
|---|---|---|---|
agency_id required | path | string | |
username required | path | string | The person's username (from list_client_users or list_agency_users), not their email. |
manager required | body | boolean |
Remove someone from an agency
/agencies/{agency_id}/users/{username}
MCP tool remove_agency_user
Global admins, Agency admins
Their keys and connected apps in clients they can no longer reach are removed too.
| Field | In | Type | About |
|---|---|---|---|
agency_id required | path | string | |
username required | path | string | The person's username (from list_client_users or list_agency_users), not their email. |
Free trial status and limits
/agencies/{agency_id}/subscription
MCP tool get_subscription
Global admins, Agency admins
state is none (no trial), trial (running), limit (a limit was reached; services are paused), expired (ended without a card; services are paused) or converted (paying).
| Field | In | Type | About |
|---|---|---|---|
agency_id required | path | string |
End the free trial and start paying
/agencies/{agency_id}/subscription
MCP tool start_subscription
Global admins, Agency admins
Needs a saved card. Lifts the trial limits; billing counts from now.
| Field | In | Type | About |
|---|---|---|---|
agency_id required | path | string |
Clients
Clients are the companies or sites whose data the API/MCP Gateway serves.
List clients
/clients
MCP tool list_clients
Global admins, Client admins, Users with service access
Global admins see every client. Client admins see the clients they manage. Client users see the clients where a client admin gave them admin service access, with my_services saying what they may do there.
| Field | In | Type | About |
|---|---|---|---|
limit | query | integer | Most items to return (default 100, max 500). |
cursor | query | string | Where to continue: the |
Create a client
/clients
MCP tool create_client
Global admins, Agency admins
Global admins can create a client in any agency, or leave out agency_id to give it a solo agency of its own. Agency admins create clients in an agency they manage (agency_id may be left out if they manage only one).
| Field | In | Type | About |
|---|---|---|---|
client required | body | string | |
name | body | string | Display name. Defaults to the client ID. |
agency_id | body | string | |
contact | body | object | Who to reach and the postal address. |
invite_email | body | string | Email a one-time link (7 days) inviting this person to add the client's details, set up a sign-in and become its client admin. |
trial | body | boolean | With invite_email and no agency_id: start a free trial when the invite is accepted. |
Turn a paid service on or off for a client
/clients/{client}/services/{service}
MCP tool set_client_service
Global admins, Agency admins
Each service a client has on adds its monthly base fee (charged by the day) to the agency's invoice.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
service required | path | string | |
on required | body | boolean |
Data sources
A client's accounts (Google, Facebook, Microsoft, Salesforce and RingCentral sign-ins, Shopify stores, HubSpot, Mailchimp, Gorgias and Klaviyo accounts, CallRail, Bing Webmaster, Supermetrics, MNTN and TechShip keys) with their credentials. A client can have many of each; services use them through connections.
List data sources that need attention
/alerts
MCP tool list_alerts
Everyone
Data sources whose Google or Facebook sign-in or Shopify access stopped working (severity error), or that no one has signed in to yet (severity warning), in every client you manage. Errors come first. People who don't manage a client get an empty list. Fix one with start_data_source_sign_in. Setup problems (kind: setup) are settings on the platform's side that stop a feature (severity error) or make it work less well (warning); features names them and get_data_source_setup_checks has the steps to fix them.
| Field | In | Type | About |
|---|---|---|---|
limit | query | integer | Most items to return (default 100, max 500). |
cursor | query | string | Where to continue: the |
Setup problems per client
/setup-checks
MCP tool setup_checks_overview
Everyone
For every client you manage: how many data source setup checks need fixing (blocking: a feature stops working) or are worth fixing (warning). Counts only features of services the client has on. Worst first.
List a client's data sources
/clients/{client}/data-sources
MCP tool list_data_sources
Global admins, Client admins, Users with service access
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
limit | query | integer | Most items to return (default 100, max 500). |
cursor | query | string | Where to continue: the |
Check that a client's data sources can still sign in
/clients/{client}/data-sources/check
MCP tool check_data_sources
Global admins, Client admins
Tests every data source's Google or Facebook sign-in or Shopify store access now (we also do this every hour) and saves the result in each source's health. Nothing is changed in Google, Shopify or Meta. Returns the data sources and any alerts. To fix an alert, use start_data_source_sign_in.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string |
Add or change a data source
/clients/{client}/data-sources/{source}
MCP tool save_data_source
Global admins, Client admins
Creates the data source if it doesn't exist (send type and credentials), otherwise changes only the fields you send. New credentials replace the old ones for every connection using the source. Credentials are stored encrypted and never returned. To use a Google, Facebook, Microsoft or Salesforce sign-in or a Shopify, HubSpot, Gorgias or Klaviyo install instead of pasting credentials, use start_data_source_sign_in.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
source required | path | string | The data source's name. |
type | body | google | shopify | meta | wordpress | callrail | microsoft_ads | bing_webmaster | supermetrics | blazeo | salesforce | mntn | ringcentral | netsuite | hubspot | snapfulfil | techship | mailchimp | gorgias | klaviyo | The kind of account. Can't change later. A new |
api_key | body | string | CallRail, Bing Webmaster Tools, Supermetrics and MNTN only, instead of |
email | body | string | Gorgias only, with |
domain | body | string | Gorgias only: the account name, the |
account_id | body | string | NetSuite only: the account ID (NetSuite > Setup > Company > Company Information), for example |
client_id | body | string | NetSuite only, with |
certificate_id | body | string | NetSuite only: the Certificate ID NetSuite shows after the certificate is uploaded and mapped. We sign in once and run one query before saving it; a refusal is rejected (400). After |
new_certificate | body | boolean | NetSuite only. Same as |
api_url | body | string | Snapfulfil only: the API address Snapfulfil gave you, |
secret_key | body | string | TechShip only: the portal's secret key ( |
username | body | string | Snapfulfil only: the API user's name (set up in Snapfulfil for the API host and your Biz). |
password | body | string | Snapfulfil only: the API user's password. Never returned. |
connectors | body | array of string | Supermetrics only: connector IDs to offer, for example |
label | body | string | A display name |
description | body | string | |
allowed | body | ['object', 'null'] | Which accounts and properties each service may reach through this data source. Maps a service (ga4, ads, gtm, gsc, gbp, merchant, adsense, datamanager, meta_ads, callrail, microsoft_ads, bing_webmaster, supermetrics, salesforce, mntn, netsuite, hubspot, snapfulfil, techship, mailchimp, gorgias, klaviyo, ...) to a list of items written "level:id", for example |
credentials | body | object or string | A credential object (or its JSON as a string). Google takes a service account key ( |
Delete a data source
/clients/{client}/data-sources/{source}
MCP tool delete_data_source
Global admins, Client admins
Deletes the data source and its credentials. Refused while a connection still uses it.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
source required | path | string | The data source's name. |
Start a Google, Facebook, Microsoft, Salesforce, RingCentral or Mailchimp sign-in, or a Shopify, HubSpot, Gorgias or Klaviyo install, for a data source
/clients/{client}/data-sources/{source}/sign-in
MCP tool start_data_source_sign_in
Global admins, Client admins
Returns a link. Open it in a browser and sign in with the Google, Facebook, Microsoft, Salesforce or RingCentral account, or approve the app in the Shopify store. A Facebook sign-in asks which businesses, Pages, Instagram accounts and ad accounts to share. A Microsoft sign-in (Microsoft Advertising) must be an account with a Microsoft Advertising user; it reaches every customer and ad account that user can, so limit it with allowed afterwards. A Salesforce sign-in connects one org (login: production, sandbox, or my_domain with my_domain) as the user who signs in; that user needs API access, and a Salesforce admin of the org must have installed our package once (the reply's install_url). A RingCentral sign-in (type: ringcentral) should be an admin of the client's RingCentral account (the company call log, analytics and RingCX need it); one sign-in serves both ringex (phone system) and ringcx (contact center), and Metric Sensei refreshes it every 15 minutes. A HubSpot link installs our app in the HubSpot account picked when it is opened (someone who can install apps there approves); one data source is one HubSpot account. A Mailchimp sign-in (type: mailchimp) connects the Mailchimp account picked when it is opened; Mailchimp's sign-ins don't expire (they stop when someone removes Metric Sensei under Mailchimp > Profile > Integrations). A Gorgias link (type: gorgias with domain, the account name) opens that account's approve screen for our app; an admin of the account approves, and one data source is one Gorgias account. A Klaviyo link installs our app in the Klaviyo account its owner, admin or manager approves; one data source is one Klaviyo account. When you finish, the data source is created (or its credentials replaced). The link works once and expires.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
source required | path | string | The data source's name. |
type | body | google | shopify | meta | microsoft_ads | salesforce | ringcentral | hubspot | mailchimp | gorgias | klaviyo | Needed for a new data source. WordPress sites connect from the plugin (approve_wordpress_connect) or with save_data_source; CallRail and Bing Webmaster Tools with an api_key in save_data_source. |
label | body | string | |
description | body | string | |
uses | body | array of ga4 | gtm | gsc | gbp | merchant | ads | adsense | datamanager | meta_ads | facebook | instagram | meta_business | Google and Meta. The services to ask permission for (default ga4 and gtm for Google, all four for Meta). |
write | body | boolean | Also ask for permission to make changes (Google, Meta, Shopify; Microsoft and Salesforce have one permission for reading and changing). |
shop | body | string | Shopify only. The store, for example my-store.myshopify.com |
domain | body | string | Gorgias only. The account name, the acme in acme.gorgias.com (taken from an existing source when left out). |
login | body | production | sandbox | my_domain | Salesforce only. Where the org signs in: login.salesforce.com, test.salesforce.com or its My Domain. |
my_domain | body | string | Salesforce only, with login my_domain. The org's address, for example https://acme.my.salesforce.com |
tracking | body | boolean | Shopify only. Also ask for the tracking pixel's permissions (write_pixels, read_customer_events). When the install finishes, the store's tracked website is created or reused and the Metric Sensei pixel is turned on (see shopify-tracking). |
Whether a data source's Metric Sensei app is installed and up to date
/clients/{client}/data-sources/{source}/app
MCP tool get_source_app
Global admins, Client admins
Asks the platform live. state: installed, update_available, needs_approval (Shopify: the store hasn't approved permissions the source uses; HubSpot, Gorgias and Klaviyo: the account hasn't approved a required scope), needs_update (WordPress plugin too old to connect from here), not_installed, inactive, not_connected, updating (Salesforce is installing a new version) or unknown. actions lists what update_source_app can do now. WordPress also reports version, latest_version, auto_update, download_url and upload_url; Salesforce version, latest_version and install_url. Shopify and HubSpot update their apps by themselves; Gorgias and Klaviyo run ours on their side (nothing to update).
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
source required | path | string | The data source's name. |
Install the Metric Sensei app on a WordPress site, Shopify store, HubSpot, Gorgias or Klaviyo account or Salesforce org
/clients/{client}/data-sources/{source}/app
MCP tool install_source_app
Global admins, Client admins
Returns a link (url) for the platform's admin to open. WordPress (site_url): the site's own Authorize Application screen; after Approve, Metric Sensei saves the data source, installs and activates the Metric Sensei plugin (from WordPress.org), connects it and adds the tracking tag, and with auto_update (default true) switches WordPress's automatic updates for it on. If the site can't install plugins over its REST API, the data source is still saved and the app's status offers the plugin download (update_source_app finishes it after the upload). Shopify (shop): the store's approve screen for our app (same as start_data_source_sign_in). HubSpot: the account's install link for our app (same as start_data_source_sign_in with type hubspot). Gorgias (domain): the account's approve screen for our app (same as start_data_source_sign_in with type gorgias). Klaviyo: the account's authorize link for our app (same as start_data_source_sign_in with type klaviyo). Salesforce (login): the install link of our package for a Salesforce admin; sign in afterwards with start_data_source_sign_in. The link works once and expires in 30 minutes (WordPress) or an hour (Shopify).
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
source required | path | string | The data source's name. |
type | body | wordpress | shopify | hubspot | salesforce | gorgias | klaviyo | Needed for a new data source. |
domain | body | string | Gorgias only. The account name, the acme in acme.gorgias.com. |
site_url | body | string | WordPress only. The site's address, for example https://www.example.com |
auto_update | body | boolean | WordPress only. Let WordPress update the plugin automatically. |
write | body | boolean | WordPress and Shopify. AI tools may also make changes. |
label | body | string | |
shop | body | string | Shopify only. The store, for example my-store.myshopify.com |
tracking | body | boolean | Shopify only. Also turn on the tracking pixel. |
login | body | production | sandbox | Salesforce only. |
Bring a data source's Metric Sensei app up to date, or switch WordPress automatic updates
/clients/{client}/data-sources/{source}/app/update
MCP tool update_source_app
Global admins, Client admins
action update (default): WordPress installs or activates the plugin and connects it as needed ("Finish setup"); Shopify, HubSpot, Gorgias and Klaviyo return a url to approve permissions the store or account is missing (or to install the app again); Salesforce asks the org to install our latest package version with the data source's own sign-in, or returns the install url for a Salesforce admin when that user may not install packages. auto_update_on / auto_update_off: WordPress only.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
source required | path | string | The data source's name. |
action | body | update | auto_update_on | auto_update_off | |
auto_update | body | boolean | WordPress, with action update: also switch automatic updates. |
Turn on tracking for a Shopify store
/clients/{client}/data-sources/{source}/shopify-tracking
MCP tool shopify_tracking_on
Global admins, Client admins
Creates the tracked website for the store's main domain (or reuses the client's existing one) and turns on the Metric Sensei pixel in the store, pointed at that website. Calling it again updates the pixel's settings. The store must be connected with Connect to Shopify, with tracking permissions. status is on, or why tracking isn't on yet: claimed_elsewhere (another account tracks the domain), unavailable (tracking isn't set up in this environment), service_off (turn on the Attribution service for the client first) or missing_permission (connect the store again with tracking). If the website later gets a custom tracking domain, the pixel switches to it by itself.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
source required | path | string | The data source's name. |
Turn off tracking for a Shopify store
/clients/{client}/data-sources/{source}/shopify-tracking
MCP tool shopify_tracking_off
Global admins, Client admins
Removes the Metric Sensei pixel from the store. The tracked website and its data stay.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
source required | path | string | The data source's name. |
Whether Blazeo is sending leads to a Blazeo data source
/clients/{client}/data-sources/{source}/blazeo
MCP tool get_blazeo_webhook
Global admins, Client admins
Blazeo (formerly ApexChat) has no API: it sends each chat lead to the data source's webhook URL. status is receiving, waiting_for_first_lead or not_set_up; also the number of leads received, when the last one arrived, test leads, and the field names to give Blazeo. The URL itself is secret and is shown only when it is made (save_data_source, rotate_blazeo_webhook).
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
source required | path | string | The data source's name. |
Make a new webhook URL for a Blazeo data source
/clients/{client}/data-sources/{source}/blazeo/rotate
MCP tool rotate_blazeo_webhook
Global admins, Client admins
Returns a new webhook_url (shown only once) with the method, format and field names. The old URL stops working at once, so send the new one to Blazeo support straight away. Stored leads stay.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
source required | path | string | The data source's name. |
Store a test lead in a Blazeo data source
/clients/{client}/data-sources/{source}/blazeo/test
MCP tool send_blazeo_test_lead
Global admins, Client admins
Stores a lead marked as a test, as if Blazeo had sent one, to check the connection end to end with the blazeo_* tools. Tools leave test leads out unless asked (include_tests).
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
source required | path | string | The data source's name. |
Where a NetSuite data source's setup stands, with its certificates
/clients/{client}/data-sources/{source}/netsuite
MCP tool get_netsuite_setup
Global admins, Client admins
Returns step (upload_certificate: upload certificate_pem in NetSuite and save the data source with the certificate_id NetSuite shows; renewing: a new certificate, new_certificate_pem, waits for its ID while the current one keeps working; done), account_id, client_id, certificate_id, certificate_expires_at, certificate_days_left and where (the NetSuite page). Certificates are public; private keys are never returned.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
source required | path | string | The data source's name. |
Make a new certificate for a NetSuite data source
/clients/{client}/data-sources/{source}/netsuite/certificate
MCP tool new_netsuite_certificate
Global admins, Client admins
Makes a new key pair (EC P-256, valid 729 days; NetSuite allows two years at most). It waits next to the current one, which keeps working, until you save the data source with the new certificate_id. Returns the same as GET .../netsuite.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
source required | path | string | The data source's name. |
Our NetSuite SuiteScript, with this data source's live-events address built in
/clients/{client}/data-sources/{source}/netsuite/script
MCP tool get_netsuite_script
Global admins, Client admins
Returns script (SuiteScript 2.1 user event script) and filename. Upload it in NetSuite > Customization > Scripting > Scripts > New and deploy it on customer, lead, prospect, contact, sales order, invoice and cash sale records. It posts a short summary of each created or edited record to the data source's live-events address (keep it private) and never changes anything in NetSuite. Live events must be on for the data source (400 otherwise).
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
source required | path | string | The data source's name. |
A data source's live events (webhooks) setting and status
/clients/{client}/data-sources/{source}/live-events
MCP tool get_live_events
Global admins, Client admins
Live events are what a platform pushes to Metric Sensei by webhook: Shopify orders, Facebook lead ads and comments, Instagram comments, CallRail calls and texts, WordPress form submissions and WooCommerce orders, Business Profile reviews, Merchant Center product status changes, Google Ads lead form leads, MNTN verified visits, NetSuite customers, leads, orders and invoices (through our SuiteScript). Returns supported, enabled, status (ok, partial, error, needs_setup, syncing, off, unsupported), message, the topics (each with on), subscriptions made at the platform, manual setup steps (e.g. the URL and key to paste into a Google Ads lead form), last_event_at and event_count. Live events are on by default for sources that support them.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
source required | path | string | The data source's name. |
Switch live events on or off and pick topics
/clients/{client}/data-sources/{source}/live-events
MCP tool update_live_events
Global admins, Client admins
Metric Sensei registers (or removes) the webhooks at the platform through its API, in the background (status: syncing until done). Leave a field out to keep it.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
source required | path | string | The data source's name. |
enabled | body | boolean | |
topics | body | array of string | Topic IDs from get_live_events. |
A client's setup checks and feature readiness
/clients/{client}/setup-checks
MCP tool list_setup_checks
Global admins, Client admins
Setup checks read the settings and permissions on each platform's side that Metric Sensei features need (for example GA4 data retention and User-ID, Google Ads auto-tagging, Search Console access, Meta permissions and pixels, the Shopify pixel, the WordPress plugin, CallRail session tracking). They run when a data source is connected, once a day, and on run_data_source_setup_checks, and never change anything.
sources: each checked data source with status (blocking, warning, ok), counts, checked_at and results. Each result has check, title, status (ok, warning, blocking, unknown = couldn't tell), detail, target (the property or account checked), features (what won't work until it's fixed) and, for problems, fix (numbered steps) and help_url. readiness: per feature, the worst status across the client's data sources and which checks block it. Only features of services the client has on are listed.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string |
One data source's setup checks
/clients/{client}/data-sources/{source}/setup-checks
MCP tool get_data_source_setup_checks
Global admins, Client admins
The saved results of one data source's setup checks, problems first (see list_setup_checks).
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
source required | path | string | The data source's name. |
Check a data source's setup now
/clients/{client}/data-sources/{source}/setup-checks/run
MCP tool run_data_source_setup_checks
Global admins, Client admins
Reads the platform's settings again now (a few read-only calls; this also runs daily) and returns the results. Use it after fixing something to confirm the fix.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
source required | path | string | The data source's name. |
Check a data source's webhooks now
/clients/{client}/data-sources/{source}/live-events/sync
MCP tool sync_live_events
Global admins, Client admins
Checks the webhooks at the platform and makes missing ones again (this also runs daily).
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
source required | path | string | The data source's name. |
Store a test live event
/clients/{client}/data-sources/{source}/live-events/test
MCP tool send_live_event_test
Global admins, Client admins
Stores a sample event marked as a test; lists and tools leave tests out unless asked.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
source required | path | string | The data source's name. |
Events a data source received by webhook
/clients/{client}/data-sources/{source}/live-events/events
MCP tool list_live_events
Global admins, Client admins
Newest first, without payloads (get_live_event has the payload). Kept for 25 months. Page with cursor (the next_cursor of the previous page).
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
source required | path | string | The data source's name. |
start | query | string | YYYY-MM-DD or ISO 8601 (default: 30 days ago). |
end | query | string | YYYY-MM-DD or ISO 8601 (default: now). |
event_type | query | string | e.g. orders/create, leadgen, post_call. |
service | query | string | e.g. shopify, facebook, instagram, gbp. |
include_tests | query | boolean | |
limit | query | integer | Most items to return (default 100, max 500). |
cursor | query | string | Where to continue: the |
One received event with its payload
/clients/{client}/data-sources/{source}/live-events/events/{event_id}
MCP tool get_live_event
Global admins, Client admins
The platform's payload as received, plus details fetched afterwards (e.g. a lead's answers).
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
source required | path | string | The data source's name. |
event_id required | path | string |
Approve connecting a WordPress site
/clients/{client}/wordpress/approve
MCP tool approve_wordpress_connect
Global admins, Client admins
Step 1 of the Metric Sensei WordPress plugin's Connect. The plugin opens /connect/wordpress?site=&callback=&state=&challenge= on the admin page; pass those four values here to link the site to this client. Returns redirect_url: open it in the browser that came from the plugin (it goes back to the site's wp-admin with a single-use code, valid 10 minutes). The plugin then finishes on its own: the site becomes a wordpress data source with a connection, and a tracked website whose tag the plugin adds to every page.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site required | body | string | The site's address, e.g. https://acme.com |
callback required | body | string | The plugin's return page (the site's own wp-admin, https) |
state required | body | string | The plugin's state value from its link. |
challenge required | body | string | The plugin's PKCE S256 challenge from its link. |
write | body | boolean | Let AI apps make changes on the site. |
List the accounts and properties a data source can be limited to
/clients/{client}/data-sources/{source}/scope-options/{service}
MCP tool list_data_source_scope_choices
Global admins, Client admins
Everything the data source's sign-in can see for one service, as a tree (for example GA4 accounts and their properties, Google Ads manager accounts and the accounts under them, GTM accounts and containers, Search Console sites, Business Profile accounts and locations, Merchant Center accounts, AdSense accounts, Meta business portfolios with their ad accounts, Pages or Instagram accounts), plus the current choice. Save a choice with save_data_source (allowed). Shopify data sources can't be limited: each one is already a single store.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
source required | path | string | The data source's name. |
service required | path | ga4 | gtm | gsc | gbp | merchant | ads | adsense | datamanager | pagespeed | shopify | meta_ads | facebook | instagram | meta_business | wordpress | callrail | microsoft_ads | bing_webmaster | supermetrics | salesforce | mntn | ringex | ringcx | netsuite | hubspot | snapfulfil | techship | mailchimp | gorgias | klaviyo |
The client's latest Google Data Manager audience uploads, newest first
/clients/{client}/datamanager/uploads
MCP tool list_datamanager_uploads
Global admins, Client admins
Counts and IDs only (people's details are never stored). Each has the request_id Google gave it.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
limit | query | integer |
How Google processed one Data Manager upload
/clients/{client}/datamanager/status
MCP tool get_datamanager_upload_status
Global admins, Client admins
Per destination: PROCESSING, SUCCESS, PARTIAL_SUCCESS or FAILED, with record counts, errors by reason and the match-rate range. Uploads usually finish within a few hours. For an offline conversion in the Conversions send log, pass service=ads and the mapping's Google Ads connection.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
request_id required | query | string | |
connection required | query | string | |
service | query | datamanager | ads |
A Google Ads account's audiences, with size and Customer Match match rate
/clients/{client}/datamanager/{connection}/audiences
MCP tool list_google_ads_audiences
Global admins, Client admins
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
connection required | path | string | The client's Google Data Manager connection |
customer_id | query | string | Google Ads account ID (default: the connection's) |
only_customer_match | query | boolean |
Create a Customer Match audience (emails and phone numbers) in Google Ads
/clients/{client}/datamanager/{connection}/audiences
MCP tool create_google_ads_audience
Global admins, Client admins
Needs write access on the connection. The audience's description ends with "[Metric Sensei]", so deleting the client empties it.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
connection required | path | string | The client's Google Data Manager connection |
customer_id | body | string | |
name required | body | string | |
description | body | string | |
membership_days | body | integer |
Add people to (or remove them from) a Customer Match audience
/clients/{client}/datamanager/{connection}/audiences/{audience}/members
MCP tool upload_google_ads_audience_members
Global admins, Client admins
Up to 10,000 people, as people (emails, or objects with email/phone, emails/phones) or csv text with an email and/or phone column (or one email or phone per line). Emails and phones are normalized and SHA-256 hashed before they leave Metric Sensei and are never stored. Adding needs the connection's customer_match_terms set to "accepted"; both need write access on the connection. validate_only has Google check the upload without saving it.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
connection required | path | string | The client's Google Data Manager connection |
audience required | path | string | Audience ID (digits) |
action | body | add | remove | |
people | body | array of any | |
csv | body | string | |
customer_id | body | string | |
default_country_code | body | string | Calling code for phones without one (default 1) |
ad_user_data | body | granted | denied | |
ad_personalization | body | granted | denied | |
validate_only | body | boolean |
Connections
How each service (Google Analytics 4, Tag Manager, Search Console, Business Profile, Merchant Center, Ads, AdSense, PageSpeed Insights, Shopify, Meta Ads, Facebook Pages, Instagram, Meta Business, WordPress, CallRail, Microsoft Advertising, Bing Webmaster Tools, Supermetrics, Salesforce, MNTN, RingEX, RingCX, HubSpot, TechShip, Mailchimp, Gorgias, Klaviyo) uses one of the client's data sources, with its own settings.
List a client's connections
/clients/{client}/connections
MCP tool list_connections
Global admins, Client admins, Users with service access
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
limit | query | integer | Most items to return (default 100, max 500). |
cursor | query | string | Where to continue: the |
Add or change a connection
/clients/{client}/connections/{service}/{name}
MCP tool save_connection
Global admins, Client admins, Users with service access
Creates the connection if it doesn't exist, otherwise changes only the fields you send. A connection uses one of the client's data sources for its credentials: a new one needs data_source (a Google source for the Google services, a Shopify source for Shopify). PageSpeed Insights needs no data source.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
service required | path | ga4 | gtm | gsc | gbp | merchant | ads | adsense | datamanager | pagespeed | shopify | meta_ads | facebook | instagram | meta_business | wordpress | callrail | microsoft_ads | bing_webmaster | supermetrics | salesforce | mntn | ringex | ringcx | netsuite | hubspot | snapfulfil | techship | mailchimp | gorgias | klaviyo | |
name required | path | string | |
data_source | body | string | The name of the data source to use. |
default | body | boolean | Make this the client's default connection for the service. |
allow_write | body | boolean | Allow tools that change data. |
description | body | string | |
settings | body | object | Service settings |
replace_settings | body | boolean | Replace all settings instead of merging. |
Delete a connection
/clients/{client}/connections/{service}/{name}
MCP tool delete_connection
Global admins, Client admins, Users with service access
Deletes the connection right away. Its data source stays.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
service required | path | ga4 | gtm | gsc | gbp | merchant | ads | adsense | datamanager | pagespeed | shopify | meta_ads | facebook | instagram | meta_business | wordpress | callrail | microsoft_ads | bing_webmaster | supermetrics | salesforce | mntn | ringex | ringcx | netsuite | hubspot | snapfulfil | techship | mailchimp | gorgias | klaviyo | |
name required | path | string |
List the choices for a connection setting
/clients/{client}/connections/{service}/{name}/options/{setting}
MCP tool list_setting_choices
Global admins, Client admins, Users with service access
Fetches the values a setting can take (for example the GA4 properties or GTM containers the connection can reach), using the connection's own credentials. Settings a list depends on can be passed as query parameters; any missing ones come back in needs.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
service required | path | ga4 | gtm | gsc | gbp | merchant | ads | adsense | datamanager | pagespeed | shopify | meta_ads | facebook | instagram | meta_business | wordpress | callrail | microsoft_ads | bing_webmaster | supermetrics | salesforce | mntn | ringex | ringcx | netsuite | hubspot | snapfulfil | techship | mailchimp | gorgias | klaviyo | |
name required | path | string | |
setting required | path | string | The setting to list choices for, for example default_property_id. |
values | query | object | Unsaved values of other settings, for example account_id=123. |
List the choices for a setting before adding a connection
/clients/{client}/data-sources/{source}/options/{service}/{setting}
MCP tool list_source_setting_choices
Global admins, Client admins, Users with service access
Like listing a connection setting's choices, but for a connection you haven't added yet: fetches the values a service's setting can take (for example the GA4 properties) with a data source's credentials. The data source must be of the kind the service uses. Use it to fill in the settings of a new connection, then add the connection with PUT /clients/{client}/connections/{service}/{name}. Settings a list depends on can be passed as query parameters; any missing ones come back in needs.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
source required | path | string | The data source's name. |
service required | path | ga4 | gtm | gsc | gbp | merchant | ads | adsense | datamanager | pagespeed | shopify | meta_ads | facebook | instagram | meta_business | wordpress | callrail | microsoft_ads | bing_webmaster | supermetrics | salesforce | mntn | ringex | ringcx | netsuite | hubspot | snapfulfil | techship | mailchimp | gorgias | klaviyo | |
setting required | path | string | The setting to list choices for, for example default_property_id. |
values | query | object | Values of other settings chosen so far, for example account_id=123. |
Gateway keys
Keys that let a person use a client's connections through the API/MCP Gateway. Not the same as API tokens. List only; keys are created and revoked in the admin page.
List a client's API/MCP Gateway keys
/clients/{client}/gateway-keys
MCP tool list_gateway_keys
Global admins, Client admins
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
limit | query | integer | Most items to return (default 100, max 500). |
cursor | query | string | Where to continue: the |
Client users
The people in a client and which connections each one can use.
List a client's users
/clients/{client}/users
MCP tool list_client_users
Global admins, Client admins
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
limit | query | integer | Most items to return (default 100, max 500). |
cursor | query | string | Where to continue: the |
Invite someone to a client
/clients/{client}/users
MCP tool invite_client_user
Global admins, Client admins
Creates their account if needed and emails them an invitation. Existing accounts are added to the client. Client admins can invite people to the clients they manage.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
email required | body | string | |
manager | body | boolean | Make them a client admin. |
Remove someone from a client
/clients/{client}/users/{username}
MCP tool remove_client_user
Global admins, Client admins
Their account stays; they lose this client, and their keys and connected apps here stop working.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
username required | path | string | The person's username (from list_client_users or list_agency_users), not their email. |
Show a user's access
/clients/{client}/users/{username}/access
MCP tool get_user_access
Global admins, Client admins
Two separate kinds of access. grants: which connections the user can use through the API/MCP Gateway and their API/MCP Gateway keys. services: what the user can see (read) or change (write) per service in the admin and through this API. Neither implies the other.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
username required | path | string | The person's username (from list_client_users or list_agency_users), not their email. |
Set a user's access
/clients/{client}/users/{username}/access
MCP tool set_user_access
Global admins, Client admins
Replaces the user's connection grants and, when services is sent, their admin service access (leave services out to keep it as it is). Leave a connection or service out (or set it to none) to take access away. With services read, the user sees that service's connections in the admin; with write they can also add, change and remove them (but not turn API/MCP Gateway changes on or off). Client admins always have full access.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
username required | path | string | The person's username (from list_client_users or list_agency_users), not their email. |
grants | body | object | Connection ("service/name") to access level. |
services | body | object | Admin service access: service name to none, read (view) or write (view and edit). Separate from connection grants. |
Connected apps
Apps (for example AI assistants) signed in to the API/MCP Gateway for a client.
List apps signed in to a client
/clients/{client}/connected-apps
MCP tool list_connected_apps
Global admins, Client admins
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
limit | query | integer | Most items to return (default 100, max 500). |
cursor | query | string | Where to continue: the |
Sign out an app from a client
/clients/{client}/connected-apps/{session_id}
MCP tool sign_out_connected_app
Global admins, Client admins
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
session_id required | path | string |
Identity
A client's company sign-in (SSO), email domains and social sign-in choices.
Show a client's sign-in setup
/clients/{client}/identity
MCP tool get_cliententity
Global admins, Client admins
Company sign-in providers, email domains (with their DNS verification records) and social sign-in choices.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string |
Add a company sign-in provider (SSO)
/clients/{client}/identity/providers
MCP tool add_sign_in_provider
Global admins, Client admins
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
kind | body | oidc | microsoft | google | saml | |
label | body | string | |
auto_join | body | boolean | Add people who sign in this way to the client automatically. |
issuer | body | string | |
directory_id | body | string | |
client_id | body | string | |
client_secret | body | string | |
metadata_url | body | string | |
metadata_xml | body | string | |
email_attribute | body | string |
Change a company sign-in provider
/clients/{client}/identity/providers/{provider}
MCP tool update_sign_in_provider
Global admins, Client admins
Send only what changes. A blank client_secret keeps the current one.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
provider required | path | string | The provider ID from get_cliententity, for example oidc-1a2b3c4d5e. |
kind | body | oidc | microsoft | google | saml | |
label | body | string | |
auto_join | body | boolean | Add people who sign in this way to the client automatically. |
issuer | body | string | |
directory_id | body | string | |
client_id | body | string | |
client_secret | body | string | |
metadata_url | body | string | |
metadata_xml | body | string | |
email_attribute | body | string |
Remove a company sign-in provider
/clients/{client}/identity/providers/{provider}
MCP tool delete_sign_in_provider
Global admins, Client admins
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
provider required | path | string | The provider ID from get_cliententity, for example oidc-1a2b3c4d5e. |
Claim an email domain for the client
/clients/{client}/identity/domains
MCP tool add_email_domain
Global admins, Client admins
Returns a DNS TXT record to add. People with that domain are sent to the client's sign-in once it's verified.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
domain required | body | string |
Check a domain's DNS record
/clients/{client}/identity/domains/{domain}/verify
MCP tool verify_email_domain
Global admins, Client admins
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
domain required | path | string |
Release an email domain
/clients/{client}/identity/domains/{domain}
MCP tool delete_email_domain
Global admins, Client admins
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
domain required | path | string |
Allow or block a social sign-in for a client
/clients/{client}/identity/social/{provider}
MCP tool set_client_social_sign_in
Global admins, Client admins
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
provider required | path | Google | Microsoft | SignInWithApple | Facebook | LoginWithAmazon | |
accept required | body | boolean |
Tracking
Tracked sites (websites, iOS and Android apps, APIs) shared by services, websites' tags and snippets, attribution settings and the dashboard. The /attribution/sites endpoints are the websites with Attribution on.
A client's tracked sites (websites, apps and APIs)
/clients/{client}/tracked-sites
MCP tool list_tracked_sites
Global admins, Client admins
Tracked sites are shared by services, the way data sources are. Each has a type (kind): website (gets a JavaScript tag), ios_app, android_app or api, the services turned on for it, and each service's settings. Also lists the types and the services, with the types each service works with and whether it is on for the client.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string |
Add a website, app or API to track
/clients/{client}/tracked-sites
MCP tool create_tracked_site
Global admins, Client admins
A website needs domain (one site per domain), an app needs app_id (the iOS bundle ID or Android package name; one site per app), and an API needs name. Services in services must work with the type and be on for the client. A website's tag is published at once; the response has the snippet to paste into the website's <head>.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string |
A tracked site, with the snippet for a website
/clients/{client}/tracked-sites/{site_id}
MCP tool get_tracked_site
Global admins, Client admins
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string |
Change a tracked site, its services or their settings
/clients/{client}/tracked-sites/{site_id}
MCP tool update_tracked_site
Global admins, Client admins
Send only the fields to change; the type can't change. services replaces the list of services turned on. settings is merged per service ({"attribution": {"debug": true}} changes only that setting), and a service's settings are kept while it is off. A website's tag is published again (live within 5 minutes) and loads only the services running on it.
Analytics settings (settings.analytics, ms-analytics): timezone (report days, e.g. "America/Chicago"), retention_months (1-25), exclude_paths (["/admin"]), goals ([{"name", "type": "page", "path"} | {"name", "type": "event", "event"}], up to 20; optional ga4_event names the matching GA4 key event for blended numbers, and event goals also match a GA4 event of the same name), funnels ([{"name", "steps": [2-8 page/event steps; a path ending in * matches what's under it]}]), ad_lift (the Ad-driven lift report: {"brand_terms", "exclude_terms", "outcomes", "ads_customer_id", "meta_ad_account_id", "mntn_advertiser_id", "ms_ads_account_id", "site_url", "flights": [{"begin", "end", "label"}]}), sources (connected sources shown in the reports: {"ga4": {"connection", "property_id"}, "gsc": {"connection", "site_url"}, "ads": {"connection", "customer_id"}, "meta_ads": {"connection", "ad_account_id"}, "microsoft_ads": {"connection", "account_id"}, "shopify": {"connection"}, "callrail": {"connection", "account_id", "company_id"}, "mailchimp": {"connection", "list_id" (optional)}, "klaviyo": {"connection"}, "pagespeed": {"connection"}, "gorgias": {"connection"} (the Support panel), "merchant": {"connection", "account_id" (optional)} (the Shopping panel: Google Merchant Center free listings, Shopping ads and products), "adsense": {"connection", "account_id"} (the AdSense panel: earnings on the site's domain), "bing_webmaster": {"connection", "site_url"}, "gbp": {"connection", "location_id" (optional)}, "facebook": {"connection", "page_id"}, "instagram": {"connection", "ig_account_id"}, "mntn": {"connection", "advertiser_id" (optional; TV spend also counts in return on ad spend)}, "woocommerce": {"connection"} (a WordPress connection), "netsuite": {"connection", "subsidiary_id" (optional)}, "ringex": {"connection", "extension_ids" (optional, comma-separated)}, "blazeo": {"connection"}, "hubspot": {"connection"}, "salesforce": {"connection"}}; linking GA4 records you as linked_by, and its nightly copy runs with your access), outbound, downloads, forms, scroll, hash_routes (true/false), not_found_title, analytics_version and forward_events (true by default: the tag also sends every named event to the other trackers on the client's page, such as GA4, Google Tag Manager and Meta Pixel, named ms_<event>, when the visitor allows it and never with emails or phone numbers; false turns it off). The reports themselves are API/MCP Gateway tools (analytics_*); with GA4 linked, analytics_report, analytics_breakdown, analytics_goals and analytics_standard_report take data (ours, ga4 or blended; without it, the person's saved choice, else blended when GA4 is linked, else ours), and analytics_audience and analytics_data_check add GA4-only breakdowns and the ours-vs-GA4 check.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | |
name | body | string | Needed for an API |
status | body | active | paused | |
domain | body | string | Websites only |
subdomains | body | array of string | Websites only. Extra hosts the tag runs on |
app_id | body | string | Apps only. iOS bundle ID or Android package name |
services | body | array of string | Services turned on for this site |
settings | body | object | Each service's settings, by service. Attribution takes the TrackingSiteInput settings other than domain, subdomains, name and status. |
Stop tracking a website, app or API
/clients/{client}/tracked-sites/{site_id}
MCP tool delete_tracked_site
Global admins, Client admins
Removes the site, and a website's tag. Pages that still have the snippet load nothing.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string |
A website's custom tracking domain and its status
/clients/{client}/tracked-sites/{site_id}/domain
MCP tool get_tracking_domain
Global admins, Client admins
A custom tracking domain (t.acme.com) serves the website's tag, its code and the ID endpoint from the client's own domain instead of our CDN, and lets the ID endpoint keep its own cookie on the site's domain. available is false until custom domains are set up in this environment.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string |
Start setting up a custom tracking domain
/clients/{client}/tracked-sites/{site_id}/domain
MCP tool put_tracking_domain
Global admins, Client admins
host must be directly under the website's domain (t.acme.com for acme.com) and not a host the website runs on. The answer lists four NS records (domain.records) to add at the client's DNS provider. We check for them every hour (or call .../domain/check); once they are in, CloudFront gets a certificate and the domain becomes active. One domain per website.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | |
host required | body | string |
Stop using the custom tracking domain
/clients/{client}/tracked-sites/{site_id}/domain
MCP tool delete_tracking_domain
Global admins, Client admins
The tag moves back to our CDN first, so pages keep working. The NS records can then be removed.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string |
Check a custom tracking domain now
/clients/{client}/tracked-sites/{site_id}/domain/check
MCP tool check_tracking_domain
Global admins, Client admins
Looks for the NS records and the certificate now instead of waiting for the hourly check. When the domain becomes active the website's tag is published again with every URL on it.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string |
A client's tracked websites and tracking settings
/clients/{client}/attribution
MCP tool get_attribution
Global admins, Client admins
Lists the sites (one per website domain) that run the Metric Sensei attribution script, the client's settings, whether the Attribution service is on, and whether services are paused.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string |
Set how visitor IDs are shared and how long they're kept
/clients/{client}/attribution/settings
MCP tool update_attribution_settings
Global admins, Client admins
id_scope client (default) gives a visitor the same IDs on all of this client's sites; domain keeps them separate per site. Visitor records are deleted after retention_months without a visit (default 3). link_sources (default true) links data sources' records to visitors. Settings left out keep their current value. Every site is published again.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
id_scope | body | client | domain | |
retention_months | body | integer | |
link_sources | body | boolean | Link data sources' records (Shopify orders, CallRail calls, Blazeo leads, WordPress form entries, Salesforce leads, contacts and opportunities, HubSpot contacts and form submissions) to the visitor behind them. Tool answers then carry an |
Add a website to track
/clients/{client}/attribution/sites
MCP tool create_tracking_site
Global admins, Client admins
Needs the Attribution service on for the client. Returns the site with the snippet to paste into the website's <head>. One site per domain. The script works on that exact domain and the subdomains listed in subdomains, and does nothing anywhere else.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
domain | body | string | The website's exact domain |
subdomains | body | array of string | Other hosts of the domain the script should also run on. It runs on the domain and these only. |
name | body | string | |
status | body | active | paused | |
debug | body | boolean | Log what the script does to the browser console |
core_version | body | string | latest |
consent_mode | body | none | gcm | cmp | When other platforms' IDs may be read (see capture_ids). none: always. gcm: from Google Consent Mode (analytics_storage; ad_storage and ad_user_data). cmp: from the IAB TCF or GPP banner, or the page calling msa('consent', {analytics: true, ads: false}). |
touch_expiry_days | body | integer | |
session_minutes | body | integer | |
ignore_referrers | body | array of string | |
params | body | object | Extra URL parameters to capture, mapped to field names |
form_fill | body | boolean | |
form_touch | body | default | first_touch | last_touch | first_marketing | last_marketing | last_paid | Which touch fills the plain fields: default (last non-direct, else last touch), first_marketing and last_marketing (first and last visit that wasn't direct), last_paid (last paid or tagged campaign) |
form_prefix | body | string | |
form_selectors | body | object | Field name to a CSS selector for forms that can't use the ms_ names |
count_submits | body | boolean | |
capture_contact | body | boolean | On form submit, hash (SHA-256, in the visitor's browser) the name, address, email and phone fields and send only the hashes. Email and phone hashes link a visitor's devices to one person. Off: no form values are read. Values are normalized before hashing (see ms-attribution README, "Normalizing before hashing"), so they match other sources prepared the same way. |
keep_contact | body | boolean | With capture_contact: also keep a readable copy of the contact details, the identify() value, other tools' user IDs and email click tokens. It is encrypted in the visitor's browser with our contact key; only the admin page decrypts it, when someone looks the person up. |
phone_country_code | body | string | Calling code added to phone numbers typed without one before hashing (E.164). 1 = US/Canada. |
capture_ids | body | boolean | Read the visitor and click IDs that other tags keep on the website (GA client and session, Google Ads, Meta _fbp/_fbc, TikTok, X, Microsoft, LinkedIn ...) and send them with the visit, so this data can later be joined with those platforms' own. Follows consent_mode: analytics IDs need analytics consent, ad IDs need ad consent, and ad IDs are skipped when the browser sends Global Privacy Control. Tag-held user IDs (Segment, Mixpanel) are sent only as hashes. |
share_ids | body | boolean | With capture_ids, also hand our browser and person IDs (ms_browser_id, ms_person_id) to the chosen platforms' tags that take a page's own ID: Clarity, Segment, Mixpanel, Amplitude, Heap, PostHog, HubSpot, Klaviyo and TikTok (external_id, SHA-256). Same consent rules. GA4 gets its user_id from ga4_user_id. Meta, X, Microsoft Ads, LinkedIn, Pinterest, Snapchat, Reddit and Criteo have no browser call for this. |
id_platforms | body | array of google_analytics | clarity | segment | mixpanel | amplitude | heap | posthog | hubspot | klaviyo | shopify | google_ads | meta | tiktok | x | microsoft_ads | linkedin | pinterest | snapchat | reddit | criteo | Which platforms' IDs to read (all by default). |
ga4_measurement_id | body | string | |
ga4_user_id | body | identified | person | browser | off | Which ID becomes GA4's user_id. identified: our person ID once the person is known (msa('identify') or a form email), none before. Our IDs always go as user properties. |
google_user_data | body | boolean | Give Google Ads the SHA-256 hashed email and phone from forms and identify (enhanced conversions). Needs ad consent. |
gtm_enabled | body | boolean | |
gtm_data_layer | body | string | |
gtm_event | body | string |
A tracked website, with its snippet
/clients/{client}/attribution/sites/{site_id}
MCP tool get_tracking_site
Global admins, Client admins
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string |
Change a tracked website's settings
/clients/{client}/attribution/sites/{site_id}
MCP tool update_tracking_site
Global admins, Client admins
Send only the fields to change. The site's script is published again (live within 5 minutes).
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | |
domain | body | string | The website's exact domain |
subdomains | body | array of string | Other hosts of the domain the script should also run on. It runs on the domain and these only. |
name | body | string | |
status | body | active | paused | |
debug | body | boolean | Log what the script does to the browser console |
core_version | body | string | latest |
consent_mode | body | none | gcm | cmp | When other platforms' IDs may be read (see capture_ids). none: always. gcm: from Google Consent Mode (analytics_storage; ad_storage and ad_user_data). cmp: from the IAB TCF or GPP banner, or the page calling msa('consent', {analytics: true, ads: false}). |
touch_expiry_days | body | integer | |
session_minutes | body | integer | |
ignore_referrers | body | array of string | |
params | body | object | Extra URL parameters to capture, mapped to field names |
form_fill | body | boolean | |
form_touch | body | default | first_touch | last_touch | first_marketing | last_marketing | last_paid | Which touch fills the plain fields: default (last non-direct, else last touch), first_marketing and last_marketing (first and last visit that wasn't direct), last_paid (last paid or tagged campaign) |
form_prefix | body | string | |
form_selectors | body | object | Field name to a CSS selector for forms that can't use the ms_ names |
count_submits | body | boolean | |
capture_contact | body | boolean | On form submit, hash (SHA-256, in the visitor's browser) the name, address, email and phone fields and send only the hashes. Email and phone hashes link a visitor's devices to one person. Off: no form values are read. Values are normalized before hashing (see ms-attribution README, "Normalizing before hashing"), so they match other sources prepared the same way. |
keep_contact | body | boolean | With capture_contact: also keep a readable copy of the contact details, the identify() value, other tools' user IDs and email click tokens. It is encrypted in the visitor's browser with our contact key; only the admin page decrypts it, when someone looks the person up. |
phone_country_code | body | string | Calling code added to phone numbers typed without one before hashing (E.164). 1 = US/Canada. |
capture_ids | body | boolean | Read the visitor and click IDs that other tags keep on the website (GA client and session, Google Ads, Meta _fbp/_fbc, TikTok, X, Microsoft, LinkedIn ...) and send them with the visit, so this data can later be joined with those platforms' own. Follows consent_mode: analytics IDs need analytics consent, ad IDs need ad consent, and ad IDs are skipped when the browser sends Global Privacy Control. Tag-held user IDs (Segment, Mixpanel) are sent only as hashes. |
share_ids | body | boolean | With capture_ids, also hand our browser and person IDs (ms_browser_id, ms_person_id) to the chosen platforms' tags that take a page's own ID: Clarity, Segment, Mixpanel, Amplitude, Heap, PostHog, HubSpot, Klaviyo and TikTok (external_id, SHA-256). Same consent rules. GA4 gets its user_id from ga4_user_id. Meta, X, Microsoft Ads, LinkedIn, Pinterest, Snapchat, Reddit and Criteo have no browser call for this. |
id_platforms | body | array of google_analytics | clarity | segment | mixpanel | amplitude | heap | posthog | hubspot | klaviyo | shopify | google_ads | meta | tiktok | x | microsoft_ads | linkedin | pinterest | snapchat | reddit | criteo | Which platforms' IDs to read (all by default). |
ga4_measurement_id | body | string | |
ga4_user_id | body | identified | person | browser | off | Which ID becomes GA4's user_id. identified: our person ID once the person is known (msa('identify') or a form email), none before. Our IDs always go as user properties. |
google_user_data | body | boolean | Give Google Ads the SHA-256 hashed email and phone from forms and identify (enhanced conversions). Needs ad consent. |
gtm_enabled | body | boolean | |
gtm_data_layer | body | string | |
gtm_event | body | string |
Stop tracking a website
/clients/{client}/attribution/sites/{site_id}
MCP tool delete_tracking_site
Global admins, Client admins
Removes the site and its script. Pages that still have the snippet load nothing.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string |
Visits, visitors, sources and conversions for one site or all
/clients/{client}/attribution/dashboard
MCP tool get_tracking_dashboard
Global admins, Client admins
Totals from the hourly job (an hour shows up about 15 minutes after it ends). Up to 3 days are shown by hour, longer ranges by day. Unique counts are estimates (about 3%).
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site | query | string | A site ID |
range | query | string | The date range in UTC days: last_24_hours (by hour, up to the current hour) or any shared preset (today, yesterday, this_week, last_week, last_7_days ... last_12_months) or custom with start and end. Up to 400 days. Without range, the older days (1 to 400, default 7, today included) or from/to are used. |
start | query | string | With range custom: the first day, yyyy-mm-dd. |
end | query | string | With range custom: the last day, yyyy-mm-dd. |
compare | query | none | previous | year | custom | Compare with another period: none (default; the overview defaults to previous), previous (the period just before, of the same length; this_month/quarter/year compare the same days of the one before, last_month/quarter/year the whole one before), year (the same dates a year earlier) or custom (with compare_start and compare_end). The answer then adds compare_period, previous and change (percent) on its totals and on each row. |
compare_start | query | string | With compare custom: the first compared day, yyyy-mm-dd. |
compare_end | query | string | With compare custom: the last compared day, yyyy-mm-dd. |
match_weekday | query | 0 | 1 | 1 to line compared days up by day of the week (previous: whole weeks back; year: 52 weeks back). |
days | query | integer | |
from | query | string | |
to | query | string | |
view | query | mapped | original | mapped (default) applies the client's tag rules to source, medium, campaign and channel; original shows the tags as they arrived. Both answers also carry |
See who is on a website right now
/clients/{client}/attribution/realtime
MCP tool get_attribution_realtime
Global admins, Client admins
Like GA4's Realtime, from the Attribution tag: browsers active in the last minutes minutes (default 30) and the last 5, new vs returning, sessions and conversions per minute (per_minute, oldest first, every minute present), top channels, sources, mediums, source / mediums, campaigns, landing pages, paid click IDs (gclid, fbclid ...), countries and devices (top, each {value, visitors}), conversions (form submits, and orders or leads the site reports with them), locations for a live map ({lat, lon, label, visitors, conversions}: the visitor's time zone city or country, never a precise place) and recent, the latest state of up to 20 visitors. Both regions are read and added up; partial is true when one didn't answer, sampled when a very busy site had more rows than one answer reads. Nothing in the answer identifies a person. The same answer as the API/MCP Gateway tool attribution_realtime.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site | query | string | A site ID (MS-XXXXXXXX); default the client's first website |
minutes | query | integer | |
view | query | mapped | original | mapped (default) applies the client's tag rules to source, medium, campaign and channel; original shows them as they arrived. |
Offline conversion settings, the choices for a mapping, and the latest sends
/clients/{client}/attribution/conversions
MCP tool get_offline_conversions
Global admins, Client admins
Offline conversions send a client's orders, leads and calls back to the ad platform that brought the visitor (Google Ads, Meta, Microsoft Ads), once each, when the record is linked to a visitor. Nothing is sent until a mapping exists. Visitors who said no to ads on the site's consent banner are never sent, and only hashed emails and phones and click IDs leave Metric Sensei. connections lists the client's ad connections per platform; log the latest 50 sends.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string |
Save offline conversion settings and mappings
/clients/{client}/attribution/conversions
MCP tool update_offline_conversions
Global admins, Client admins
Settings left out keep their value. Each mapping sends one event type (shopify_order, woocommerce_order, wordpress_form, blazeo_lead, callrail_call, callrail_form, hubspot_contact, netsuite_lead, netsuite_sale, ringcentral_call, salesforce_lead, salesforce_won) to one conversion action: platform google_ads (account_id = customer ID, action = conversion action ID), meta (account_id = Pixel/dataset ID, action = event name such as Purchase or Lead) or microsoft_ads (account_id = account ID, action = the offline conversion goal's name). value is "record" (the order total), a fixed number, or empty. CallRail calls count only from min_call_seconds (default 60); RingCentral calls when they were inbound and answered.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
enabled | body | boolean | |
min_call_seconds | body | integer | |
mappings | body | array of object |
The latest offline conversion sends, newest first
/clients/{client}/attribution/conversions/log
MCP tool list_offline_conversion_sends
Global admins, Client admins
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
status | query | sent | skipped | failed | sending | |
limit | query | integer |
Send a failed offline conversion again
/clients/{client}/attribution/conversions/send-again
MCP tool resend_offline_conversion
Global admins, Client admins
Pass received_at, mapping, source and event_id from a failed log row. Sent ones are never sent twice.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
received_at required | body | string | |
mapping required | body | string | |
source required | body | string | |
event_id required | body | string |
Send the last N days of stored events through the mappings
/clients/{client}/attribution/conversions/backfill
MCP tool backfill_offline_conversions
Global admins, Client admins
Runs in the background (202). Events already sent are skipped, so running it twice is safe. Up to 90 days, the longest Google Ads takes conversions after a click.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
days | body | integer |
A client's tag rules, versions, tag values and what the rules change
/clients/{client}/attribution/tag-rules
MCP tool get_tag_rules
Global admins, Client admins
Tag rules clean up campaign tags (source, medium, campaign, term, content) and group visits into channels. They apply when reports are read: the original tags are never changed, so new rules apply to all history at once. Also returns the distinct tag values of the last 90 days with counts, what the rules change (changes), values no rule covers yet (unmapped, tag health) and the clean values a link builder offers (approved).
| Field | In | Type | About |
|---|---|---|---|
client required | path | string |
Save tag rules as a new version
/clients/{client}/attribution/tag-rules
MCP tool update_tag_rules
Global admins, Client admins
Body: lowercase, values (field, match exact|contains|starts|regex, value with | between alternatives, to), channels (name, when: conditions on mapped values, all must hold) and default_channels (GA4-style groups for anything unmatched). Saved versions are kept.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
lowercase | body | boolean | |
default_channels | body | boolean | |
values | body | array of object | |
channels | body | array of object |
Bring back an older version of the tag rules
/clients/{client}/attribution/tag-rules/restore
MCP tool restore_tag_rules
Global admins, Client admins
Saves the chosen version again as the newest one.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
version required | body | integer |
AI-suggested tag rules (not saved)
/clients/{client}/attribution/tag-rules/suggest
MCP tool suggest_tag_rules
Global admins, Client admins
Claude reviews the client's distinct tag values (last 90 days; only values and counts are sent) and suggests merges and channel groups, with what they would change. Nothing is saved until the rules are sent to PUT tag-rules. Counts as AI usage.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string |
Build a campaign (UTM) link with clean tags
/clients/{client}/attribution/links/build
MCP tool build_utm_link
Global admins, Client admins
The tags are cleaned by the client's tag rules first, so new links arrive standardized. save: true keeps the link (with name) in the client's saved links.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
url required | body | string | |
source required | body | string | |
medium required | body | string | |
campaign | body | string | |
term | body | string | |
content | body | string | |
save | body | boolean | |
name | body | string |
Saved campaign links
/clients/{client}/attribution/links
MCP tool list_utm_links
Global admins, Client admins
Newest first.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string |
Forget a saved campaign link
/clients/{client}/attribution/links/{link_id}
MCP tool delete_utm_link
Global admins, Client admins
The link itself keeps working.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
link_id required | path | string |
Whether a website has first-party mode on (never the key)
/clients/{client}/tracked-sites/{site_id}/proxy
MCP tool get_site_proxy
Global admins, Client admins
In first-party mode the website serves our tag and forwards its calls from its own address (<path>/t.js, <path>/m/<file>, <path>/i, <path>/a), so browsers keep visitor IDs as first-party data and ad blockers can't tell the tag from the site.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string |
Turn on first-party mode, or make a new proxy key
/clients/{client}/tracked-sites/{site_id}/proxy
MCP tool enable_site_proxy
Global admins, Client admins
Returns the proxy key once, with ready-to-install Cloudflare Worker and Nginx code and the script tag to put in the page. Only the key's hash is kept; a new key stops the old one. WordPress sites with the Metric Sensei plugin turn this on by themselves.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | |
path | body | string |
Turn off first-party mode
/clients/{client}/tracked-sites/{site_id}/proxy
MCP tool disable_site_proxy
Global admins, Client admins
The site's tag goes back to the CDN. Put the normal snippet back in the page first.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string |
Everything we know about one visitor, person or household
/clients/{client}/attribution/lookup
MCP tool lookup_visitor
Global admins, Client admins
Type what you have in q: one of our IDs (browser, device, person or household, 32 hex characters), an email address or phone number (normalized and SHA-256 hashed the way the attribution script does; the plain text is never stored), a SHA-256 hash, an IP address, or another platform's ID as it is (GA1.1.123.456, a GA client ID like 1234567890.1700000000, a HubSpot or Segment ID ...). Other platforms' IDs are tried as every ID type we collect, and text that could also be one of our IDs is searched both ways; matched_ids says which types matched. Write _ga=GA1.1.123.456 to search one cookie only. Only this client's visitors are searched.
The answer lists the people, browsers and households found, other platforms' IDs, hashed contact details and, where the website keeps them (keep_contact), the readable contact details, decrypted only for this answer. The visit history (sessions, form submits, identify calls and the campaign behind each visit) covers up to the last 95 days.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
q required | query | string | |
days | query | integer | How far back the visit history goes (1 to 95 days). |
Privacy requests
A client's website visitor asks to see or delete their data. Log the request, check who is asking, search every service, then export or delete; the client answers the visitor.
List the client's visitor privacy requests, newest first
/clients/{client}/privacy-requests
MCP tool list_privacy_requests
Global admins, Client admins
| Field | In | Type | About |
|---|---|---|---|
client required | path | string |
Log a visitor's request to see, delete, correct or stop using their data
/clients/{client}/privacy-requests
MCP tool create_privacy_request
Global admins, Client admins
identifiers are what the visitor gave: email, phone, the browser ID shown by msa('privacy') on your site, or another tool's ID. They are kept only as hashes or IDs. IP addresses are refused (many people share one). The due date is 30 days after received_at (default now). send_link_to (one of the identifiers, an email) emails the visitor a one-time link that confirms the request is theirs.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
kind required | body | access | delete | correct | stop | |
identifiers required | body | array of string | |
received_at | body | string | |
by_agent | body | boolean | Made by an authorized agent for the visitor |
note | body | string | |
send_link_to | body | string |
Get one request with its matches and a draft answer for the visitor
/clients/{client}/privacy-requests/{request}
MCP tool get_privacy_request
Global admins, Client admins
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
request required | path | string | The privacy request's ID (16 hex characters) |
Email the visitor a one-time link that confirms the request is theirs
/clients/{client}/privacy-requests/{request}/verify-link
MCP tool send_privacy_verify_link
Global admins, Client admins
The email must be one the request was logged with. The link works for 7 days, once, and unlocks only data tied to that email.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
request required | path | string | The privacy request's ID (16 hex characters) |
email | body | string |
Record how you checked who is asking, without the email link
/clients/{client}/privacy-requests/{request}/attest
MCP tool attest_privacy_request
Global admins, Client admins
browser_id: the visitor gave you the browser ID that msa('privacy') showed them on your site (only that browser's data is reachable). attested: you checked by your own means (a signed-in customer, say); say how.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
request required | path | string | The privacy request's ID (16 hex characters) |
method | body | browser_id | attested | |
reason | body | string |
Search every service for the verified visitor (runs in the background)
/clients/{client}/privacy-requests/{request}/search
MCP tool search_privacy_request
Global admins, Client admins
Answers at once; poll the request until status is found. Matches are exact or guessed (another browser on the same device, a fingerprint match, a shared home connection).
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
request required | path | string | The privacy request's ID (16 hex characters) |
Choose which matches belong to the visitor
/clients/{client}/privacy-requests/{request}/selection
MCP tool select_privacy_matches
Global admins, Client admins
A copy of the data (access) may include exact matches only.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
request required | path | string | The privacy request's ID (16 hex characters) |
keys | body | array of string |
Go ahead and make the copy, or delete the chosen data (runs in the background)
/clients/{client}/privacy-requests/{request}/act
MCP tool act_on_privacy_request
Global admins, Client admins
access makes an export kept 7 days. The other kinds delete the chosen data in every service and both Regions, check that nothing is left, then put the visitor's email and phone hashes on the client's do-not-match list.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
request required | path | string | The privacy request's ID (16 hex characters) |
Download the copy of the visitor's data (JSON, kept 7 days)
/clients/{client}/privacy-requests/{request}/export
MCP tool get_privacy_request_export
Global admins, Client admins
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
request required | path | string | The privacy request's ID (16 hex characters) |
Move the due date once, with a reason the visitor is told
/clients/{client}/privacy-requests/{request}/extend
MCP tool extend_privacy_request
Global admins, Client admins
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
request required | path | string | The privacy request's ID (16 hex characters) |
days | body | integer | |
reason | body | string |
Refuse the request, with a reason the visitor is told (they may appeal)
/clients/{client}/privacy-requests/{request}/refuse
MCP tool refuse_privacy_request
Global admins, Client admins
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
request required | path | string | The privacy request's ID (16 hex characters) |
reason | body | string |
Close the request once the visitor has been answered
/clients/{client}/privacy-requests/{request}/close
MCP tool close_privacy_request
Global admins, Client admins
Only hashes and counts are kept, for 24 months; the matches and any export are deleted.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
request required | path | string | The privacy request's ID (16 hex characters) |
Carry on with a search, export or deletion that stopped
/clients/{client}/privacy-requests/{request}/retry
MCP tool retry_privacy_request
Global admins, Client admins
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
request required | path | string | The privacy request's ID (16 hex characters) |
Billing
Usage, invoices (one per agency per month, broken down by client), payments, balance and saved cards.
Balances and invoices for every agency you can see
/billing
MCP tool get_billing_overview
Global admins, Agency admins
An agency's balance, invoices and saved cards
/agencies/{agency_id}/billing
MCP tool get_agency_billing
Global admins, Agency admins
| Field | In | Type | About |
|---|---|---|---|
agency_id required | path | string |
Usage and charges so far, by client
/agencies/{agency_id}/billing/usage
MCP tool get_agency_usage
Global admins, Agency admins
An estimate of the invoice for a month (this month by default), with each client's measured usage.
| Field | In | Type | About |
|---|---|---|---|
agency_id required | path | string | |
period | query | string |
Get an invoice with its lines by client and its payments
/agencies/{agency_id}/invoices/{period}
MCP tool get_invoice
Global admins, Agency admins
| Field | In | Type | About |
|---|---|---|---|
agency_id required | path | string | |
period required | path | string | The invoice's month. |
Charge the invoice's balance to the agency's default card now
/agencies/{agency_id}/invoices/{period}/pay
MCP tool pay_invoice
Global admins, Agency admins
Answers 402 if the card is declined.
| Field | In | Type | About |
|---|---|---|---|
agency_id required | path | string | |
period required | path | string | The invoice's month. |
A one-time token for Braintree's card form
/agencies/{agency_id}/card-form-token
MCP tool get_card_form_token
Global admins, Agency admins
Use it with Braintree's client SDK (Hosted Fields or Drop-in) to collect a card; send the nonce it returns to Save a card. Card numbers never reach Metric Sensei.
| Field | In | Type | About |
|---|---|---|---|
agency_id required | path | string |
Save a card for automatic charges
/agencies/{agency_id}/cards
MCP tool add_card
Global admins, Agency admins
| Field | In | Type | About |
|---|---|---|---|
agency_id required | path | string | |
nonce required | body | string | From Braintree's card form. |
default | body | boolean |
Make a saved card the one that gets charged
/agencies/{agency_id}/cards/{token}/default
MCP tool set_default_card
Global admins, Agency admins
| Field | In | Type | About |
|---|---|---|---|
agency_id required | path | string | |
token required | path | string |
Delete a saved card
/agencies/{agency_id}/cards/{token}
MCP tool delete_card
Global admins, Agency admins
| Field | In | Type | About |
|---|---|---|---|
agency_id required | path | string | |
token required | path | string |
Pricing
Monthly base fee per service per client, free usage included, and prices above it.
Get the prices in force
/pricing
MCP tool get_pricing
Global admins, Agency admins
Each service has a monthly base fee per agency that includes included_clients clients, a client_fee for each client above that, and per metric the units each client adds to the agency's pooled allowance (included, also in free_units); usage above the pool is charged at unit_price. tiers raise the base fee and clients included and discount the rest; a standard plan's tier applies to every service (built-in plans Core, Growth and Scale). platform (storage and API requests) has no base fee and covers every client with any service on.
Activity
Who changed what, and when, in a client or agency (admin page, this API and API/MCP Gateway write tools).
See who changed what in a client
/clients/{client}/activity
MCP tool list_client_activity
Global admins, Client admins
Every change made in the admin page (its own screens and the paid services' screens), through this API or by an API/MCP Gateway write tool, and every super admin log-in to the client, newest first. Normal reads aren't logged. Kept for a year. Secrets are never logged. Filter by person, source, kind, action, role and dates, and search the words with q.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
limit | query | integer | Most items to return (default 100, max 500). |
cursor | query | string | Where to continue: the |
actor | query | string | Only entries by this person (their email). |
via | query | page | api | gateway | cli | sign-in | system | Only entries from here (the admin page, this API, the API/MCP Gateway, the command line, the sign-in page, or the platform itself). |
kind | query | change | sign-in | session | deploy | Only changes, sign-ins, super admin log-ins to accounts ( |
action | query | string | Only this action, by its stable name (e.g. |
role | query | string | Only entries made in this role ( |
q | query | string | Text search over the summary, person, action, target, client and agency, ignoring case. Every word must appear. |
since | query | string | Only entries on or after this day (UTC). |
until | query | string | Only entries on or before this day (UTC). |
See who changed what in an agency and its clients
/agencies/{agency_id}/activity
MCP tool list_agency_activity
Global admins, Agency admins
Changes to the agency itself and to every client it owned at the time, newest first, with the same filters and search as a client's log. Kept for a year.
| Field | In | Type | About |
|---|---|---|---|
agency_id required | path | string | |
limit | query | integer | Most items to return (default 100, max 500). |
cursor | query | string | Where to continue: the |
actor | query | string | Only entries by this person (their email). |
via | query | page | api | gateway | cli | sign-in | system | Only entries from here (the admin page, this API, the API/MCP Gateway, the command line, the sign-in page, or the platform itself). |
kind | query | change | sign-in | session | deploy | Only changes, sign-ins, super admin log-ins to accounts ( |
action | query | string | Only this action, by its stable name (e.g. |
role | query | string | Only entries made in this role ( |
q | query | string | Text search over the summary, person, action, target, client and agency, ignoring case. Every word must appear. |
since | query | string | Only entries on or after this day (UTC). |
until | query | string | Only entries on or before this day (UTC). |
See your own sign-ins and changes
/me/activity
MCP tool list_my_activity
Everyone
Every time you signed in (the admin page, an AI app or the Admin API's sign-in) and every change you made, anywhere on the platform, newest first, with the same filters and search as a client's log. Kept for a year.
| Field | In | Type | About |
|---|---|---|---|
limit | query | integer | Most items to return (default 100, max 500). |
cursor | query | string | Where to continue: the |
actor | query | string | Only entries by this person (their email). |
via | query | page | api | gateway | cli | sign-in | system | Only entries from here (the admin page, this API, the API/MCP Gateway, the command line, the sign-in page, or the platform itself). |
kind | query | change | sign-in | session | deploy | Only changes, sign-ins, super admin log-ins to accounts ( |
action | query | string | Only this action, by its stable name (e.g. |
role | query | string | Only entries made in this role ( |
q | query | string | Text search over the summary, person, action, target, client and agency, ignoring case. Every word must appear. |
since | query | string | Only entries on or after this day (UTC). |
until | query | string | Only entries on or before this day (UTC). |
See the audit log you're allowed to see
/audit
MCP tool list_audit_log
Everyone
The audit log, newest first, scoped to you. Super admins see everyone's: every person's sign-ins, super admins' log-ins to clients and agencies, every change in any client or agency, platform settings, and each stack deploy in both Regions (and can narrow it with client or agency). Agency admins see their agency's trail, which includes all its clients (client narrows it to one; with more than one agency, agency picks which). Client admins see their client's trail (with more than one client, client picks which). Anyone else sees only their own sign-ins and changes. Asking for a client or agency you can't see is refused. Without dates a super admin's view covers the last year; one request looks at a limited number of entries, so a narrow search may return a short (even empty) page with a next_cursor: keep going until it is null.
| Field | In | Type | About |
|---|---|---|---|
limit | query | integer | Most items to return (default 100, max 500). |
cursor | query | string | Where to continue: the |
actor | query | string | Only entries by this person (their email). |
via | query | page | api | gateway | cli | sign-in | system | Only entries from here (the admin page, this API, the API/MCP Gateway, the command line, the sign-in page, or the platform itself). |
kind | query | change | sign-in | session | deploy | Only changes, sign-ins, super admin log-ins to accounts ( |
action | query | string | Only this action, by its stable name (e.g. |
role | query | string | Only entries made in this role ( |
q | query | string | Text search over the summary, person, action, target, client and agency, ignoring case. Every word must appear. |
since | query | string | Only entries on or after this day (UTC). |
until | query | string | Only entries on or before this day (UTC). |
client | query | string | Only entries in this client (one you can see). |
agency | query | string | Only entries in this agency and its clients (one you can see). |
Usage
API/MCP Gateway tool calls per day, per service and per client (successful calls are billed, failed ones are not), and the numbers on a client's and an agency's Home.
See a client's API/MCP Gateway tool calls per day and per service
/clients/{client}/usage
MCP tool get_client_usage
Global admins, Client admins
Successful API/MCP Gateway tool calls (the ones that are billed) for each of the last days days (UTC, today included), split by service, plus failed calls, which are never billed. month is this month's billed total next to the free calls the API/MCP Gateway's base fee includes (included, null if the API/MCP Gateway has no price). Calls made before November 2026 have no service and are listed as other.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
days | query | integer | How many days to show, today included (1 to 90). |
See API/MCP Gateway tool calls for each of an agency's clients
/agencies/{agency_id}/usage
MCP tool get_agency_gateway_usage
Global admins, Agency admins
Each client's successful and failed API/MCP Gateway tool calls over the last days days, busiest first, with its calls per day, plus the agency's total per day. For charges, see the billing usage estimate.
| Field | In | Type | About |
|---|---|---|---|
agency_id required | path | string | |
days | query | integer | How many days to show, today included (1 to 90). |
See the numbers on a client's Home
/clients/{client}/summary
MCP tool get_client_summary
Global admins, Client admins
One entry per Home tile, only for the paid services the client has on: API/MCP Gateway calls per day for the last 30 days (UTC), Attribution sessions, submits and people identified, data sources and how many need a new sign-in, live events received, Dashboards and AI Services usage this month. Agency admins (and super admins) also get the client's share of this month's bill so far (client_bill, an estimate until the month closes). Tiles with nothing to show are left out; a tile that couldn't be read has error and no data.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
tiles | query | string | Only these tiles, comma-separated keys (e.g. |
lazy | query | skip |
|
See the numbers on an agency's Home
/agencies/{agency_id}/summary
MCP tool get_agency_summary
Global admins, Agency admins
The agency's free trial (while one runs), its bill (this month so far, plan, balance owed and when services would pause) and each service's numbers added up over its active clients. A service's tile shows only when at least one active client has that service on.
| Field | In | Type | About |
|---|---|---|---|
agency_id required | path | string | |
tiles | query | string | Only these tiles, comma-separated keys (e.g. |
lazy | query | skip |
|
SEO
SEO (rank tracking, keyword research, site audits, backlinks, competitors, local grids, content briefs, AI visibility, alerts, reports, link prospects, log analysis) for clients with SEO on. One route runs every SEO operation; the operations and their arguments are the same as the API/MCP Gateway's seo_* tools.
Read SEO data for a client
/clients/{client}/seo/{op}
MCP tool get_seo
Everyone
Runs one read or research SEO operation with the query string as its arguments (lists as comma-separated text), e.g. keywords?project_id=p_abc or keyword_ideas?seed=plumber%20austin&kind=questions. Anyone with a role in the client may read; the client must have SEO on. Research operations are billed as SEO lookups.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
op required | path | string | The SEO operation. Reads (GET): projects, project, overview, keywords, keyword_history, serp_snapshot, rank_summary, rank_trend, audits, audit, audit_issue, audit_pages, audit_page, crawl_summary, competitors, grid_runs, grid, local_profile, briefs, brief, search_console, paid_overlap, organic_pages, ai_visibility, alerts, prospects, prospect_verify, log_analyses, log_analysis, disavow_file. Research, billed as lookups: keyword_overview, keyword_ideas, serp, domain_overview, ranked_keywords, competitor_discover, keyword_gap, backlinks_summary, backlinks, referring_domains, anchors, backlinks_new_lost, backlink_gap. Changes and paid runs (POST; client admins for changes): project_create, project_update, project_delete, keywords_add, keywords_remove, keywords_tag, audit_start, grid_run, content_brief, content_grade, ai_check, report_pdf, prospects_add, prospects_from_gap, prospect_update, prospect_remove, log_upload, webhook_secret. |
project_id | query | string | The SEO project (one website); |
Change SEO settings or run an SEO job for a client
/clients/{client}/seo/{op}
MCP tool run_seo_operation
Everyone
Runs one SEO operation with the JSON body as its arguments, e.g. keywords_add with {"project_id": "p_abc", "keywords": ["plumber austin"], "tags": ["money"]} or audit_start with {"project_id": "p_abc"}. Changes to projects, keywords, prospects and webhooks need a client admin or agency admin; paid runs (audits, local grids, content tools, AI checks) are billed to the client.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
op required | path | string | The SEO operation. Reads (GET): projects, project, overview, keywords, keyword_history, serp_snapshot, rank_summary, rank_trend, audits, audit, audit_issue, audit_pages, audit_page, crawl_summary, competitors, grid_runs, grid, local_profile, briefs, brief, search_console, paid_overlap, organic_pages, ai_visibility, alerts, prospects, prospect_verify, log_analyses, log_analysis, disavow_file. Research, billed as lookups: keyword_overview, keyword_ideas, serp, domain_overview, ranked_keywords, competitor_discover, keyword_gap, backlinks_summary, backlinks, referring_domains, anchors, backlinks_new_lost, backlink_gap. Changes and paid runs (POST; client admins for changes): project_create, project_update, project_delete, keywords_add, keywords_remove, keywords_tag, audit_start, grid_run, content_brief, content_grade, ai_check, report_pdf, prospects_add, prospects_from_gap, prospect_update, prospect_remove, log_upload, webhook_secret. |
Analytics
Website analytics for a client with Analytics on: traffic, channels, pages, goals, revenue, funnels, cohorts, heatmaps, recordings, A/B tests and the comparison with GA4. Everything the Analytics screen shows, run as you; the Analytics service checks your role in the client on every call. Most take a date range: `range` (today, yesterday, last_7_days, last_28_days, last_30_days, last_90_days, this_month, last_month, this_year, last_12_months or custom with `start` and `end`), in the website's own time zone. Settings (goals, funnels, linked sources) are under Tracking.
See what you may do in a client's Analytics
/clients/{client}/analytics/access
MCP tool get_analytics_access
Everyone
Your role in the client as Analytics sees it.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string |
Get your Analytics preferences
/clients/{client}/analytics/preferences
MCP tool get_analytics_preferences
Everyone
Which numbers Analytics reports open on for you in this client (data): auto (blended on websites with GA4 linked, our tag's numbers elsewhere), ours, ga4 or blended. A saved ga4 or blended choice shows our tag's numbers on websites without GA4.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string |
Set your Analytics preferences
/clients/{client}/analytics/preferences
MCP tool set_analytics_preferences
Everyone
Choose which numbers Analytics reports open on for you in this client, like the Numbers switch on the Analytics screen. It applies when a report call doesn't send data, here and in the AI assistant. auto goes back to the default.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
data required | body | auto | ours | ga4 | blended | auto (blended where GA4 is linked, else ours), ours, ga4 or blended. |
List a client's websites with Analytics on
/clients/{client}/analytics/sites
MCP tool list_analytics_sites
Everyone
The websites Analytics measures for this client, with their time zone and linked data sources. The other Analytics operations take a website's site_id from here.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
limit | query | integer | Most items to return (default 100, max 500). |
cursor | query | string | Where to continue: the |
Analytics overview for a website
/clients/{client}/analytics/sites/{site_id}/overview
MCP tool get_analytics_overview
Everyone
Headline numbers for the date range (visitors, visits, page views, conversions, revenue), the change against the period before, and a day-by-day chart.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID (MS-XXXXXXXX), from List a client's websites with Analytics on. |
range | query | string | The date range: today, yesterday, this_week, last_week, last_7_days, last_14_days, last_28_days (default), last_30_days, last_90_days, this_month, last_month, this_quarter, last_quarter, this_year, last_year, last_12_months or custom (with start and end). Whole days; 'last N days' ends yesterday. |
start | query | string | With range custom: the first day, yyyy-mm-dd. |
end | query | string | With range custom: the last day, yyyy-mm-dd. |
data | query | string | Whose numbers: ours, ga4 or blended (the last two need GA4 linked). Without it: your saved choice (Get your Analytics preferences), else blended when GA4 is linked to the website, else ours. The answer's |
compare | query | none | previous | year | custom | Compare with another period: none (default; the overview defaults to previous), previous (the period just before, of the same length; this_month/quarter/year compare the same days of the one before, last_month/quarter/year the whole one before), year (the same dates a year earlier) or custom (with compare_start and compare_end). The answer then adds compare_period, previous and change (percent) on its totals and on each row. |
compare_start | query | string | With compare custom: the first compared day, yyyy-mm-dd. |
compare_end | query | string | With compare custom: the last compared day, yyyy-mm-dd. |
match_weekday | query | 0 | 1 | 1 to line compared days up by day of the week (previous: whole weeks back; year: 52 weeks back). |
Break a website's traffic down by one dimension
/clients/{client}/analytics/sites/{site_id}/breakdown/{dimension}
MCP tool get_analytics_breakdown
Everyone
Visitors and conversions grouped by one dimension: channel, source, medium, source_medium, campaign, content, term, page, entry_page, referrer, click_id, country, region, city, device, browser, os, language or hostname.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID (MS-XXXXXXXX), from List a client's websites with Analytics on. |
dimension required | path | string | What to group by: channel, source, medium, source_medium, campaign, content, term, page, entry_page, referrer, click_id, country, region, city, device, browser, os, language or hostname. |
range | query | string | The date range: today, yesterday, this_week, last_week, last_7_days, last_14_days, last_28_days (default), last_30_days, last_90_days, this_month, last_month, this_quarter, last_quarter, this_year, last_year, last_12_months or custom (with start and end). Whole days; 'last N days' ends yesterday. |
start | query | string | With range custom: the first day, yyyy-mm-dd. |
end | query | string | With range custom: the last day, yyyy-mm-dd. |
compare | query | none | previous | year | custom | Compare with another period: none (default; the overview defaults to previous), previous (the period just before, of the same length; this_month/quarter/year compare the same days of the one before, last_month/quarter/year the whole one before), year (the same dates a year earlier) or custom (with compare_start and compare_end). The answer then adds compare_period, previous and change (percent) on its totals and on each row. |
compare_start | query | string | With compare custom: the first compared day, yyyy-mm-dd. |
compare_end | query | string | With compare custom: the last compared day, yyyy-mm-dd. |
match_weekday | query | 0 | 1 | 1 to line compared days up by day of the week (previous: whole weeks back; year: 52 weeks back). |
data | query | string | Whose numbers: ours, ga4 or blended (the last two need GA4 linked). Without it: your saved choice (Get your Analytics preferences), else blended when GA4 is linked to the website, else ours. The answer's |
raw | query | string | Send 1 for the source and medium as they arrived, before the client's tag rules. |
limit | query | integer | How many rows (default 50). |
q | query | string | Only rows containing this text. |
List a website's events
/clients/{client}/analytics/sites/{site_id}/events
MCP tool get_analytics_events
Everyone
The events the website sent in the date range: rows (each event's count, visits and conversion rate), properties (text parameter values per event), numbers (number parameters per event: count, sum and average), items (GA4-style items per event: events, quantity and revenue) and currency. How websites send events: the tracking JavaScript API guide at /docs/tracking.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID (MS-XXXXXXXX), from List a client's websites with Analytics on. |
range | query | string | The date range: today, yesterday, this_week, last_week, last_7_days, last_14_days, last_28_days (default), last_30_days, last_90_days, this_month, last_month, this_quarter, last_quarter, this_year, last_year, last_12_months or custom (with start and end). Whole days; 'last N days' ends yesterday. |
start | query | string | With range custom: the first day, yyyy-mm-dd. |
end | query | string | With range custom: the last day, yyyy-mm-dd. |
compare | query | none | previous | year | custom | Compare with another period: none (default; the overview defaults to previous), previous (the period just before, of the same length; this_month/quarter/year compare the same days of the one before, last_month/quarter/year the whole one before), year (the same dates a year earlier) or custom (with compare_start and compare_end). The answer then adds compare_period, previous and change (percent) on its totals and on each row. |
compare_start | query | string | With compare custom: the first compared day, yyyy-mm-dd. |
compare_end | query | string | With compare custom: the last compared day, yyyy-mm-dd. |
match_weekday | query | 0 | 1 | 1 to line compared days up by day of the week (previous: whole weeks back; year: 52 weeks back). |
Get a website's goal conversions
/clients/{client}/analytics/sites/{site_id}/goals
MCP tool get_analytics_goals
Everyone
Conversions for each goal in the date range, by day.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID (MS-XXXXXXXX), from List a client's websites with Analytics on. |
range | query | string | The date range: today, yesterday, this_week, last_week, last_7_days, last_14_days, last_28_days (default), last_30_days, last_90_days, this_month, last_month, this_quarter, last_quarter, this_year, last_year, last_12_months or custom (with start and end). Whole days; 'last N days' ends yesterday. |
start | query | string | With range custom: the first day, yyyy-mm-dd. |
end | query | string | With range custom: the last day, yyyy-mm-dd. |
compare | query | none | previous | year | custom | Compare with another period: none (default; the overview defaults to previous), previous (the period just before, of the same length; this_month/quarter/year compare the same days of the one before, last_month/quarter/year the whole one before), year (the same dates a year earlier) or custom (with compare_start and compare_end). The answer then adds compare_period, previous and change (percent) on its totals and on each row. |
compare_start | query | string | With compare custom: the first compared day, yyyy-mm-dd. |
compare_end | query | string | With compare custom: the last compared day, yyyy-mm-dd. |
match_weekday | query | 0 | 1 | 1 to line compared days up by day of the week (previous: whole weeks back; year: 52 weeks back). |
data | query | string | Whose numbers: ours, ga4 or blended (the last two need GA4 linked). Without it: your saved choice (Get your Analytics preferences), else blended when GA4 is linked to the website, else ours. The answer's |
See a website's visitors right now
/clients/{client}/analytics/sites/{site_id}/live
MCP tool get_analytics_live
Everyone
Like GA4's Realtime: visitors in the last minutes minutes (default 30; last_30_minutes and last_5_minutes stay for older callers), visitors, page views and conversions per minute, top pages, channels, sources, campaigns, countries, devices, events and goals, locations for a live map ({lat, lon, label, visitors, conversions}, city level, rounded to 0.1 degree) and recent activity. Source, medium, campaign and channel use the client's tag rules unless raw=true. Both regions are read and added up. Nothing in the answer identifies a person. The same answer as the API/MCP Gateway tool analytics_live.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID (MS-XXXXXXXX), from List a client's websites with Analytics on. |
minutes | query | integer | |
raw | query | boolean |
Get a website's revenue
/clients/{client}/analytics/sites/{site_id}/revenue
MCP tool get_analytics_revenue
Everyone
Revenue in the date range, grouped by channel, source and medium, campaign, entry page or event.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID (MS-XXXXXXXX), from List a client's websites with Analytics on. |
range | query | string | The date range: today, yesterday, this_week, last_week, last_7_days, last_14_days, last_28_days (default), last_30_days, last_90_days, this_month, last_month, this_quarter, last_quarter, this_year, last_year, last_12_months or custom (with start and end). Whole days; 'last N days' ends yesterday. |
start | query | string | With range custom: the first day, yyyy-mm-dd. |
end | query | string | With range custom: the last day, yyyy-mm-dd. |
compare | query | none | previous | year | custom | Compare with another period: none (default; the overview defaults to previous), previous (the period just before, of the same length; this_month/quarter/year compare the same days of the one before, last_month/quarter/year the whole one before), year (the same dates a year earlier) or custom (with compare_start and compare_end). The answer then adds compare_period, previous and change (percent) on its totals and on each row. |
compare_start | query | string | With compare custom: the first compared day, yyyy-mm-dd. |
compare_end | query | string | With compare custom: the last compared day, yyyy-mm-dd. |
match_weekday | query | 0 | 1 | 1 to line compared days up by day of the week (previous: whole weeks back; year: 52 weeks back). |
by | query | string | channel (default), source_medium, campaign, entry_page or event. |
Get a website's Core Web Vitals
/clients/{client}/analytics/sites/{site_id}/vitals
MCP tool get_analytics_vitals
Everyone
Loading, responsiveness and layout stability as real visitors experienced them (75th percentile), by page and device.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID (MS-XXXXXXXX), from List a client's websites with Analytics on. |
range | query | string | The date range: today, yesterday, this_week, last_week, last_7_days, last_14_days, last_28_days (default), last_30_days, last_90_days, this_month, last_month, this_quarter, last_quarter, this_year, last_year, last_12_months or custom (with start and end). Whole days; 'last N days' ends yesterday. |
start | query | string | With range custom: the first day, yyyy-mm-dd. |
end | query | string | With range custom: the last day, yyyy-mm-dd. |
Get a website's visitor cohorts
/clients/{client}/analytics/sites/{site_id}/cohorts
MCP tool get_analytics_cohorts
Everyone
How many visitors who first came in each week or month came back in the weeks or months after.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID (MS-XXXXXXXX), from List a client's websites with Analytics on. |
range | query | string | The date range: today, yesterday, this_week, last_week, last_7_days, last_14_days, last_28_days (default), last_30_days, last_90_days, this_month, last_month, this_quarter, last_quarter, this_year, last_year, last_12_months or custom (with start and end). Whole days; 'last N days' ends yesterday. |
start | query | string | With range custom: the first day, yyyy-mm-dd. |
end | query | string | With range custom: the last day, yyyy-mm-dd. |
unit | query | string | week (default) or month. |
See where visitors go before or after a page
/clients/{client}/analytics/sites/{site_id}/paths
MCP tool get_analytics_paths
Everyone
The most common next or previous pages for one page.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID (MS-XXXXXXXX), from List a client's websites with Analytics on. |
range | query | string | The date range: today, yesterday, this_week, last_week, last_7_days, last_14_days, last_28_days (default), last_30_days, last_90_days, this_month, last_month, this_quarter, last_quarter, this_year, last_year, last_12_months or custom (with start and end). Whole days; 'last N days' ends yesterday. |
start | query | string | With range custom: the first day, yyyy-mm-dd. |
end | query | string | With range custom: the last day, yyyy-mm-dd. |
page | query | string | The page, for example /pricing. |
direction | query | string | next (default) or previous. |
Get a page's click heatmap
/clients/{client}/analytics/sites/{site_id}/heatmap
MCP tool get_analytics_heatmap
Everyone
Where visitors clicked on one page, for one kind of device.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID (MS-XXXXXXXX), from List a client's websites with Analytics on. |
range | query | string | The date range: today, yesterday, this_week, last_week, last_7_days, last_14_days, last_28_days (default), last_30_days, last_90_days, this_month, last_month, this_quarter, last_quarter, this_year, last_year, last_12_months or custom (with start and end). Whole days; 'last N days' ends yesterday. |
start | query | string | With range custom: the first day, yyyy-mm-dd. |
end | query | string | With range custom: the last day, yyyy-mm-dd. |
page | query | string | The page, for example /. |
device | query | string | Desktop, Mobile or Tablet. |
Get a page's scroll depth
/clients/{client}/analytics/sites/{site_id}/scroll
MCP tool get_analytics_scroll
Everyone
How far down one page visitors scrolled.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID (MS-XXXXXXXX), from List a client's websites with Analytics on. |
range | query | string | The date range: today, yesterday, this_week, last_week, last_7_days, last_14_days, last_28_days (default), last_30_days, last_90_days, this_month, last_month, this_quarter, last_quarter, this_year, last_year, last_12_months or custom (with start and end). Whole days; 'last N days' ends yesterday. |
start | query | string | With range custom: the first day, yyyy-mm-dd. |
end | query | string | With range custom: the last day, yyyy-mm-dd. |
page | query | string | The page, for example /. |
Make a link that shows a heatmap over the live page
/clients/{client}/analytics/sites/{site_id}/heatmap-link
MCP tool create_analytics_heatmap_link
Everyone
Returns a link that opens the real page with its click heatmap drawn on top. The link works for one hour.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID (MS-XXXXXXXX), from List a client's websites with Analytics on. |
page | body | string | The page, for example /. |
range | body | string | The date range, for example last_28_days. |
device | body | string | Desktop, Mobile or Tablet. |
Ask about a segment of a website's visitors
/clients/{client}/analytics/sites/{site_id}/segment
MCP tool query_analytics_segment
Everyone
Numbers for only the visitors matching a set of filters (each with a field, an operator and a value), or a saved segment by name, optionally broken down by one dimension. It only reads; it is a POST because the question can be long.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID (MS-XXXXXXXX), from List a client's websites with Analytics on. |
filters | body | array of any | Filters, each {field, op, value}. |
segment | body | string | Or the name of a saved segment. |
breakdown | body | string | A dimension to group by. |
range | body | string | The date range. |
Export a website's raw events
/clients/{client}/analytics/sites/{site_id}/exports
MCP tool create_analytics_export
Everyone
Starts an export of the date range's events and returns an export_id. Read it with Get an Analytics export until it has a download link.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID (MS-XXXXXXXX), from List a client's websites with Analytics on. |
range | body | string | The date range. |
start | body | string | With range custom: yyyy-mm-dd. |
end | body | string | With range custom: yyyy-mm-dd. |
Get an Analytics export
/clients/{client}/analytics/sites/{site_id}/exports/{export_id}
MCP tool get_analytics_export
Everyone
The export's state and, once it is ready, a download link.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID (MS-XXXXXXXX), from List a client's websites with Analytics on. |
export_id required | path | string | The export's ID, from Export a website's raw events. |
List a website's traffic alerts
/clients/{client}/analytics/sites/{site_id}/alerts
MCP tool list_analytics_alerts
Everyone
Unusual drops and spikes Analytics noticed in the last 30 days.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID (MS-XXXXXXXX), from List a client's websites with Analytics on. |
List a website's session recordings
/clients/{client}/analytics/sites/{site_id}/replays
MCP tool list_analytics_replays
Everyone
Recorded visits (an add-on), newest first, optionally only those that included one page.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID (MS-XXXXXXXX), from List a client's websites with Analytics on. |
range | query | string | The date range: today, yesterday, this_week, last_week, last_7_days, last_14_days, last_28_days (default), last_30_days, last_90_days, this_month, last_month, this_quarter, last_quarter, this_year, last_year, last_12_months or custom (with start and end). Whole days; 'last N days' ends yesterday. |
start | query | string | With range custom: the first day, yyyy-mm-dd. |
end | query | string | With range custom: the last day, yyyy-mm-dd. |
page | query | string | Only visits that included this page. |
Get a session recording
/clients/{client}/analytics/sites/{site_id}/replays/{day}/{replay_id}
MCP tool get_analytics_replay
Everyone
Signed links to one recording's parts, for the player. They work for a few minutes.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID (MS-XXXXXXXX), from List a client's websites with Analytics on. |
day required | path | string | The recording's day (yyyy-mm-dd), from List a website's session recordings. |
replay_id required | path | string | The recording's ID. |
List a website's A/B tests and feature flags
/clients/{client}/analytics/sites/{site_id}/experiments
MCP tool list_analytics_experiments
Everyone
The website's experiments and flags (an add-on) and their state.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID (MS-XXXXXXXX), from List a client's websites with Analytics on. |
Create or change an A/B test or feature flag
/clients/{client}/analytics/sites/{site_id}/experiments
MCP tool save_analytics_experiment
Everyone
Creates or changes an A/B test as a draft, or stops one. Client and agency admins only. Starting a test, and changing one that is running, happens on the admin page, which republishes the website's tag.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID (MS-XXXXXXXX), from List a client's websites with Analytics on. |
name | body | string | The test's name. |
key | body | string | Its key. Defaults to one made from the name. |
variants | body | array of any | The variants and their weights. |
status | body | string | draft (default) or stopped. |
Get an A/B test's results
/clients/{client}/analytics/sites/{site_id}/experiments/{experiment_key}
MCP tool get_analytics_experiment
Everyone
Visitors, conversions and the chance of being best, per variant.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID (MS-XXXXXXXX), from List a client's websites with Analytics on. |
experiment_key required | path | string | The experiment's key. |
range | query | string | The date range: today, yesterday, this_week, last_week, last_7_days, last_14_days, last_28_days (default), last_30_days, last_90_days, this_month, last_month, this_quarter, last_quarter, this_year, last_year, last_12_months or custom (with start and end). Whole days; 'last N days' ends yesterday. |
start | query | string | With range custom: the first day, yyyy-mm-dd. |
end | query | string | With range custom: the last day, yyyy-mm-dd. |
Create or change a smart event (tracked at once)
/clients/{client}/tracked-sites/{site_id}/smart-events/{rule_id}
MCP tool save_smart_event
Global admins, Client admins
A smart event is a rule the website's Analytics tag matches with no code on the site; each match counts an event with the rule's name. The website's tag is published again, so the change is live within minutes. Rules can't watch form fields or anything a visitor types. A website has up to 30. goal true also makes the event a website goal (false removes that goal).
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | |
rule_id required | path | string | The rule's ID (lower-case letters, digits, - and _), e.g. se-quote-request. |
rule required | body | object | |
goal | body | boolean | Make it a website goal (true) or not (false). |
Delete a smart event
/clients/{client}/tracked-sites/{site_id}/smart-events/{rule_id}
MCP tool delete_smart_event
Global admins, Client admins
Stops tracking the event (its counts so far stay in the reports) and removes its goal.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | |
rule_id required | path | string | The rule's ID (lower-case letters, digits, - and _), e.g. se-quote-request. |
Approve a suggested smart event (it is tracked from now on)
/clients/{client}/tracked-sites/{site_id}/smart-events/suggestions/{suggestion_id}/approve
MCP tool approve_smart_event_suggestion
Global admins, Client admins
Turns a suggestion (from Find events, the event assistant or Website Optimizer) into a live smart event and publishes the website's tag. The name and rule may be changed first; goal overrides the suggestion's advice on making it a website goal.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | |
suggestion_id required | path | string | A suggested smart event's ID (c and 10 hex digits). |
name | body | string | |
rule | body | object | |
goal | body | boolean |
List a website's smart events and suggestions
/clients/{client}/analytics/sites/{site_id}/smart-events
MCP tool list_analytics_smart_events
Everyone
The smart events tracked now (count in the range, and a warning when one stopped matching), suggestions waiting for review, approved and dismissed ones, the latest Find events run and the client's event goals. Default range: last 30 days.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID (MS-XXXXXXXX), from List a client's websites with Analytics on. |
range | query | string | The date range: today, yesterday, this_week, last_week, last_7_days, last_14_days, last_28_days (default), last_30_days, last_90_days, this_month, last_month, this_quarter, last_quarter, this_year, last_year, last_12_months or custom (with start and end). Whole days; 'last N days' ends yesterday. |
start | query | string | With range custom: the first day, yyyy-mm-dd. |
end | query | string | With range custom: the last day, yyyy-mm-dd. |
Find smart events on a website (AI)
/clients/{client}/analytics/sites/{site_id}/smart-events/discover
MCP tool find_analytics_smart_events
Everyone
Looks at the website's pages and what is already measured, and suggests key events for the client's goals. Runs in the background for up to a minute: list the smart events again to see the run finish. Client and agency admins only; counts as one Analytics AI run.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID (MS-XXXXXXXX), from List a client's websites with Analytics on. |
goals | body | object | |
pages | body | array of string | Extra pages to look at (paths). |
Suggest a smart event (waits for approval)
/clients/{client}/analytics/sites/{site_id}/smart-events/suggestions
MCP tool suggest_analytics_smart_event
Everyone
Drafts a smart event for someone to approve; it isn't tracked until then. Client and agency admins only.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID (MS-XXXXXXXX), from List a client's websites with Analytics on. |
rule required | body | object | As in Create or change a smart event. |
why | body | string | |
goal | body | boolean |
Get one suggested smart event
/clients/{client}/analytics/sites/{site_id}/smart-events/suggestions/{suggestion_id}
MCP tool get_analytics_smart_event_suggestion
Everyone
What it tracks, where it was found, why, its estimated count and its status.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID (MS-XXXXXXXX), from List a client's websites with Analytics on. |
suggestion_id required | path | string | A suggested smart event's ID (c and 10 hex digits). |
Dismiss a suggested smart event, or bring one back
/clients/{client}/analytics/sites/{site_id}/smart-events/suggestions/{suggestion_id}
MCP tool review_analytics_smart_event_suggestion
Everyone
action dismiss or restore. Approving is Approve a suggested smart event. Client and agency admins only.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID (MS-XXXXXXXX), from List a client's websites with Analytics on. |
suggestion_id required | path | string | A suggested smart event's ID (c and 10 hex digits). |
action required | body | dismiss | restore |
Ask the smart events assistant
/clients/{client}/analytics/sites/{site_id}/smart-events/assistant
MCP tool ask_analytics_event_assistant
Everyone
One reply in a chat with the assistant, which asks about the client's goals and proposes smart events (added as suggestions for approval). Send the whole chat each time. Client and agency admins only; each reply counts as one Analytics AI run.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID (MS-XXXXXXXX), from List a client's websites with Analytics on. |
messages required | body | array of object |
See crawler and AI agent visits to a website
/clients/{client}/analytics/sites/{site_id}/crawlers
MCP tool get_analytics_crawlers
Everyone
Visits by search engine crawlers and AI agents, from imported server logs.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID (MS-XXXXXXXX), from List a client's websites with Analytics on. |
range | query | string | The date range: today, yesterday, this_week, last_week, last_7_days, last_14_days, last_28_days (default), last_30_days, last_90_days, this_month, last_month, this_quarter, last_quarter, this_year, last_year, last_12_months or custom (with start and end). Whole days; 'last N days' ends yesterday. |
start | query | string | With range custom: the first day, yyyy-mm-dd. |
end | query | string | With range custom: the last day, yyyy-mm-dd. |
Get what changed on a website
/clients/{client}/analytics/sites/{site_id}/insights
MCP tool get_analytics_insights
Everyone
Plain-language notes on what moved most in the date range and why.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID (MS-XXXXXXXX), from List a client's websites with Analytics on. |
range | query | string | The date range: today, yesterday, this_week, last_week, last_7_days, last_14_days, last_28_days (default), last_30_days, last_90_days, this_month, last_month, this_quarter, last_quarter, this_year, last_year, last_12_months or custom (with start and end). Whole days; 'last N days' ends yesterday. |
start | query | string | With range custom: the first day, yyyy-mm-dd. |
end | query | string | With range custom: the last day, yyyy-mm-dd. |
Get one visitor's timeline
/clients/{client}/analytics/sites/{site_id}/people/{visitor_id}
MCP tool get_analytics_visitor
Everyone
Everything one visitor did on the website, in order. Take the visitor ID from a segment or a recording.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID (MS-XXXXXXXX), from List a client's websites with Analytics on. |
visitor_id required | path | string | The visitor's ID. |
Get a website's visitor lifecycle
/clients/{client}/analytics/sites/{site_id}/lifecycle
MCP tool get_analytics_lifecycle
Everyone
Each week's new, returning, resurrected and dormant visitors.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID (MS-XXXXXXXX), from List a client's websites with Analytics on. |
range | query | string | The date range: today, yesterday, this_week, last_week, last_7_days, last_14_days, last_28_days (default), last_30_days, last_90_days, this_month, last_month, this_quarter, last_quarter, this_year, last_year, last_12_months or custom (with start and end). Whole days; 'last N days' ends yesterday. |
start | query | string | With range custom: the first day, yyyy-mm-dd. |
end | query | string | With range custom: the last day, yyyy-mm-dd. |
Get how often a website's visitors come back
/clients/{client}/analytics/sites/{site_id}/stickiness
MCP tool get_analytics_stickiness
Everyone
How many visitors were active on one, two, three or more days of each week.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID (MS-XXXXXXXX), from List a client's websites with Analytics on. |
range | query | string | The date range: today, yesterday, this_week, last_week, last_7_days, last_14_days, last_28_days (default), last_30_days, last_90_days, this_month, last_month, this_quarter, last_quarter, this_year, last_year, last_12_months or custom (with start and end). Whole days; 'last N days' ends yesterday. |
start | query | string | With range custom: the first day, yyyy-mm-dd. |
end | query | string | With range custom: the last day, yyyy-mm-dd. |
List a website's server keys
/clients/{client}/analytics/sites/{site_id}/server-keys
MCP tool list_analytics_server_keys
Everyone
The keys servers use to send events and logs to Analytics. Only each key's first characters are shown.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID (MS-XXXXXXXX), from List a client's websites with Analytics on. |
Create or revoke a server key
/clients/{client}/analytics/sites/{site_id}/server-keys
MCP tool change_analytics_server_keys
Everyone
Send name to make a key (its secret is returned once), or revoke with a key's first characters to revoke it.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID (MS-XXXXXXXX), from List a client's websites with Analytics on. |
name | body | string | A name for a new key. |
revoke | body | string | The first characters of the key to revoke. |
Run a funnel on a website
/clients/{client}/analytics/sites/{site_id}/funnel
MCP tool query_analytics_funnel
Everyone
How many visitors got through each step, in order. Send the steps, or the name of a saved funnel. A big question may come back still running, with a query_id for Get an Analytics query. It only reads.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID (MS-XXXXXXXX), from List a client's websites with Analytics on. |
steps | body | array of any | The steps, each a page or an event. |
funnel | body | string | Or the name of a saved funnel. |
range | body | string | The date range. |
Get a website's exit pages
/clients/{client}/analytics/sites/{site_id}/exit-pages
MCP tool get_analytics_exit_pages
Everyone
The pages visitors most often left from. A big question may come back still running, with a query_id.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID (MS-XXXXXXXX), from List a client's websites with Analytics on. |
range | query | string | The date range: today, yesterday, this_week, last_week, last_7_days, last_14_days, last_28_days (default), last_30_days, last_90_days, this_month, last_month, this_quarter, last_quarter, this_year, last_year, last_12_months or custom (with start and end). Whole days; 'last N days' ends yesterday. |
start | query | string | With range custom: the first day, yyyy-mm-dd. |
end | query | string | With range custom: the last day, yyyy-mm-dd. |
Get an Analytics query that was still running
/clients/{client}/analytics/sites/{site_id}/queries/{query_id}
MCP tool get_analytics_query
Everyone
The result of a funnel or exit-pages question that was not ready at first.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID (MS-XXXXXXXX), from List a client's websites with Analytics on. |
query_id required | path | string | The query's ID, from the answer that was still running. |
Get GA4's numbers for a website
/clients/{client}/analytics/sites/{site_id}/ga4
MCP tool get_analytics_ga4
Everyone
What GA4 measured for the same website and dates (from a nightly copy), where GA4 is linked.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID (MS-XXXXXXXX), from List a client's websites with Analytics on. |
range | query | string | The date range: today, yesterday, this_week, last_week, last_7_days, last_14_days, last_28_days (default), last_30_days, last_90_days, this_month, last_month, this_quarter, last_quarter, this_year, last_year, last_12_months or custom (with start and end). Whole days; 'last N days' ends yesterday. |
start | query | string | With range custom: the first day, yyyy-mm-dd. |
end | query | string | With range custom: the last day, yyyy-mm-dd. |
compare | query | none | previous | year | custom | Compare with another period: none (default; the overview defaults to previous), previous (the period just before, of the same length; this_month/quarter/year compare the same days of the one before, last_month/quarter/year the whole one before), year (the same dates a year earlier) or custom (with compare_start and compare_end). The answer then adds compare_period, previous and change (percent) on its totals and on each row. |
compare_start | query | string | With compare custom: the first compared day, yyyy-mm-dd. |
compare_end | query | string | With compare custom: the last compared day, yyyy-mm-dd. |
match_weekday | query | 0 | 1 | 1 to line compared days up by day of the week (previous: whole weeks back; year: 52 weeks back). |
Get GA4's audience breakdowns for a website
/clients/{client}/analytics/sites/{site_id}/audience
MCP tool get_analytics_audience
Everyone
New against returning visitors, age, interests and other breakdowns only GA4 has, where GA4 is linked.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID (MS-XXXXXXXX), from List a client's websites with Analytics on. |
range | query | string | The date range: today, yesterday, this_week, last_week, last_7_days, last_14_days, last_28_days (default), last_30_days, last_90_days, this_month, last_month, this_quarter, last_quarter, this_year, last_year, last_12_months or custom (with start and end). Whole days; 'last N days' ends yesterday. |
start | query | string | With range custom: the first day, yyyy-mm-dd. |
end | query | string | With range custom: the last day, yyyy-mm-dd. |
Compare a website's numbers with GA4's
/clients/{client}/analytics/sites/{site_id}/data-check
MCP tool get_analytics_data_check
Everyone
Our numbers and GA4's day by day, and anything that looks wrong, such as a tag missing from part of the site.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID (MS-XXXXXXXX), from List a client's websites with Analytics on. |
range | query | string | The date range: today, yesterday, this_week, last_week, last_7_days, last_14_days, last_28_days (default), last_30_days, last_90_days, this_month, last_month, this_quarter, last_quarter, this_year, last_year, last_12_months or custom (with start and end). Whole days; 'last N days' ends yesterday. |
start | query | string | With range custom: the first day, yyyy-mm-dd. |
end | query | string | With range custom: the last day, yyyy-mm-dd. |
Get a connected source's panel for a website
/clients/{client}/analytics/sites/{site_id}/sources/{source_name}
MCP tool get_analytics_source_panel
Everyone
The panel for one of the website's linked data sources (for example gsc, ads or shopify), read with your own access to it.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID (MS-XXXXXXXX), from List a client's websites with Analytics on. |
source_name required | path | string | The linked source, for example gsc, ads or shopify. |
range | query | string | The date range: today, yesterday, this_week, last_week, last_7_days, last_14_days, last_28_days (default), last_30_days, last_90_days, this_month, last_month, this_quarter, last_quarter, this_year, last_year, last_12_months or custom (with start and end). Whole days; 'last N days' ends yesterday. |
start | query | string | With range custom: the first day, yyyy-mm-dd. |
end | query | string | With range custom: the last day, yyyy-mm-dd. |
Get a standard Analytics report
/clients/{client}/analytics/sites/{site_id}/reports/{report_name}
MCP tool get_analytics_report
Everyone
One of the standard reports: overview, channels, seo, ecommerce, ad_lift or attribution.
ad_lift (Ad-driven lift): the direct visits, organic-search visits and branded searches the client's ads brought, by ad channel (Google Ads YouTube, Display/Demand Gen/PMax, Search; Meta; MNTN TV) and by campaign (by_channel, by_campaign: extra visits, share, cost per extra visit, confidence), with outcomes, flights, hourly (TV) and, for websites that run Attribution, came_back_after_click. Ad accounts and search sources are read with your own access (a person's token). Optional query parameters: outcomes (comma-separated: direct, organic_search, brand_searches_google, brand_searches_google_ads, brand_searches_microsoft), brand_terms, exclude_terms, ads_customer_id, meta_ad_account_id, mntn_advertiser_id, ms_ads_account_id, site_url, include_hourly, baseline_days, after_days; they override the website's saved ad_lift Analytics settings for this request. When the answer has retry, Microsoft is still building its report: call again in about 20 seconds with ms_ads_report_id from it. A correlation, not proof.
attribution (websites that run Attribution): visits, unique people, devices, browsers and households, visitors recognised after clearing cookies, form submits by channel, source and page, and direct or organic visits after an ad click, with compare.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID (MS-XXXXXXXX), from List a client's websites with Analytics on. |
report_name required | path | string | overview, channels, seo, ecommerce, ad_lift or attribution. |
range | query | string | The date range: today, yesterday, this_week, last_week, last_7_days, last_14_days, last_28_days (default), last_30_days, last_90_days, this_month, last_month, this_quarter, last_quarter, this_year, last_year, last_12_months or custom (with start and end). Whole days; 'last N days' ends yesterday. |
start | query | string | With range custom: the first day, yyyy-mm-dd. |
end | query | string | With range custom: the last day, yyyy-mm-dd. |
compare | query | none | previous | year | custom | Compare with another period: none (default; the overview defaults to previous), previous (the period just before, of the same length; this_month/quarter/year compare the same days of the one before, last_month/quarter/year the whole one before), year (the same dates a year earlier) or custom (with compare_start and compare_end). The answer then adds compare_period, previous and change (percent) on its totals and on each row. |
compare_start | query | string | With compare custom: the first compared day, yyyy-mm-dd. |
compare_end | query | string | With compare custom: the last compared day, yyyy-mm-dd. |
match_weekday | query | 0 | 1 | 1 to line compared days up by day of the week (previous: whole weeks back; year: 52 weeks back). |
data | query | string | Whose numbers: ours, ga4 or blended (the last two need GA4 linked). Without it: your saved choice (Get your Analytics preferences), else blended when GA4 is linked to the website, else ours. The answer's |
Offline Conversions
Offline Conversions for a client with it on: rules that decide which orders, leads, calls and won deals are sent to Google Ads, Meta, Microsoft Ads and Google Analytics 4, previews, test sends, the send log, the do-not-send list and the conversions assistant. Everything the Offline Conversions screen does, run as you; the service checks your role in the client on every call (changes need a client or agency admin).
Get a client's offline conversions overview
/clients/{client}/conversions/overview
MCP tool get_conversions_overview
Everyone
Conversions sent, skipped and failed per day and per platform, the value sent, how many were sent of those tried, and anything that needs attention.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
days | query | integer | Days back (1-90, default 30). |
Get what conversion rules can use
/clients/{client}/conversions/catalog
MCP tool get_conversions_catalog
Everyone
Event types, fields and operators for conditions, value modes, platforms (with their test modes), and the client's ad connections and data sources.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string |
List a client's conversion rules
/clients/{client}/conversions/rules
MCP tool list_conversion_rules
Everyone
Rules (draft, on, paused) with their last 7 days' counts, and the Attribution mappings still being sent (read-only rules whose IDs start with m-).
| Field | In | Type | About |
|---|---|---|---|
client required | path | string |
Create a conversion rule
/clients/{client}/conversions/rules
MCP tool create_conversion_rule
Everyone
Admins only. Saves a draft: nothing is sent until the rule is turned on. Send rule: {name, description?, trigger: {events, sources?}, conditions?: {match: all|any, items: [{field, op, value}]}, value?: {mode, amount, min, max, currency}, hold_hours?, limits?: {daily_sends, daily_value}, destinations: [{platform, connection, account_id, action}]}. Get conversions catalog lists the choices.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
rule | body | object | The rule. |
Get a conversion rule
/clients/{client}/conversions/rules/{rule_id}
MCP tool get_conversion_rule
Everyone
One rule, its versions and today's use of its daily limits.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
rule_id required | path | string | A conversion rule's ID (or a mapping's, starting with m-), from List a client's conversion rules. |
Change a conversion rule
/clients/{client}/conversions/rules/{rule_id}
MCP tool update_conversion_rule
Everyone
Admins only. Send the whole rule and the version you read, so two people editing at once don't overwrite each other. An active rule stays on.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
rule_id required | path | string | A conversion rule's ID (or a mapping's, starting with m-), from List a client's conversion rules. |
rule | body | object | The rule. |
version | body | integer | The version you read. |
Delete a conversion rule
/clients/{client}/conversions/rules/{rule_id}
MCP tool delete_conversion_rule
Everyone
Admins only. What it already sent stays in the send log.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
rule_id required | path | string | A conversion rule's ID (or a mapping's, starting with m-), from List a client's conversion rules. |
Turn a conversion rule on or pause it
/clients/{client}/conversions/rules/{rule_id}/status
MCP tool set_conversion_rule_status
Everyone
Admins only. status: active (turns it on: matching events are sent from now on; check its preview first), paused or draft. Turning a rule on works only from the admin page or this API, never from AI apps.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
rule_id required | path | string | A conversion rule's ID (or a mapping's, starting with m-), from List a client's conversion rules. |
status | body | string | active, paused or draft. |
Preview a conversion rule
/clients/{client}/conversions/rules/{rule_id}/preview
MCP tool preview_conversion_rule
Everyone
Dry run, nothing is sent: what the rule would send over the last days per destination, the value, what it would match on, why other events don't match, and samples with shortened hashes.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
rule_id required | path | string | A conversion rule's ID (or a mapping's, starting with m-), from List a client's conversion rules. |
days | query | integer | Days back (1-90, default 30). |
Preview a draft conversion rule
/clients/{client}/conversions/preview
MCP tool preview_conversion_rule_draft
Everyone
Dry run of a rule that isn't saved (rule, days). Nothing is sent or saved.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
rule | body | object | The rule. |
days | body | integer | Days back (1-90). |
Send a test conversion
/clients/{client}/conversions/rules/{rule_id}/test
MCP tool test_conversion_rule
Everyone
Admins only. Sends the newest matching event of the last 30 days in each platform's test mode (Google checks it without recording, Meta shows it under Test events with the saved test code; Microsoft has no test mode). Not billed.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
rule_id required | path | string | A conversion rule's ID (or a mapping's, starting with m-), from List a client's conversion rules. |
Convert an Attribution mapping to a rule
/clients/{client}/conversions/mappings/{rule_id}/convert
MCP tool convert_conversion_mapping
Everyone
Admins only. The mapping (ID starting with m-) becomes an active rule and keeps sending; nothing it sent is sent again.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
rule_id required | path | string | A conversion rule's ID (or a mapping's, starting with m-), from List a client's conversion rules. |
List sent conversions
/clients/{client}/conversions/log
MCP tool list_conversion_sends
Everyone
The send log, newest first: sent, skipped (and why), failed, held (waiting for the rule's hold time) and test sends. No contact details.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
status | query | string | sent, skipped, failed, held or test. |
rule_id | query | string | Only this rule. |
platform | query | string | Only this platform. |
limit | query | integer | At most this many (1-500, default 100). |
cursor | query | string | next_cursor from the previous page. |
Send a failed conversion again
/clients/{client}/conversions/log/{log_id}/send-again
MCP tool send_conversion_again
Everyone
Admins only. Retries one failed send from the log.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
log_id required | path | string | A send's ID from List sent conversions. |
Send past events
/clients/{client}/conversions/backfill
MCP tool backfill_conversions
Everyone
Admins only. Runs the rules that are on (or one rule_id) over stored events of the last days (1-90). Events already sent are never sent again. Runs in the background.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
days | body | integer | Days back (1-90). |
rule_id | body | string | Only this rule. |
List changes to offline conversions
/clients/{client}/conversions/audit
MCP tool list_conversions_changes
Everyone
Who changed which rule or setting, how (admin page, Admin API, AI app) and when, with before and after.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string |
Get offline conversions settings
/clients/{client}/conversions/settings
MCP tool get_conversions_settings
Everyone
Whether sending is paused for the client, whether only visitors who said yes to ads are sent, and whether a Meta test code is saved.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string |
Change offline conversions settings
/clients/{client}/conversions/settings
MCP tool update_conversions_settings
Everyone
Admins only. Send only what changes: paused, require_consent, test_event_code.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
paused | body | boolean | Pause all sending. |
require_consent | body | boolean | Only send visitors who said yes to ads. |
test_event_code | body | string | Meta Events Manager test code. |
Get which GA4 streams have an API secret
/clients/{client}/conversions/destination-secrets
MCP tool get_conversions_destination_secrets
Everyone
Per GA4 measurement ID used by a rule: whether its Measurement Protocol API secret is saved. Secrets are never shown.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string |
Save a GA4 Measurement Protocol API secret
/clients/{client}/conversions/destination-secrets/ga4
MCP tool set_conversions_ga4_secret
Everyone
Admins only. measurement_id (G-...) and api_secret (empty removes it). Sealed and never shown again.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
measurement_id | body | string | The web stream's measurement ID. |
api_secret | body | string | The API secret. |
List the do-not-send list
/clients/{client}/conversions/suppressions
MCP tool list_conversions_suppressions
Everyone
People who must never be sent to ad platforms (privacy requests, opt-outs). Only SHA-256 hashes are kept.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string |
Add people to the do-not-send list
/clients/{client}/conversions/suppressions
MCP tool add_conversions_suppressions
Everyone
Admins only. emails and phones are hashed before anything is stored; or send hashes (SHA-256 hex). reason: privacy_request, opt_out or other.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
emails | body | array of string | Email addresses. |
phones | body | array of string | Phone numbers. |
hashes | body | array of string | SHA-256 hashes. |
reason | body | string | privacy_request, opt_out or other. |
Remove someone from the do-not-send list
/clients/{client}/conversions/suppressions/{hash}
MCP tool remove_conversions_suppression
Everyone
Admins only. Removes one hash.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
hash required | path | string | A do-not-send entry's SHA-256 hash. |
Ask the conversions assistant
/clients/{client}/conversions/assistant
MCP tool suggest_conversion_rules
Everyone
Admins only. Describe a goal; the assistant studies the client's events, previews ideas and saves draft rules (never turned on) with its reasoning. Needs AI Services on; tokens are billed there.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
goal | body | string | The goal in plain words. |
save_drafts | body | boolean | Save the drafts (default true). |
Get a client's offline conversions summary
/clients/{client}/conversions/summary
MCP tool get_conversions_summary
Everyone
The last 7 days' totals, rules on and attention items (the Home tile).
| Field | In | Type | About |
|---|---|---|---|
client required | path | string |
Website Optimizer
Website Optimizer for a client with it on: the websites it checks each day, their recommendations with one-click fixes and A/B tests, scores, reports and alerts. Everything the Website Optimizer screen does, run as you; the service checks your role in the client on every call (changes need a client or agency admin).
Get Website Optimizer's totals across an agency's clients
/agencies/{agency_id}/optimizer-summary
MCP tool get_agency_optimizer_summary
Global admins, Agency admins
For every client of the agency that you can see and that has Website Optimizer on: its websites, open and new recommendations and alerts this week. The agency view of the Website Optimizer screen.
| Field | In | Type | About |
|---|---|---|---|
agency_id required | path | string |
See what you may do in a client's Website Optimizer
/clients/{client}/optimizer/access
MCP tool get_optimizer_access
Everyone
Your role in the client as Website Optimizer sees it, and whether you may change things.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string |
Get a client's Website Optimizer totals
/clients/{client}/optimizer/summary
MCP tool get_optimizer_summary
Everyone
Websites, open and new recommendations, alerts this week and the top recommendation: the numbers on the client's Home page.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string |
List the people who can get Website Optimizer emails
/clients/{client}/optimizer/people
MCP tool list_optimizer_people
Everyone
The client's people, for the weekly digest and alert lists.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string |
List a client's websites in Website Optimizer
/clients/{client}/optimizer/sites
MCP tool list_optimizer_sites
Everyone
The websites being checked, and under addable the client's tracked websites that could be added.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
limit | query | integer | Most items to return (default 100, max 500). |
cursor | query | string | Where to continue: the |
Add a website to Website Optimizer
/clients/{client}/optimizer/sites
MCP tool add_optimizer_site
Everyone
Admins only. Send site_id for one of the client's tracked websites, or url for any address. You become the person its daily checks run as. The first check starts at once.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id | body | string | A tracked website's ID. |
url | body | string | Or any website address. |
name | body | string | A name to show. |
Get a website in Website Optimizer
/clients/{client}/optimizer/sites/{site_id}
MCP tool get_optimizer_site
Everyone
Its goals, the pages checked, its scores and when it was last checked.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID in Website Optimizer, from List a client's websites in Website Optimizer. |
Change a website in Website Optimizer
/clients/{client}/optimizer/sites/{site_id}
MCP tool update_optimizer_site
Everyone
Admins only. Send only what changes: goals, name, pages, auto_pages, status, digest_email, alerts. Send the version you read so two people editing at once don't overwrite each other.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID in Website Optimizer, from List a client's websites in Website Optimizer. |
goals | body | object | What the website is for: primary, secondary, conversion_pages, markets, audience, priorities, business_type, notes. |
name | body | string | A name to show. |
pages | body | array of any | The pages to check. |
auto_pages | body | boolean | Pick the pages to check automatically. |
status | body | string | active or paused. |
digest_email | body | object | Who gets the weekly digest. |
alerts | body | object | Who is told about urgent problems, and how. |
version | body | integer | The version you read. |
Remove a website from Website Optimizer
/clients/{client}/optimizer/sites/{site_id}
MCP tool remove_optimizer_site
Everyone
Admins only. Removes the website with its recommendations, scores and fixes.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID in Website Optimizer, from List a client's websites in Website Optimizer. |
Make yourself the person a website's checks run as
/clients/{client}/optimizer/sites/{site_id}/take-over
MCP tool take_over_optimizer_site
Everyone
Admins only. The daily check reads the client's data with one person's access; this makes that person you.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID in Website Optimizer, from List a client's websites in Website Optimizer. |
Get a website's alert webhook signing secret
/clients/{client}/optimizer/sites/{site_id}/webhook-secret
MCP tool get_optimizer_webhook_secret
Everyone
Admins only. The secret that signs the alerts Website Optimizer posts to your webhook.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID in Website Optimizer, from List a client's websites in Website Optimizer. |
Check a website now
/clients/{client}/optimizer/sites/{site_id}/check
MCP tool check_optimizer_site
Everyone
Admins only. Starts a check; results arrive in a few minutes. At most once an hour.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID in Website Optimizer, from List a client's websites in Website Optimizer. |
List a website's recommendations
/clients/{client}/optimizer/sites/{site_id}/recommendations
MCP tool list_optimizer_recommendations
Everyone
What to fix, most valuable first, each with why it matters, the pages it is on and the steps to fix it.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID in Website Optimizer, from List a client's websites in Website Optimizer. |
status | query | string | open (default), all, or one status such as done or dismissed. |
category | query | string | Only one category, for example seo or speed. |
limit | query | integer | How many to return (default 50). |
Change a recommendation's status
/clients/{client}/optimizer/sites/{site_id}/recommendations/{recommendation_id}
MCP tool update_optimizer_recommendation
Everyone
Admins only. Mark a recommendation done, dismissed or open again, with a reason.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID in Website Optimizer, from List a client's websites in Website Optimizer. |
recommendation_id required | path | string | The recommendation's ID. |
status | body | string | The new status. |
reason | body | string | Why, in a few words. |
Preview a one-click fix
/clients/{client}/optimizer/sites/{site_id}/recommendations/{recommendation_id}/fix
MCP tool preview_optimizer_fix
Everyone
Admins only. What a one-click fix would change on each page, before applying it. Only some recommendations can be fixed this way (can_fix).
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID in Website Optimizer, from List a client's websites in Website Optimizer. |
recommendation_id required | path | string | The recommendation's ID. |
Apply a one-click fix
/clients/{client}/optimizer/sites/{site_id}/recommendations/{recommendation_id}/fix
MCP tool apply_optimizer_fix
Everyone
Admins only. Applies the fix to the pages you send, through the website's connected platform. It can be undone.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID in Website Optimizer, from List a client's websites in Website Optimizer. |
recommendation_id required | path | string | The recommendation's ID. |
pages | body | array of any | The pages to fix, each {url, values}, from the preview. |
Draft an A/B test for a recommendation
/clients/{client}/optimizer/sites/{site_id}/recommendations/{recommendation_id}/test
MCP tool draft_optimizer_test
Everyone
Admins only. A ready-made A/B test that would prove whether the recommendation helps, to review before saving.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID in Website Optimizer, from List a client's websites in Website Optimizer. |
recommendation_id required | path | string | The recommendation's ID. |
goal_event | query | string | The event the test is judged by. |
Save a recommendation's A/B test in Analytics
/clients/{client}/optimizer/sites/{site_id}/recommendations/{recommendation_id}/test
MCP tool save_optimizer_test
Everyone
Admins only. Saves the test as a draft in Analytics (the A/B tests add-on); start it on the admin page.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID in Website Optimizer, from List a client's websites in Website Optimizer. |
recommendation_id required | path | string | The recommendation's ID. |
experiment | body | object | The test, as drafted. |
List the fixes applied to a website
/clients/{client}/optimizer/sites/{site_id}/fixes
MCP tool list_optimizer_fixes
Everyone
One-click fixes that were applied, newest first, and whether each was undone.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID in Website Optimizer, from List a client's websites in Website Optimizer. |
Undo a fix
/clients/{client}/optimizer/sites/{site_id}/fixes/{fix_id}/undo
MCP tool undo_optimizer_fix
Everyone
Admins only. Puts the pages back as they were before the fix.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID in Website Optimizer, from List a client's websites in Website Optimizer. |
fix_id required | path | string | The fix's ID, from List the fixes applied to a website. |
Get a website's one-page report
/clients/{client}/optimizer/sites/{site_id}/report
MCP tool get_optimizer_report
Everyone
Scores, what changed, the top recommendations and what was fixed, as data.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID in Website Optimizer, from List a client's websites in Website Optimizer. |
Make a website's report as a PDF
/clients/{client}/optimizer/sites/{site_id}/report/pdf
MCP tool create_optimizer_report_pdf
Everyone
Returns a download link (url) that works for five minutes, with a file name.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID in Website Optimizer, from List a client's websites in Website Optimizer. |
Get a website's score history
/clients/{client}/optimizer/sites/{site_id}/scores
MCP tool get_optimizer_scores
Everyone
Its scores day by day, for the whole site or one page.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID in Website Optimizer, from List a client's websites in Website Optimizer. |
page | query | string | One page; leave out for the site. |
days | query | integer | How many days back. |
Get the newest audit of a page
/clients/{client}/optimizer/sites/{site_id}/audit
MCP tool get_optimizer_audit
Everyone
Everything the last check found on one page.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID in Website Optimizer, from List a client's websites in Website Optimizer. |
page | query | string | The page's address. |
List a website's alerts
/clients/{client}/optimizer/sites/{site_id}/alerts
MCP tool list_optimizer_alerts
Everyone
Urgent problems Website Optimizer noticed, newest first.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
site_id required | path | string | The website's ID in Website Optimizer, from List a client's websites in Website Optimizer. |
days | query | integer | How many days back. |
limit | query | integer | Most items to return (default 100, max 500). |
cursor | query | string | Where to continue: the |
Dashboards
Live dashboards for a client with Dashboards on: list, build and edit them, read their tiles' data, share them with people or by public link, send them by daily email and export them. Everything the Dashboards screen does, run as you; the Dashboards service checks your role in the client on every call.
List a client's dashboards
/clients/{client}/dashboards
MCP tool list_dashboards
Everyone
The dashboards you can see: your own, the ones shared with you and, for admins, all of them. Each says whether it is yours and how it was made.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
made_by_ai | query | string | Send 1 for only the dashboards the AI assistant made. |
chat_id | query | string | Only the dashboards made in this AI chat. |
limit | query | integer | Most items to return (default 100, max 500). |
cursor | query | string | Where to continue: the |
Create a dashboard
/clients/{client}/dashboards
MCP tool create_dashboard
Everyone
Makes a dashboard from a spec: its name, date range, refresh interval and tiles. It is private to you until you share it. Use List dashboard data tools for what a tile can show, and Preview a dashboard tile to try one first.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
spec | body | object | The dashboard: name, description, date_range, refresh_minutes, timezone and tiles. |
Get a dashboard
/clients/{client}/dashboards/{dashboard_id}
MCP tool get_dashboard
Everyone
One dashboard: its spec, sharing, daily email settings and what you may do with it.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
dashboard_id required | path | string | The dashboard's ID, from List dashboards. |
Save a dashboard
/clients/{client}/dashboards/{dashboard_id}
MCP tool save_dashboard
Everyone
Replaces the dashboard's spec. Send the version you read, so two people editing at once don't overwrite each other: a stale version is refused.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
dashboard_id required | path | string | The dashboard's ID, from List dashboards. |
spec | body | object | The whole dashboard spec. |
version | body | integer | The version you read. Leave out to save regardless. |
Delete a dashboard
/clients/{client}/dashboards/{dashboard_id}
MCP tool delete_dashboard
Everyone
Deletes the dashboard, its public link and its daily email. Only its owner or an admin of the client can.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
dashboard_id required | path | string | The dashboard's ID, from List dashboards. |
Get a dashboard's data
/clients/{client}/dashboards/{dashboard_id}/data
MCP tool get_dashboard_data
Everyone
The numbers for every tile, read with your own access to the client's connections. Kept for the dashboard's refresh interval; refresh=1 reads fresh (and counts as usage). The date parameters show other dates for this answer only (the dashboard keeps its own); compare=none leaves comparisons out.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
dashboard_id required | path | string | The dashboard's ID, from List dashboards. |
range | query | string | The date range: today, yesterday, this_week, last_week, last_7_days, last_14_days, last_28_days (default), last_30_days, last_90_days, this_month, last_month, this_quarter, last_quarter, this_year, last_year, last_12_months or custom (with start and end). Whole days; 'last N days' ends yesterday. |
start | query | string | With range custom: the first day, yyyy-mm-dd. |
end | query | string | With range custom: the last day, yyyy-mm-dd. |
compare | query | none | previous | year | custom | Compare with another period: none (default; the overview defaults to previous), previous (the period just before, of the same length; this_month/quarter/year compare the same days of the one before, last_month/quarter/year the whole one before), year (the same dates a year earlier) or custom (with compare_start and compare_end). The answer then adds compare_period, previous and change (percent) on its totals and on each row. |
compare_start | query | string | With compare custom: the first compared day, yyyy-mm-dd. |
compare_end | query | string | With compare custom: the last compared day, yyyy-mm-dd. |
match_weekday | query | 0 | 1 | 1 to line compared days up by day of the week (previous: whole weeks back; year: 52 weeks back). |
refresh | query | string | Send 1 to read fresh data now. |
Make a public link to a dashboard
/clients/{client}/dashboards/{dashboard_id}/public-link
MCP tool create_dashboard_public_link
Everyone
Admins only. Returns a link anyone can open without signing in, for days days. Making a new one replaces the old one.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
dashboard_id required | path | string | The dashboard's ID, from List dashboards. |
days | body | integer | How long the link works. |
Turn a dashboard's public link off
/clients/{client}/dashboards/{dashboard_id}/public-link
MCP tool remove_dashboard_public_link
Everyone
The link stops working at once.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
dashboard_id required | path | string | The dashboard's ID, from List dashboards. |
Set a dashboard's daily email
/clients/{client}/dashboards/{dashboard_id}/email
MCP tool set_dashboard_email
Everyone
Who gets the dashboard by email each day, and when. Send the settings object the dashboard shows under email; an empty list of people turns it off.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
dashboard_id required | path | string | The dashboard's ID, from List dashboards. |
enabled | body | boolean | Whether the daily email is on. |
people | body | array of any | Usernames who get it. |
hour | body | integer | Hour of the day to send, in the time zone of the dashboard. |
Send a dashboard's email to yourself now
/clients/{client}/dashboards/{dashboard_id}/email/test
MCP tool send_dashboard_email_test
Everyone
Sends the dashboard's email to your own address, so you can see it before turning the daily email on.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
dashboard_id required | path | string | The dashboard's ID, from List dashboards. |
Export a dashboard
/clients/{client}/dashboards/{dashboard_id}/export
MCP tool export_dashboard
Everyone
Makes a PDF, Excel or PNG copy and returns a download link (url) that works for five minutes, with a file name.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
dashboard_id required | path | string | The dashboard's ID, from List dashboards. |
format | body | string | pdf (default), xlsx or png. |
List the data tools dashboard tiles can use
/clients/{client}/dashboard-sources
MCP tool list_dashboard_sources
Everyone
The client's connected data, as the tools a tile can read from, with the arguments each takes.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string |
Preview a dashboard tile
/clients/{client}/dashboard-preview
MCP tool preview_dashboard_tile
Everyone
Reads one tile's data without saving anything, to try a tile before adding it.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
tile | body | object | The tile, as it would go in a dashboard spec. |
date_range | body | string | For example last_28_days. |
timezone | body | string | An IANA time zone name. |
List the people a dashboard can be shared with
/clients/{client}/dashboard-people
MCP tool list_dashboard_people
Everyone
The client's people, for sharing and the daily email.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string |
See what you may do with a client's dashboards
/clients/{client}/dashboard-access
MCP tool get_dashboard_access
Everyone
Your role in the client as Dashboards sees it, and whether you may edit, share publicly and email.
| Field | In | Type | About |
|---|---|---|---|
client required | path | string |
Network Monitoring
Network Monitoring (NMS) for a client with it on - locations and their collectors, devices, cloud monitors of websites and data sources, alarms, outages, notification rules and maintenance windows. Every operation the Network page offers; the NMS service checks your role in the client on every call (setup changes need a client or agency admin).
Read Network Monitoring data
/clients/{client}/nms/{op}
MCP tool nms_query
Everyone
Runs one read-only Network Monitoring operation, with its arguments as query parameters (all optional unless noted): status (location_id, group_id), list_groups (device groups, which can hold devices from any location, with members per location), list_locations, list_collectors, list_devices (location_id, group_id, status), get_device (node_id, required), list_found (discovered devices waiting), list_monitors, shared_status (the shared API endpoints of the client's data sources, checked once for all clients), list_alarms (location_id, group_id, min_severity, all, limit), list_events (day yyyy-mm-dd, limit), list_outages (since, until unix seconds; target or group_id), metric_series (target and metric required; start, end), list_maintenance, get_settings, list_snmp_profiles and list_rules (admins; secrets are never shown), get_contact (your own alert email and mobile number), topology (network overview: the network gear, its links from LLDP/CDP and a connection list; location_id), site_map (every device on its switch port; location_id), connected_devices (every MAC seen with IP, VLAN, switch and port; unmonitored, location_id), list_unifi, config_platforms, config_versions / config_text / config_diff (admins; node_id, at, a, b), flows_top (top talkers, apps, sources, destinations from NetFlow/IPFIX/sFlow; target, start, end, limit), availability_report (month yyyy-mm; location_id, group_id), alarm_context (alarm_id; everything around an alarm, for root cause), list_event_rules, list_thresholds, list_credentials (admins; secrets never shown).
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
op required | path | status | topology | site_map | connected_devices | list_unifi | config_platforms | config_versions | config_text | config_diff | flows_top | availability_report | alarm_context | list_event_rules | list_thresholds | list_credentials | list_groups | list_locations | list_collectors | list_devices | get_device | list_found | list_monitors | shared_status | list_alarms | list_events | list_outages | metric_series | list_maintenance | get_settings | list_snmp_profiles | list_rules | get_contact |
Change Network Monitoring setup or alarms
/clients/{client}/nms/{op}
MCP tool nms_change
Everyone
Runs one Network Monitoring change; the body is the operation's arguments, the same JSON the Network page sends. Admins: save_location (location_id to change one; name, networks [CIDRs], discovery {ranges, exclude, every_hours, auto_add rules, snmp_profiles}), delete_location, collector_setup_code (location_id; a one-time code for a new collector), remove_collector (collector_id), save_device (node_id to change one; ip, label, location_id, snmp_profile, checks, tags; probe: auto - public addresses from our cloud probes, private ones from the location's collector - or collector or cloud), delete_device, save_monitor / delete_monitor (cloud checks of public URLs and hosts), save_group / delete_group (group_id to change one; name, description, devices [node_ids], match {vendor, type, tags, location_ids, network, name_contains} to add devices automatically), save_snmp_profile / delete_snmp_profile, save_rule / delete_rule (notification rules: match, delay_minutes, steps of email, sms, slack, teams, pagerduty or webhook channels; match.group_ids aims a rule at device groups), save_event_rule / delete_event_rule (trap and syslog rules: match {kind, trap_oid, text_contains, program, max_syslog_severity, location_ids, group_ids}, action alarm/event/ignore, severity, clears {...}), save_threshold / delete_threshold (metric, op > or <, value, rearm, samples, severity, scope), save_credential / delete_credential (kind ssh, winrm or unifi; username, password, private_key, api_key, url), save_unifi / delete_unifi (mode local or cloud, credential, location_id, sites), save_maintenance / delete_maintenance (scope.group_ids covers device groups), save_settings (auto_websites, auto_sources, retention_days). Anyone in the client: acknowledge_alarm (alarm_id, ack), clear_alarm (alarm_id), save_contact (email, mobile in +country format, email_on, sms_on).
| Field | In | Type | About |
|---|---|---|---|
client required | path | string | |
op required | path | acknowledge_alarm | clear_alarm | save_location | delete_location | collector_setup_code | remove_collector | save_device | delete_device | save_monitor | delete_monitor | save_group | delete_group | save_event_rule | delete_event_rule | save_threshold | delete_threshold | save_credential | delete_credential | save_unifi | delete_unifi | save_snmp_profile | delete_snmp_profile | save_rule | delete_rule | save_maintenance | delete_maintenance | save_settings | save_contact |
About
What this environment offers.
Describe this environment
/meta
MCP tool get_meta
Everyone
Your role, the services you can connect (with their settings and tools), and whether Google, Shopify, Facebook, Microsoft, Salesforce, HubSpot, Gorgias and Klaviyo connect are set up.
Metric Sensei Admin API 1.0.0. The OpenAPI spec is the full contract, including response shapes.