NEWAI content checker: see which pages read like AI text

SEO APIWhite label & accountSites API

Sites API for your own dashboard and client onboarding.

Add, update and remove client sites from your own backend, and set the competitors each site follows. The first SEO crawl starts the moment you add a domain, and we keep the measurements running in the background. Every plan includes the API and the MCP at no extra cost, with 600 calls per minute on a white label key and 60 on a personal key.

Add client sites

Create a site with its Google locale and your own tag, and start the first crawl right away.

Shared competitor list

One list of up to six domains feeds the Rank tracker, Core Web Vitals and AI Insights.

SERP rival suggestions

See which domains ranked above the site most often in its latest Rank tracker checks.

Google connection status

Check on every site whether Search Console and Google Analytics 4 are connected.

Manage client sites and their competitors from your code

Every endpoint in the MarketingTracer API takes a site_id. The sites and competitors endpoints let your own backend create that site and manage its settings and competitors.

Endpoint MCP tool Role needed What it returns
sites.list list_sites guest or higher The sites you can open, starred first and then by domain. Supports q search and cursor pagination (limit up to 500, cursor).
sites.get get_site guest or higher One site's details: locale and tag, your role, active with expires_at, plus search_console_connected and analytics_connected.
sites.add API only Account / white label Adds a site and makes you its owner. Sets recommended alerts and starts the first crawl right away, returning the new site object.
sites.update API only owner or higher Updates a site's locale (country, language) or tag; only the fields you send change. Returns the updated site.
sites.remove API only owner or higher Deletes the site and all stored data permanently when confirm_domain matches the site's domain. Returns removed: true.
competitors.list get_competitors_list guest or higher The site's followed domains (competitors, max: 6) plus suggestions with domain and keywords_above from the latest Rank tracker checks.
competitors.save API only user or higher Replaces the competitor list with up to 6 domains (strips www and paths; ignores duplicates and the site itself). An empty list clears all competitors.
competitors.add API only user or higher Adds one domain at the end of the competitor list, or returns 409 list_full when 6 domains are already followed.
competitors.remove API only user or higher Removes one domain from the competitor list and returns the remaining domains.

Who sees which sites and how sites.add works

When you call sites.list, a white label owner or admin (superadmin or white_label_admin) gets every site of that white label. Anyone else gets the sites they were added to; on a white label domain, that list only shows sites of that white label. Starred sites (favorite: true) come first, and the rest follow alphabetically by domain.

Calling sites.add only requires domain, either as a host like www.example.co.uk or a homepage URL (we store the lowercase host). You can also pass a two-letter country code (gb is stored as uk) and a language code such as nl or en (or a regional code like pt-BR), which sets the app language for that site when available. An optional tag of up to 60 characters holds your own client ID or label. Any locale field you omit falls back to the white label's default. On a white label domain, the new site gets status: "white_label" and is billed to the white label. Its expiry date renews every day while the white label is paid.

A domain that does not resolve is refused with 400 invalid_domain. If the domain is already a site in MarketingTracer, only white label staff or a paid account can add it again, while trial accounts get 409 duplicate_domain.

Changing settings or deleting a site requires role owner or higher. Calling sites.remove wipes the site and everything stored for it, from scan history and rankings to links and reports. Because that cannot be undone, you must pass the exact domain from sites.get in confirm_domain, or the call stops with 400 confirm_mismatch.

One shared competitor list with SERP suggestions

Every site has a single list of up to 6 competitor domains (max: 6) shared by the Rank tracker, Core Web Vitals and AI Insights. We strip www and keep the domains in the order you add them; chart colours in the app follow that same order. Anyone on the site with role user or higher can replace the whole list with competitors.save, or add and remove individual domains with competitors.add and competitors.remove.

Along with the current list, competitors.list returns suggestions with the domains that ranked above the site most often in its latest Rank tracker measurements. Each suggestion includes keywords_above, with big platforms like Wikipedia and YouTube already left out. The Rank tracker stores the top 20 results for every measurement, so a competitor you add later already has ranking history from earlier checks.

