Ein Problem abrufen
/sites/{siteId}/issues/{issueId}- Berechtigung
issues:read- MCP-Tool
issue_detail
Get an issue with pages, evidence and suggestions For a writable field other than alt, suggestions gives the rule-based value per affected page, 100 per call: page with suggestions_offset. A recheck reads every listed page fresh, so affected, evidence and suggestions show what the pages say now.
Die Beschreibungen kommen aus dem OpenAPI-Dokument und sind auf Englisch.
Parameter
| Name | Ort | Details |
|---|---|---|
siteIdPflicht | Pfad | stringWebsite id, from GET /sites. |
issueIdPflicht | Pfad | stringIssue id, from GET /sites/{siteId}/issues or /actions. |
suggestions_offset | Query | integerdefault 0, min 0, max 1000000Suggestions to skip (suggestionsNextOffset of the previous page). |
suggestions_limit | Query | integerdefault 100, min 1, max 100Most suggestions to return, 1 to 100. |
suggestionsOffset | Query | integerdefault 0, min 0, max 1000000Same as suggestions_offset; the snake_case name wins when both are sent. |
suggestionsLimit | Query | integerdefault 100, min 1, max 100Same as suggestions_limit. |
Antwort
200 · application/json
| Feld | Details |
|---|---|
id | string · required; Issue id |
ruleId | string · required; Rule that found it, for example SEO-ONP-011 |
title | string · required; Issue title |
category | string · required; Rule category, for example Technical, On-page, Internal linking, Performance, Structured data, AEO readiness or Google Ads (the Ads waste checks, ADS-* rules: about the Ads account, so they list no pages and carry their rows in example.rows) |
severity | critical | serious | warning | low · required; How much it hurts |
confidence | high | medium | low · required; How sure the rule is |
status | open | in_progress | recheck_queued | resolved | ignored | reopened · required; Where the issue stands |
affectedPages | integer · required; Pages the issue lists |
template | string · required; The group of pages: Template: /blog/*, Site-level, or a count of URLs |
summary | string · required; One line on what was found |
firstSeen | string · required; First found |
lastSeen | string · required; Last found |
lastRecheck | required; What the last recheck found; null before any recheck |
link | string · required; The issue in the app |
why | string or null · required; Why it matters |
affected | list of object · required; Affected pages (first 50) |
affected[].url | string · required; Page address |
affected[].evidence | required; What the rule saw on the page |
affectedTotal | integer · required; All affected pages |
explanation | object or null · required; The AI explanation when drafted; null otherwise |
explanation.summary | string · required; What is wrong |
explanation.summaryRefs | list of string · required; Evidence the summary is based on |
explanation.why | string · required; Why it matters |
explanation.steps | list of object · required |
explanation.steps[].text | string · required; Fix step |
explanation.steps[].refs | list of string · required; Evidence for the step |
explanation.doNotTouch | list of string · required; What to leave alone |
explanation.verify | string · required; How to check the fix |
explanation.drafted | string · required; Always "AI-drafted from evidence" |
writableField | seo_title | seo_description | canonical | noindex | alt | redirect | · required; The field MonoRanks can write for this issue; null when none |
suggestions | list of object · Writable fields other than alt: the suggested value per affected page, the same as the app shows before Apply |
suggestions[].url | string · required; Page address |
suggestions[].pageId | string · required; Page id |
suggestions[].current | string · required; What the page shows now |
suggestions[].suggested | string or null · required; The rule-based value MonoRanks suggests; null when there is none |
suggestions[].advice | object or null · Meta descriptions only: advice for pages that may not need one |
suggestions[].advice.pageKind | legal | archive | empty_archive | empty_page | account · required; legal page, archive, empty archive, near-empty page, or a logged-in, cart or checkout page |
suggestions[].advice.legalKind | privacy | cookie | terms | imprint | legal · Kind of legal page |
suggestions[].advice.recommended | leave_or_noindex | add_posts_or_noindex | add_content_or_noindex | noindex · required; What to do besides or instead of a description |
suggestions[].advice.message | string · required; The advice in words |
suggestions[].writable | true or false · required; Whether apply can write this page |
suggestions[].notWritableReason | string · Why apply cannot write this page |
suggestionsNote | string or null · Titles only: the site changes the letter case of every title (for example Rank Math's Capitalize Titles) |
suggestionsTotal | integer · Suggestions over all pages |
suggestionsOffset | integer · Suggestions skipped |
suggestionsLimit | integer · Most suggestions in this answer |
suggestionsNextOffset | integer or null · Send as suggestions_offset for the next page; null after the last |
suggestionsTruncated | true or false · More suggestions after this page |
titleTemplate | object or null · Too-long titles (SEO-ONP-005) only: one template ending that makes most titles too long |
titleTemplate.suffix | string · required; The shared ending |
titleTemplate.count | integer · required; Titles carrying it |
titleTemplate.note | string · required; Where to shorten it once |
lastChange | object or null · required; The last approved change batch; null when none |
lastChange.batchId | string · required; Batch id |
lastChange.approvedBy | string · required; Who approved it |
lastChange.approvedAt | string · required; When it was approved |
lastChange.changes | list of object · required; First 50 changes |
lastChange.changes[].url | string · required; Page address |
lastChange.changes[].field | string · required; Field written, for example seo_description |
lastChange.changes[].value | string · required; The approved value |
lastChange.changes[].status | approved | applying | applied | not_live | failed | refused | stale | reverting | reverted | revert_failed · required; applied: written and seen on the live page; not_live: written, but the page still shows another value; refused: the plugin cannot write this field here; stale: the field changed in WordPress after the review, so it is back in review |
lastChange.changes[].appliedAt | string or null · required; When it was written |
lastChange.changes[].live | true or false or null · required; Whether the recheck saw the value on the live page |
lastChange.changes[].liveValue | string or null · required; What the live page showed |
lastChange.changes[].notLiveReason | string or null · required; not_live only: why, including whether the page cache was cleared |
lastChange.changes[].liveNote | string or null · required; applied only: for example the page shows the value in another letter case |
lastChange.changes[].error | string or null · required; Why it failed or was refused |
Hinweise
Für ein Problem, das MonoRanks beheben kann (SEO-Titel, Meta-Beschreibung, Canonical oder Weiterleitung), gibt GET /sites/{siteId}/issues/{issueId} auch suggestions zurück: für jede betroffene Seite den aktuellen Wert und den Wert, den MonoRanks vorschlägt. Es sind dieselben Werte, die die App zeigt, bevor Sie auf Apply drücken.
"suggestions": [
{ "url": "https://example.com/pricing/", "pageId": "…", "current": "Pricing", "suggested": "Pricing | Example", "writable": true }
],
"suggestionsTotal": 240,
"suggestionsOffset": 0,
"suggestionsLimit": 100,
"suggestionsNextOffset": 100,
"suggestionsTruncated": true
| Was | Details |
|---|---|
| Blättern | Jeder Aufruf liefert bis zu 100. Für die nächsten rufen Sie erneut auf, mit ? gleich suggestionsNextOffset; nach der letzten Seite ist es null. suggestions_limit (1 bis 100) legt die Seitengröße fest. Die Schreibweisen suggestionsOffset und suggestionsLimit funktionieren auch. |
suggested |
ist null, wenn MonoRanks für diese Seite keinen guten neuen Wert hat. Ein zu langer Titel wird nach festen Regeln gekürzt, die das Thema der Seite behalten und nie einen Ausdruck mittendrin abschneiden; wenn kein kürzerer Titel passt, ist suggested null und Sie können in der App einen entwerfen. |
suggestionsNote |
(nur Titel) ist gesetzt, wenn die Website die Groß- und Kleinschreibung von Titeln auf der Seite ändert, zum Beispiel mit der Einstellung Capitalize Titles von Rank Math. |
writable |
ist false, mit notWritableReason, wenn apply diese Seite nicht schreiben kann, zum Beispiel ein Kategoriearchiv, das kein WordPress-Beitrag und keine Seite ist. Senden Sie diese nicht an apply. |
advice |
(nur Meta-Beschreibungen) sagt, wann eine Seite vielleicht keine Beschreibung braucht: eine Rechtsseite oder ein Archiv (leer lassen oder noindex setzen), ein leeres Archiv (Beiträge hinzufügen oder noindex setzen) oder eine Login-, Konto-, Warenkorb- oder Kassenseite (noindex setzen; es wird keine Beschreibung vorgeschlagen). |
titleTemplate |
(zu lange Titel) ist gesetzt, wenn eine gemeinsame Endung aus der Titelvorlage des SEO-Plugins die meisten Titel zu lang macht; dann behebt eine Änderung an der Vorlage alle. |
lastRecheck |
sagt, was die letzte erneute Prüfung gefunden hat. Eine Prüfung liest jede gelistete Seite frisch neu, sodass bereits behobene Seiten aus der Liste fallen. Eine Seite, die nicht geantwortet hat, bleibt gelistet und wird in lastRecheck.notRechecked gezählt. |
lastChange |
ist der letzte genehmigte Stapel, mit dem Status jeder Änderung. not_live heißt: geschrieben, aber die Seite zeigt noch einen anderen Wert; notLiveReason sagt warum, auch ob der Seiten-Cache der Website nach dem Schreiben geleert wurde. Eine erneute Prüfung schaut sich solche Änderungen noch einmal an. Titel und Beschreibungen gelten als live, wenn sich nur Groß- und Kleinschreibung, Leerzeichen, Anführungszeichen oder Bindestriche unterscheiden; liveNote sagt dann, was sie geändert hat. |
Senden Sie die Werte, die Sie genehmigen, an POST /sites/{siteId}/actions/{issueId}/apply als { "changes": [ { "url": "…", "value": "…" } ] } (höchstens 500). Über die API schreibt apply SEO-Titel, Meta-Beschreibungen, Canonicals und noindex; Alt-Texte von Bildern und Weiterleitungen wenden Sie in der App an.
Persönliche E-Mail-Adressen im Seitentext, den MonoRanks speichert, werden verborgen, zum Beispiel j•••@gmail.com.
Fehler
| Status | Bedeutung |
|---|---|
400 | Bad request. Codes: bad_paging. |
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/issues/ISSUE_ID"const res = await fetch("https://app.monoranks.com/api/v1/sites/SITE_ID/issues/ISSUE_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/issues/ISSUE_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/issues/ISSUE_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/issues/ISSUE_ID", { headers: { Authorization: "Bearer mr_ws_…" } });Beispielantwort
{
"id": "b2e4c6a8-1d3f-4a5b-9c7d-0e2f4a6b8c1d",
"ruleId": "SEO-ONP-011",
"title": "Meta description missing on 3 pages (/products/*)",
"category": "On-page",
"severity": "warning",
"confidence": "high",
"status": "open",
"affectedPages": 3,
"template": "Template: /products/*",
"summary": "3 pages have no meta description. Google shows a snippet cut from the page instead.",
"firstSeen": "2026-09-20T02:40:03.000Z",
"lastSeen": "2026-10-04T02:41:12.000Z",
"lastRecheck": {
"at": "2026-10-02T09:12:44.000Z",
"present": 3,
"checked": 3,
"crawlId": "e5a7c9e1-3f5b-4d7f-9b1d-5f7b9d1f3b5c",
"passed": false
},
"link": "https://app.monoranks.com/sites/3f6c2a1e-8b4d-4c7a-9e21-5d0b7a6f4c13/issues/b2e4c6a8-1d3f-4a5b-9c7d-0e2f4a6b8c1d",
"why": "A written description raises click-through from results; it is the one line of ad copy you control.",
"affected": [
{
"url": "https://acmebikes.com/products/trail-pro-29",
"evidence": {
"title": "Trail Pro 29 Mountain Bike | Acme Bikes"
}
},
{
"url": "https://acmebikes.com/products/city-glide-7",
"evidence": {
"title": "City Glide 7 | Acme Bikes"
}
}
],
"affectedTotal": 3,
"explanation": null,
"writableField": "seo_description",
"suggestions": [
{
"url": "https://acmebikes.com/products/trail-pro-29",
"pageId": "c7a9e1b3-5d7f-4b9c-8e1a-3c5e7a9b1d2f",
"current": "",
"suggested": "Trail Pro 29: a light aluminium trail bike with 140 mm travel and a 12-speed drivetrain. Free delivery and 30-day returns.",
"advice": null,
"writable": true
}
],
"suggestionsNote": null,
"suggestionsTotal": 3,
"suggestionsOffset": 0,
"suggestionsLimit": 1,
"suggestionsNextOffset": 1,
"suggestionsTruncated": true,
"lastChange": {
"batchId": "f6b8d0f2-4a6c-4e8a-ac2e-6a8cae2a4c6d",
"approvedBy": "sam@acmebikes.com",
"approvedAt": "2026-10-01T14:03:00.000Z",
"changes": [
{
"url": "https://acmebikes.com/products/city-glide-7",
"field": "seo_description",
"value": "City Glide 7: a comfortable seven-speed city bike with mudguards and a rack.",
"status": "applied",
"appliedAt": "2026-10-01T14:03:41.000Z",
"live": true,
"liveValue": "City Glide 7: a comfortable seven-speed city bike with mudguards and a rack.",
"notLiveReason": null,
"liveNote": null,
"error": null
}
]
}
}{
"error": {
"code": "bad_paging",
"message": "suggestionsLimit must be a whole number from 1 to 100."
}
}{
"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": "Issue not found."
}
}{
"error": {
"code": "rate_limited",
"message": "More than 1200 requests this hour for this key."
}
}Der MCP-Server macht dasselbe mit dem Tool issue_detail.