One keyword with its expanded row
GET
/sites/{siteId}/keywords/{keywordId}- Berechtigung
search:read- MCP-Tool
keyword
One keyword with its expanded row One keyword (the fields of GET /keywords) with what its expanded row on the Keywords screen shows: the related keywords on the same topic with volumes, who ranks in the last stored Google check (engine, location, device) and why it is an opportunity. Who ranks only reads stored checks of tracked keywords; it never buys a new lookup (track the keyword with POST /keywords/track).
Die Beschreibungen kommen aus dem OpenAPI-Dokument und sind auf Englisch.
Parameter
| Name | Ort | Details |
|---|---|---|
siteIdPflicht | Pfad | stringWebsite id, from GET /sites. |
keywordIdPflicht | Pfad | stringKeyword id, from GET /keywords or keywordId on a gap row. |
related | Query | integerdefault 4, min 1, max 20How many related keywords; the screen shows 4. |
Antwort
200 · application/json
| Feld | Details |
|---|---|
keyword | object · required |
keyword.id | string |
keyword.keyword | string |
keyword.source | string |
keyword.branded | true or false |
keyword.cluster | string |
keyword.intent | string |
keyword.locationCode | number |
keyword.location | string |
keyword.languageCode | string |
keyword.device | string |
keyword.volume | number |
keyword.difficulty | number |
keyword.cpc | number |
keyword.competition | number |
keyword.monthly | list of numbers |
keyword.dataUpdatedAt | string |
keyword.position | number |
keyword.positionFrom | string |
keyword.gscPosition | number |
keyword.gscClicks | number |
keyword.gscImpressions | number |
keyword.gscUrl | string |
keyword.tracked | true or false |
keyword.latestPosition | number |
keyword.latestUrl | string |
keyword.latestDate | string |
keyword.deepPosition | number |
keyword.deepDate | string |
keyword.weekAgoPosition | number |
keyword.bestPosition | number |
keyword.features | list of strings |
keyword.opportunity | string |
keyword.opportunityScore | number |
keyword.relevance | number |
keyword.relevanceStatus | string |
keyword.offTopic | true or false |
keyword.topic | string |
keyword.relevanceReason | string |
keyword.relevanceIntent | string |
keyword.action | object |
keyword.action.id | string |
keyword.action.status | string |
keyword.action.link | string |
related | list of object · required; Keywords on the same topic, most searched first; off-topic ones left out |
related[].id | string · required; Keyword id |
related[].keyword | string · required; The search phrase |
related[].volume | integer or null · required; Monthly searches (estimate) |
related[].position | number or null · required; Our position (as position on a keyword); null: not ranking |
whoRanks | object or null · required; The "Who ranks" panel: the last stored Google check of the keyword. null when it has none: only tracked keywords are checked, and reading never buys a new lookup |
whoRanks.engine | google · required; The search engine |
whoRanks.date | date (YYYY-MM-DD) · required; Day of the check |
whoRanks.observedAt | string · required; When the check read the results |
whoRanks.locationCode | integer · required; Google location id of the check |
whoRanks.location | string · required; The location by name |
whoRanks.languageCode | string · required; Language code |
whoRanks.device | mobile | desktop · required; Device of the check |
whoRanks.ourPosition | integer · required; Our position in that check; 0 = not in the results it read |
whoRanks.ourUrl | string or null · required; Our ranking page in that check |
whoRanks.results | list of object · required; The top results that check read, best first |
whoRanks.results[].position | integer · required; Position |
whoRanks.results[].domain | string · required; Domain |
whoRanks.results[].url | string or null · required; The ranking page |
whoRanks.results[].ours | true or false · required; This website |
whoRanks.features | list of string · required; Search result features on the page |
why | object · required |
why.opportunity | defend | improve | new | · required; The opportunity label |
why.text | string · required; "Why it is an opportunity" from the expanded row, in English |
why.relevanceReason | string or null · required; The relevance review's reason, which the screen shows after the text |
why.relatedRanking | list of object · required; Related keywords the website already ranks for, best first (up to 10) |
why.relatedRanking[].id | string · required; Keyword id |
why.relatedRanking[].keyword | string · required; The search phrase |
why.relatedRanking[].volume | integer or null · required; Monthly searches (estimate) |
why.relatedRanking[].position | number or null · required; Our position (as position on a keyword); null: not ranking |
note | string · required; How to read the numbers |
link | address (URL) · required; The keyword on the Keywords screen |
Fehler
| Status | Bedeutung |
|---|---|
400 | Bad request. Codes: bad_related. |
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, keyword_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/keywords/KEYWORD_ID"const res = await fetch("https://app.monoranks.com/api/v1/sites/SITE_ID/keywords/KEYWORD_ID", {
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/keywords/KEYWORD_ID",
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/keywords/KEYWORD_ID");
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/keywords/KEYWORD_ID", { headers: { Authorization: "Bearer mr_ws_…" } });Beispielantwort
{
"keyword": {
"id": "2d4f6b8d-0f2b-4d4f-9b6d-0f2b4d6f8b0d",
"keyword": "gravel bike tires",
"source": "search_console",
"branded": false,
"cluster": "gravel tires",
"intent": "commercial",
"locationCode": 2840,
"location": "United States",
"languageCode": "en",
"device": "mobile",
"volume": 2900,
"difficulty": 34,
"cpc": 1.12,
"competition": 0.81,
"monthly": [
2400,
2400,
2900,
2900,
3600,
3600,
3600,
2900,
2900,
2400,
2400,
2900
],
"dataUpdatedAt": "2026-10-01T04:12:00.000Z",
"position": 6,
"positionFrom": "tracked",
"gscPosition": 7.4,
"gscClicks": 118,
"gscImpressions": 3240,
"gscUrl": "https://acmebikes.com/tires/gravel/",
"tracked": true,
"latestPosition": 6,
"latestUrl": "https://acmebikes.com/tires/gravel/",
"latestDate": "2026-10-05",
"deepPosition": 6,
"deepDate": "2026-10-05",
"weekAgoPosition": 8,
"bestPosition": 5,
"features": [
"people_also_ask",
"images"
],
"opportunity": "improve",
"opportunityScore": 42.7,
"relevance": 92,
"relevanceStatus": "reviewed",
"offTopic": false,
"topic": "Tires",
"relevanceReason": "Acme Bikes sells gravel tires on this page.",
"relevanceIntent": "commercial",
"action": {
"id": "b2e4c6a8-1d3f-4a5b-9c7d-0e2f4a6b8c1d",
"status": "open",
"link": "https://app.monoranks.com/sites/3f6c2a1e-8b4d-4c7a-9e21-5d0b7a6f4c13/actions/b2e4c6a8-1d3f-4a5b-9c7d-0e2f4a6b8c1d"
}
},
"related": [
{
"id": "c7a9e1b3-5d7f-4b9c-8e1a-3c5e7a9b1d2f",
"keyword": "gravel bike tyres",
"volume": 880,
"position": null
},
{
"id": "0b2d4f6a-8c0e-4a2c-9e4a-8c0e2a4c6e8a",
"keyword": "best gravel tires",
"volume": 720,
"position": 12
}
],
"whoRanks": {
"engine": "google",
"date": "2026-10-05",
"observedAt": "2026-10-05T03:10:00.000Z",
"locationCode": 2840,
"location": "United States",
"languageCode": "en",
"device": "mobile",
"ourPosition": 6,
"ourUrl": "https://acmebikes.com/tires/gravel/",
"results": [
{
"position": 1,
"domain": "bikeworld.example",
"url": "https://bikeworld.example/gravel-tires/",
"ours": false
},
{
"position": 6,
"domain": "acmebikes.com",
"url": "https://acmebikes.com/tires/gravel/",
"ours": true
}
],
"features": [
"people_also_ask"
]
},
"why": {
"opportunity": "improve",
"text": "You rank on page 1 for this. A better page can climb; each step up roughly doubles the clicks.",
"relevanceReason": "Acme Bikes sells gravel tires on this page.",
"relatedRanking": [
{
"id": "0b2d4f6a-8c0e-4a2c-9e4a-8c0e2a4c6e8a",
"keyword": "best gravel tires",
"volume": 720,
"position": 12
}
]
},
"note": "whoRanks: the last stored Google check; null when the keyword has none.",
"link": "https://app.monoranks.com/sites/3f6c2a1e-8b4d-4c7a-9e21-5d0b7a6f4c13/keywords?open=2d4f6b8d-0f2b-4d4f-9b6d-0f2b4d6f8b0d"
}{
"error": {
"code": "bad_related",
"message": "related must be a whole number from 1 to 20."
}
}{
"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 keyword.