Adding a site and reading its competitor suggestions

Every endpoint takes a POST request with a JSON body at /rest/v1/<endpoint> and an Authorization: Bearer header. The three reading endpoints also accept GET with query parameters and are in the MCP server as read-only tools.

curl -s https://app.marketingtracer.com/rest/v1/sites.add \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"domain":"https://www.example.co.uk/","country":"uk","language":"en","tag":"Campaign Q4"}'
{
  "data": {
    "id": "6733f0e1d2c3b4a596877869",
    "domain": "www.example.co.uk",
    "url": "https://www.example.co.uk",
    "country": "uk",
    "language": "en",
    "tag": "Campaign Q4",
    "role": "white_label_admin",
    "status": "white_label",
    "active": true,
    "expires_at": "2026-11-26T15:30:02Z",
    "favorite": false,
    "search_console_connected": false,
    "analytics_connected": false,
    "created_at": "2026-11-12T15:30:02Z"
  },
  "meta": []
}

Once the site has Rank tracker measurements, competitors.list returns both the followed competitors and the suggested SERP rivals:

curl -s https://app.marketingtracer.com/rest/v1/competitors.list \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"site_id":"65a1b2c3d4e5f60718293a4b"}'
{
  "data": {
    "competitors": [
      "example-shop.nl",
      "voorbeeld.com"
    ],
    "max": 6,
    "suggestions": [
      {"domain": "example-rival.nl", "keywords_above": 23},
      {"domain": "another-example.com", "keywords_above": 14},
      {"domain": "sample-store.nl", "keywords_above": 9}
    ]
  },
  "meta": {
    "site_id": "65a1b2c3d4e5f60718293a4b"
  }
}

Adding a new client straight from your onboarding

When a new client signs up in your agency portal or CRM, your backend calls sites.add with their domain and locale, plus your internal client ID in tag. On your white label domain, the site is added to your white label (status: "white_label") and billed to your account. The first SEO crawl starts right away, and you can follow its progress through scan.status. Save the returned id as site_id in your database and pass the client's rivals to competitors.save so every tool starts with the same competitor list.

Picking real SERP rivals with your client

Ask a new client who their competitors are and they usually name the company down the road. Once the Rank tracker has run, competitors.list returns the site's followed domains (up to 6) along with suggestions: the domains that ranked above the client most often in Google. Big platforms like Wikipedia and YouTube are already filtered out. Show that list in your onboarding screen and add the domains your client picks with competitors.add. The Rank tracker keeps the top 20 for every measurement, so a competitor you add weeks later still has ranking history from day one.

Checking Google connections and offboarding a client

Your admin overview or daily sync calls sites.list to pull every site you manage, starred sites first. Every row includes active and expires_at along with search_console_connected and analytics_connected, so your team sees right away which client still needs to connect Search Console or GA4. If a client moves to another market or account manager, sites.update changes country, language or tag. When a contract ends, call sites.remove with the domain in confirm_domain to wipe the site and all its stored history.

Endpoints, arguments and field descriptions

Every endpoint is a POST with a JSON body; reading endpoints also take a GET with the same arguments in the query string. Send your API key as Authorization: Bearer YOUR_API_KEY. Every answer is {"data": …, "meta": {…}}: meta.site_id always, meta.next_cursor and meta.total for a list, meta.period where the endpoint covers a period. An error is {"error": {"code", "message"}} with the HTTP status: 400 invalid_argument, unknown_argument or missing_argument; 401 not_authenticated; 403 no_access or tool_off; 404 not_found; 409 not_connected (a connection the endpoint needs, such as Google Analytics 4, is missing); 429 rate_limited; 502 google_error (Google returned an error). The machine-readable version is openapi.json.

sites.list

POST /rest/v1/sites.list · MCP tool

Returns the sites you can open: for an owner or admin of a white label every site of that white label, for anyone else the sites you were added to (on a white label domain only those of that white label). Starred sites first, then by domain.

Arguments

