Keyword-Lücken auflisten
GET
/sites/{siteId}/competitors/gaps- Berechtigung
search:read- MCP-Tool
competitor_gaps
Keyword gaps across the competitor set Per keyword each competitor's Google position and ranking page next to ours. Views: gaps (they rank, we do not), content (gaps with 1,000+ searches), lost (we rank below 10, one of them in the top 3), lead (we rank above all of them). Off-topic and competitor-brand keywords are left out (counts.hidden); include=offtopic lists them with hidden: true. Also accepted in snake_case (min_volume for minVolume).
Die Beschreibungen kommen aus dem OpenAPI-Dokument und sind auf Englisch.
Parameter
| Name | Ort | Details |
|---|---|---|
siteIdPflicht | Pfad | stringWebsite id, from GET /sites. |
view | Query | gapscontentlostleaddefault gapsWhich keywords to list. |
q | Query | stringat most 100 charactersPart of the keyword. |
domains | Query | stringComma-separated competitor domains, each in the set. Default: the ones the Keyword gaps table compares (the competitors that drive gaps and have data, at most three). |
include | Query | offtopicofftopic also lists off-topic and competitor-brand keywords. |
sort | Query | opportunityvolumedefault opportunityopportunity (0–100: relevance × demand × winnable difficulty) or monthly searches. |
minVolume | Query | integermin 0, max 10000000Only keywords with at least this many monthly searches. Also accepted in snake_case (min_volume for minVolume). |
maxDifficulty | Query | integermin 0, max 100Only keywords at most this hard (0–100; 0 = no limit). |
page | Query | integerdefault 1, min 1Page number, from 1. |
per | Query | integerdefault 50, min 1, max 200Rows per page, 1 to 200. |
Antwort
200 · application/json
| Feld | Details |
|---|---|
domains | list of string · required; The competitors compared |
view | gaps | content | lost | lead · required; The view listed |
sort | opportunity | volume · required; The order |
include | offtopic | · required; Hidden keywords included |
filters | object · required; The filters applied to the rows |
filters.q | string or null · required; Search |
filters.minVolume | integer or null · required; Minimum monthly searches |
filters.maxDifficulty | integer or null · required; Maximum difficulty |
counts | object · required; Keywords per tab, as the screen counts them: before q, minVolume and maxDifficulty |
counts.gaps | integer · required; Keywords in gaps |
counts.content | integer · required; Keywords in content |
counts.lost | integer · required; Keywords in lost |
counts.lead | integer · required; Keywords in lead |
counts.hidden | integer · required; Off-topic and competitor-brand keywords this view leaves out |
total | integer · required; Rows that match, over all pages |
page | integer · required; This page, from 1 |
per | integer · required; Rows per page |
hasMore | true or false · required; More rows after this page |
rows | list of values · required |
rows[].keyword | string |
rows[].keywordId | |
rows[].locationCode | number |
rows[].location | string |
rows[].languageCode | string |
rows[].device | |
rows[].volume | number |
rows[].difficulty | number |
rows[].ourPosition | |
rows[].positions | object |
rows[].positions.bikeworld.example | number |
rows[].positions.cyclehub.example | number |
rows[].pages | object |
rows[].pages.bikeworld.example | string |
rows[].pages.cyclehub.example | |
rows[].opportunity | number |
rows[].relevance | number |
rows[].relevanceStatus | string |
rows[].offTopic | true or false |
rows[].topic | string |
rows[].reason | string |
rows[].brand | |
rows[].hidden | true or false |
rows[].action | |
note | string · required; How to read the numbers |
link | address (URL) · required; The Competitors screen in the app |
Fehler
| Status | Bedeutung |
|---|---|
400 | Bad request. Codes: bad_view, unknown_competitor, bad_include, bad_sort, bad_minVolume, bad_maxDifficulty, bad_page, bad_per. |
401 | Missing, unknown or revoked key. Codes: missing_key, invalid_key. |
403 | The key lacks the scope, covers another website, or its owner lost access. Codes: missing_scope, other_site, owner_left, no_owner, forbidden. |
404 | Not found. Codes: not_found. |
429 | Too many requests this hour for this key. Codes: rate_limited. |
Beispielanfrage
curl \
-H "Authorization: Bearer mr_ws_…" \
"https://app.monoranks.com/api/v1/sites/SITE_ID/competitors/gaps"const res = await fetch("https://app.monoranks.com/api/v1/sites/SITE_ID/competitors/gaps", {
headers: { Authorization: "Bearer mr_ws_…" },
});
if (!res.ok) throw new Error((await res.json()).error.message);
const data = await res.json();import requests
res = requests.get(
"https://app.monoranks.com/api/v1/sites/SITE_ID/competitors/gaps",
headers={"Authorization": "Bearer mr_ws_…"},
)
res.raise_for_status()
data = res.json()<?php
$ch = curl_init("https://app.monoranks.com/api/v1/sites/SITE_ID/competitors/gaps");
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => ["Authorization: Bearer mr_ws_…"],
CURLOPT_RETURNTRANSFER => true,
]);
$data = json_decode(curl_exec($ch), true);import axios from "axios";
const { data } = await axios.get("https://app.monoranks.com/api/v1/sites/SITE_ID/competitors/gaps", { headers: { Authorization: "Bearer mr_ws_…" } });Beispielantwort
{
"domains": [
"bikeworld.example",
"cyclehub.example"
],
"view": "gaps",
"sort": "opportunity",
"include": null,
"filters": {
"q": null,
"minVolume": null,
"maxDifficulty": null
},
"counts": {
"gaps": 318,
"content": 42,
"lost": 17,
"lead": 64,
"hidden": 23
},
"total": 318,
"page": 1,
"per": 50,
"hasMore": true,
"rows": [
{
"keyword": "tubeless gravel tires",
"keywordId": null,
"locationCode": 2840,
"location": "United States",
"languageCode": "en",
"device": null,
"volume": 1900,
"difficulty": 28,
"ourPosition": null,
"positions": {
"bikeworld.example": 4,
"cyclehub.example": 9
},
"pages": {
"bikeworld.example": "https://bikeworld.example/tires/tubeless/",
"cyclehub.example": null
},
"opportunity": 74,
"relevance": 90,
"relevanceStatus": "reviewed",
"offTopic": false,
"topic": "Tires",
"reason": "Acme Bikes sells tubeless gravel tires.",
"brand": null,
"hidden": false,
"action": null
}
],
"note": "Views: gaps (they rank, we do not), content, lost, lead.",
"link": "https://app.monoranks.com/sites/3f6c2a1e-8b4d-4c7a-9e21-5d0b7a6f4c13/competitors"
}{
"error": {
"code": "bad_view",
"message": "view must be one of gaps, content, lost, lead."
}
}{
"error": {
"code": "missing_key",
"message": "Send the key as Authorization: Bearer mr_site_…"
}
}{
"error": {
"code": "missing_scope",
"message": "This key does not have the scope this call needs."
}
}{
"error": {
"code": "not_found",
"message": "Website not found."
}
}{
"error": {
"code": "rate_limited",
"message": "More than 1200 requests this hour for this key."
}
}Der MCP-Server macht dasselbe mit dem Tool competitor_gaps.