ArgumentTypeWhat it does
qstringOnly sites whose domain contains this text.
limitinteger, 1 to 500, default 100Sites per call.
cursorstringmeta.next_cursor of the previous call, for the next page.

Example request

curl -X POST https://app.marketingtracer.com/rest/v1/sites.list \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"limit":3,"site_id":"YOUR_SITE_ID"}'

Example response · A white label admin with 41 sites; domains anonymised.

{
  "data": [
    {
      "id": "65a1b2c3d4e5f60718293a4b",
      "domain": "www.example.com",
      "url": "https://www.example.com",
      "country": "nl",
      "language": "nl",
      "tag": "Klant A",
      "role": "white_label_admin",
      "status": "white_label",
      "active": true,
      "expires_at": "2026-11-26T09:12:40Z",
      "favorite": true,
      "search_console_connected": true,
      "analytics_connected": true,
      "created_at": "2024-01-12T14:03:31Z"
    },
    {
      "id": "65f0c1d2e3f4a5b6c7d8e9f0",
      "domain": "shop.example.org",
      "url": "https://shop.example.org",
      "country": "be",
      "language": "nl",
      "tag": null,
      "role": "white_label_admin",
      "status": "white_label",
      "active": true,
      "expires_at": "2026-11-26T09:12:40Z",
      "favorite": false,
      "search_console_connected": true,
      "analytics_connected": false,
      "created_at": "2024-03-13T08:41:20Z"
    },
    {
      "id": "6731aa02b4c5d6e7f8091a2b",
      "domain": "www.example.net",
      "url": "https://www.example.net",
      "country": "de",
      "language": "de",
      "tag": null,
      "role": "white_label_admin",
      "status": "on_hold",
      "active": false,
      "expires_at": "2026-09-28T09:12:40Z",
      "favorite": false,
      "search_console_connected": false,
      "analytics_connected": false,
      "created_at": "2024-11-11T10:22:58Z"
    }
  ],
  "meta": {"next_cursor": "3", "total": 41, "site_id": "YOUR_SITE_ID"}
}

Response fields · data is a list; each item has:

FieldTypeWhat it is
idstringThe site id: site_id in every other endpoint.
domainstringThe domain as we scan it, e.g. www.example.com.
urlstringhttps:// plus the domain.
countrystring or nullTwo-letter country code Google data is filtered and measured for (Rank tracker, AI Insights); null when not set.
languagestring or nullLanguage code for Google (nl, en, pt-BR …); null when not set.
tagstring or nullYour own label for the site; null without one.
rolestring or nullYour role on this site: superadmin, white_label_admin, admin, owner, user or guest.
statusstringtrial, paid, white_label (a site of a white label, billed to the white label), on_hold, test or other.
activebooleanWhether the site is active now: not expired and not on hold. Scans and measurements only run for active sites.
expires_atstring or nullWhen the site expires unless renewed, ISO 8601 UTC. White label sites are renewed every day while the white label is paid.
favoritebooleanWhether you starred the site.
search_console_connectedbooleanWhether Search Console is connected (with a property).
analytics_connectedbooleanWhether Google Analytics 4 is connected (with a property).
created_atstring or nullWhen the site was added, ISO 8601 UTC.

sites.get

POST /rest/v1/sites.get · MCP tool get_site

Returns one site: its domain, country and language, your role, whether it is active and until when, and which Google accounts are connected.

Arguments

ArgumentTypeWhat it does
site_id (required)stringThe site: its id from list_sites, or the id in the app’s address.

Example request

curl -X POST https://app.marketingtracer.com/rest/v1/sites.get \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"site_id":"YOUR_SITE_ID"}'

Example response · Domain anonymised.

{
  "data": {
    "id": "65a1b2c3d4e5f60718293a4b",
    "domain": "www.example.com",
    "url": "https://www.example.com",
    "country": "nl",
    "language": "nl",
    "tag": "Klant A",
    "role": "white_label_admin",
    "status": "white_label",
    "active": true,
    "expires_at": "2026-11-26T09:12:40Z",
    "favorite": true,
    "search_console_connected": true,
    "analytics_connected": true,
    "created_at": "2024-01-12T14:03:31Z"
  },
  "meta": {"site_id": "YOUR_SITE_ID"}
}

Response fields · in data:

FieldTypeWhat it is
idstringThe site id: site_id in every other endpoint.
domainstringThe domain as we scan it, e.g. www.example.com.
urlstringhttps:// plus the domain.
countrystring or nullTwo-letter country code Google data is filtered and measured for (Rank tracker, AI Insights); null when not set.
languagestring or nullLanguage code for Google (nl, en, pt-BR …); null when not set.
tagstring or nullYour own label for the site; null without one.
rolestring or nullYour role on this site: superadmin, white_label_admin, admin, owner, user or guest.
statusstringtrial, paid, white_label (a site of a white label, billed to the white label), on_hold, test or other.
activebooleanWhether the site is active now: not expired and not on hold. Scans and measurements only run for active sites.
expires_atstring or nullWhen the site expires unless renewed, ISO 8601 UTC. White label sites are renewed every day while the white label is paid.
favoritebooleanWhether you starred the site.
search_console_connectedbooleanWhether Search Console is connected (with a property).
analytics_connectedbooleanWhether Google Analytics 4 is connected (with a property).
created_atstring or nullWhen the site was added, ISO 8601 UTC.

sites.add

POST /rest/v1/sites.add · MCP tool

Returns the new site (as sites.get) after adding it. You become its owner. On a white label domain the site belongs to that white label and is billed to it like every site of the white label. The first crawl starts at once; follow it with scan.status. A domain that already exists can only be added again by white label staff or a paid account (409 duplicate_domain); a domain that does not resolve is refused (400 invalid_domain).

Arguments

ArgumentTypeWhat it does
domain (required)stringThe domain or the address of the homepage: www.example.com or https://www.example.com/. Only the host counts.
tagstringYour own label for the site.
countrystringTwo-letter country code (nl, be, de, uk, us …; gb works too and is stored as uk, like everywhere in this API). Without it: the default of the white label.
languagestringLanguage code (nl, en, de, fr, pt-BR …). Without it: the default of the white label. Also sets the language of the app for this site when we have it (nl, en, de, fr; otherwise English).

Example request

curl -X POST https://app.marketingtracer.com/rest/v1/sites.add \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"domain":"https://www.example.co.uk/","country":"uk","language":"en","tag":"Campaign Q4","site_id":"YOUR_SITE_ID"}'

Example response · Added by a white label admin on the white label domain; the first crawl has started.

{
  "data": {
    "id": "6733f0e1d2c3b4a596877869",
    "domain": "www.example.co.uk",
    "url": "https://www.example.co.uk",
    "country": "uk",
    "language": "en",
    "tag": "Campaign Q4",
    "role": "white_label_admin",
    "status": "white_label",
    "active": true,
    "expires_at": "2026-11-26T15:30:02Z",
    "favorite": false,
    "search_console_connected": false,
    "analytics_connected": false,
    "created_at": "2026-11-12T15:30:02Z"
  },
  "meta": {"site_id": "YOUR_SITE_ID"}
}

Response fields · in data:

FieldTypeWhat it is
idstringThe site id: site_id in every other endpoint.
domainstringThe domain as we scan it, e.g. www.example.com.
urlstringhttps:// plus the domain.
countrystring or nullTwo-letter country code Google data is filtered and measured for (Rank tracker, AI Insights); null when not set.
languagestring or nullLanguage code for Google (nl, en, pt-BR …); null when not set.
tagstring or nullYour own label for the site; null without one.
rolestring or nullYour role on this site: superadmin, white_label_admin, admin, owner, user or guest.
statusstringtrial, paid, white_label (a site of a white label, billed to the white label), on_hold, test or other.
activebooleanWhether the site is active now: not expired and not on hold. Scans and measurements only run for active sites.
expires_atstring or nullWhen the site expires unless renewed, ISO 8601 UTC. White label sites are renewed every day while the white label is paid.
favoritebooleanWhether you starred the site.
search_console_connectedbooleanWhether Search Console is connected (with a property).
analytics_connectedbooleanWhether Google Analytics 4 is connected (with a property).
created_atstring or nullWhen the site was added, ISO 8601 UTC.

sites.update

POST /rest/v1/sites.update · MCP tool

Returns the site (as sites.get) after changing its country, language or tag. Only what you send changes. Owner or higher.

Arguments

ArgumentTypeWhat it does
site_id (required)stringThe site: its id from list_sites, or the id in the app’s address.
tagstringYour own label; an empty string removes it.
countrystringTwo-letter country code (nl, be, de, uk, us …; gb works too and is stored as uk, like everywhere in this API). Without it: the default of the white label.
languagestringLanguage code (nl, en, de, fr, pt-BR …). Without it: the default of the white label. Also sets the language of the app for this site when we have it (nl, en, de, fr; otherwise English).

Example request

curl -X POST https://app.marketingtracer.com/rest/v1/sites.update \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"site_id":"YOUR_SITE_ID","country":"be","tag":"Klant B"}'

Example response · Only country and tag changed.

{
  "data": {
    "id": "65a1b2c3d4e5f60718293a4b",
    "domain": "www.example.com",
    "url": "https://www.example.com",
    "country": "be",
    "language": "nl",
    "tag": "Klant B",
    "role": "white_label_admin",
    "status": "white_label",
    "active": true,
    "expires_at": "2026-11-26T09:12:40Z",
    "favorite": true,
    "search_console_connected": true,
    "analytics_connected": true,
    "created_at": "2024-01-12T14:03:31Z"
  },
  "meta": {"site_id": "YOUR_SITE_ID"}
}

Response fields · in data:

FieldTypeWhat it is
idstringThe site id: site_id in every other endpoint.
domainstringThe domain as we scan it, e.g. www.example.com.
urlstringhttps:// plus the domain.
countrystring or nullTwo-letter country code Google data is filtered and measured for (Rank tracker, AI Insights); null when not set.
languagestring or nullLanguage code for Google (nl, en, pt-BR …); null when not set.
tagstring or nullYour own label for the site; null without one.
rolestring or nullYour role on this site: superadmin, white_label_admin, admin, owner, user or guest.
statusstringtrial, paid, white_label (a site of a white label, billed to the white label), on_hold, test or other.
activebooleanWhether the site is active now: not expired and not on hold. Scans and measurements only run for active sites.
expires_atstring or nullWhen the site expires unless renewed, ISO 8601 UTC. White label sites are renewed every day while the white label is paid.
favoritebooleanWhether you starred the site.
search_console_connectedbooleanWhether Search Console is connected (with a property).
analytics_connectedbooleanWhether Google Analytics 4 is connected (with a property).
created_atstring or nullWhen the site was added, ISO 8601 UTC.

sites.remove

POST /rest/v1/sites.remove · MCP tool

Returns removed: true after removing a site with everything we stored for it (scans, keywords, links, history). This cannot be undone. Owner or higher. Send the domain as confirm_domain, so a wrong site_id never removes another site.

Arguments

ArgumentTypeWhat it does
site_id (required)stringThe site: its id from list_sites, or the id in the app’s address.
confirm_domain (required)stringThe domain of the site, exactly as in sites.get.

Example request

curl -X POST https://app.marketingtracer.com/rest/v1/sites.remove \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"site_id":"YOUR_SITE_ID","confirm_domain":"www.example.net"}'

Example response · The answer is always this shape.

{
  "data": {"id": "6731aa02b4c5d6e7f8091a2b", "domain": "www.example.net", "removed": true},
  "meta": {"site_id": "YOUR_SITE_ID"}
}

Response fields · in data:

FieldTypeWhat it is
idstringThe id of the removed site.
domainstringIts domain.
removedbooleanAlways true.

Endpoints, arguments and field descriptions

Every endpoint is a POST with a JSON body; reading endpoints also take a GET with the same arguments in the query string. Send your API key as Authorization: Bearer YOUR_API_KEY. Every answer is {"data": …, "meta": {…}}: meta.site_id always, meta.next_cursor and meta.total for a list, meta.period where the endpoint covers a period. An error is {"error": {"code", "message"}} with the HTTP status: 400 invalid_argument, unknown_argument or missing_argument; 401 not_authenticated; 403 no_access or tool_off; 404 not_found; 409 not_connected (a connection the endpoint needs, such as Google Analytics 4, is missing); 429 rate_limited; 502 google_error (Google returned an error). The machine-readable version is openapi.json.

competitors.list

POST /rest/v1/competitors.list · MCP tool get_competitors_list

Returns the competitors the site follows: one list for the Rank tracker, Core Web Vitals and AI Insights. With suggestions: the domains that most often rank above the site in its latest Rank tracker measurements (platforms like Wikipedia or YouTube left out).

Arguments

ArgumentTypeWhat it does
site_id (required)stringThe site: its id from list_sites, or the id in the app’s address.

Example request

curl -X POST https://app.marketingtracer.com/rest/v1/competitors.list \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"site_id":"YOUR_SITE_ID"}'

Example response · Domains anonymised; suggestions from the latest Rank tracker measurements of 61 keywords.

{
  "data": {
    "competitors": ["example-shop.nl", "voorbeeld.com"],
    "max": 6,
    "suggestions": [
      {"domain": "example-rival.nl", "keywords_above": 23},
      {"domain": "another-example.com", "keywords_above": 14},
      {"domain": "sample-store.nl", "keywords_above": 9}
    ]
  },
  "meta": {"site_id": "YOUR_SITE_ID"}
}

Response fields · in data:

FieldTypeWhat it is
competitorsarray<string>The followed competitors: domains without www, in the order they were added. Their colour in the charts follows this order.
maxintegerHow many a site can follow (6).
suggestionsarrayDomains worth following, most often above you first; empty without Rank tracker measurements.
suggestions[].domainstringThe domain.
suggestions[].keywords_aboveintegerIn how many of the latest measurements it ranked above the site.

competitors.save

POST /rest/v1/competitors.save · MCP tool

Returns the competitors after replacing the whole list. Cleaned like everywhere: without www, no duplicates, never the site itself, at most 6 (the rest is dropped). An empty list removes all. Positions come from the stored Rank tracker results, so a competitor added later still has history.

Arguments

ArgumentTypeWhat it does
site_id (required)stringThe site: its id from list_sites, or the id in the app’s address.
competitors (required)list of stringThe domains to follow, in order.

Example request

curl -X POST https://app.marketingtracer.com/rest/v1/competitors.save \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"site_id":"YOUR_SITE_ID","competitors":["https://www.example-shop.nl/","voorbeeld.com","example-rival.nl"]}'

Example response · Cleaned: without www and path.

{
  "data": {"competitors": ["example-shop.nl", "voorbeeld.com", "example-rival.nl"], "max": 6},
  "meta": {"site_id": "YOUR_SITE_ID"}
}

Response fields · in data:

FieldTypeWhat it is
competitorsarray<string>The followed competitors: domains without www, in the order they were added. Their colour in the charts follows this order.
maxintegerHow many a site can follow (6).

competitors.add

POST /rest/v1/competitors.add · MCP tool

Returns the competitors after adding one at the end. Already followed: nothing changes. With 6 already: 409 list_full.

Arguments

ArgumentTypeWhat it does
site_id (required)stringThe site: its id from list_sites, or the id in the app’s address.
domain (required)stringA domain or an address on it (https://www.example.com/page works too); stored without www.

Example request

curl -X POST https://app.marketingtracer.com/rest/v1/competitors.add \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"site_id":"YOUR_SITE_ID","domain":"sample-store.nl"}'

Example response · The answer is always this shape.

{
  "data": {
    "competitors": ["example-shop.nl", "voorbeeld.com", "example-rival.nl", "sample-store.nl"],
    "max": 6
  },
  "meta": {"site_id": "YOUR_SITE_ID"}
}

Response fields · in data:

FieldTypeWhat it is
competitorsarray<string>The followed competitors: domains without www, in the order they were added. Their colour in the charts follows this order.
maxintegerHow many a site can follow (6).

competitors.remove

POST /rest/v1/competitors.remove · MCP tool

Returns the competitors after removing one. Not followed: nothing changes.

Arguments

ArgumentTypeWhat it does
site_id (required)stringThe site: its id from list_sites, or the id in the app’s address.
domain (required)stringA domain or an address on it (https://www.example.com/page works too); stored without www.

Example request

curl -X POST https://app.marketingtracer.com/rest/v1/competitors.remove \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"site_id":"YOUR_SITE_ID","domain":"voorbeeld.com"}'

Example response · The answer is always this shape.

{
  "data": {"competitors": ["example-shop.nl", "example-rival.nl", "sample-store.nl"], "max": 6},
  "meta": {"site_id": "YOUR_SITE_ID"}
}

Response fields · in data:

FieldTypeWhat it is
competitorsarray<string>The followed competitors: domains without www, in the order they were added. Their colour in the charts follows this order.
maxintegerHow many a site can follow (6).
White label & agency keys

Run the Sites API on your own domain with one white label key for every client site.

On your agency's white label domain, the REST API and the MCP server answer on your own URL under your name and logo. An owner or admin creates a white label key (mtw_…) on the MCP page in the app. That single key works on your own domains, covers every client site in your white label and gives you 600 calls per minute. Personal keys (mtk_…, 60 calls per minute) follow the exact site access and role of the person who made them. You create and revoke keys on the MCP page in the app, and an API key can never create or read keys.

OverviewAll SEO API topics, keys and authentication After sites.addSEO audit API for scan.status and site issues Competitors in actionRank tracker API for positions and competitor visibility

Free 14-day trial

MarketingTracer smart A.I. tool shows you what you need to rank. Then we'll help you get it done.

  • No credit card required
  • No installation needed
  • No strings attached
Start your 14-day trial

FAQ

Something else? Ask us.

Does adding a site with sites.add start the SEO crawl immediately?

Yes. As soon as sites.add creates the site, the first crawl starts in the background and the recommended alert settings are set for your account. You can poll scan.status with the returned id as site_id to follow the crawl.

What is the difference between a white label key (mtw_…) and a personal key (mtk_…)?

White label keys (mtw_…) are made by a white label owner or admin and work on the white label's own domains. They give access to every site of that white label at 600 calls per minute. Personal keys (mtk_…) have the same site access and role as the user who created them, with a limit of 60 calls per minute.

Can an AI assistant add or delete sites through the MCP server?

No. The MCP server is read-only. An AI assistant can call list_sites and get_site to inspect sites, or get_competitors_list to read competitors and suggestions. Every write call goes through the REST API with an API key.

Why does sites.add return 409 duplicate_domain?

That domain is already a site in MarketingTracer. Trial accounts cannot add a domain that already exists in the system. White label staff and paid accounts can add an existing domain again under their own account or white label.

Do competitors added later with competitors.add get historical ranking data?

Yes. The Rank tracker stores the top 20 results for every keyword measurement. Any competitor domain you add later is matched against those stored results and shows its ranking history right away.

Which tools share the competitor list from competitors.list?

The Rank tracker, Core Web Vitals and AI Insights all share the same list of up to six competitor domains per site. Any change you make to that list updates the comparison in all three tools at once, and chart colours follow the order of the domains.

What gets deleted when I call sites.remove?

Everything stored for that site is deleted permanently: scanned pages and weekly audit history; Rank tracker keywords and AI visibility data; watched links and the linkbuilding pipeline; topic models and planning tasks; cached reports and the site itself. You need role owner or higher and must pass the site's exact domain in confirm_domain.