Find page history by address
GET
/sites/{siteId}/pages/history- Scope
pages:read- MCP tool
page_history
What changed on a page, by URL.
Parameters
| Name | In | Details |
|---|---|---|
siteIdRequired | path | stringWebsite id, from GET /sites. |
urlRequired | query | stringThe page address, exactly as crawled. |
limit | query | integerdefault 30, min 1, max 100Entries to return, 1 to 100. |
Response
200 · application/json
| Field | Details |
|---|---|
page | object · required |
page.id | string · required; Page id |
page.url | string · required; Page address |
entries | list of values · required; Newest first |
entries[].crawlId | string |
entries[].at | string |
entries[].kind | string |
entries[].status | number |
entries[].redirectHops | number |
entries[].pageScore | number |
entries[].aeoScore | number |
entries[].wordCount | number |
entries[].title | string |
entries[].first | true or false |
entries[].noSnapshot | true or false |
entries[].changes | list of objects |
entries[].changes[].field | string |
entries[].changes[].before | string |
entries[].changes[].after | string |
more | true or false · required; Older entries exist |
note | string · required; How the entries are compared |
link | string · required; The page history in the app |
Notes
GET /sites/{siteId}/pages/{pageId}/history (or GET /sites/{siteId}/pages/history?url=) says what changed on one page from one audit or recheck to the next, newest first. It uses what MonoRanks stored when it read the page; nothing is crawled for it. The app shows the same timeline on the page’s detail screen.
{
"page": { "id": "…", "url": "https://example.com/pricing/" },
"entries": [
{ "crawlId": "…", "at": "2026-10-01T09:12:00Z", "kind": "recheck", "status": 200, "redirectHops": 0, "pageScore": 86, "aeoScore": 71,
"wordCount": 912, "title": "Pricing – Example", "first": false, "noSnapshot": false,
"changes": [ { "field": "title", "before": "Pricing", "after": "Pricing – Example" }, { "field": "pageScore", "before": 78, "after": 86 } ] }
],
"more": true, "note": "…", "link": "https://app.monoranks.com/sites/SITE_ID/pages/PAGE_ID#history"
}
| What | Details |
|---|---|
| What is compared | field is one of status, redirect, title, description, h1, headings (number of H2 headings), canonical, noindex, robots, wordCount, schemaTypes, internalLinks, pageScore and aeoScore. An empty changes list means nothing changed. |
| Small moves are not changes | Word count must move by at least 10 words and 5%. Spacing in titles and the order of schema types are ignored. |
| Outages | noSnapshot is true when the reading had no readable HTML. That entry shows only the status change, and the next reading is compared with the last one that had readable HTML. |
| How far back | Readings are kept for 12 months; first marks the oldest one kept. Rechecks and page scores are stored from version 1.0.92 on, so older entries have pageScore and aeoScore set to null. |
Errors
| Status | Meaning |
|---|---|
400 | Bad request. Codes: bad_limit, missing_page. |
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. |
Example request
curl \
-H "Authorization: Bearer mr_ws_…" \
"https://app.monoranks.com/api/v1/sites/SITE_ID/pages/history?url=https%3A%2F%2Fexample.com%2Fpricing%2F"const res = await fetch("https://app.monoranks.com/api/v1/sites/SITE_ID/pages/history?url=https%3A%2F%2Fexample.com%2Fpricing%2F", {
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/pages/history?url=https%3A%2F%2Fexample.com%2Fpricing%2F",
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/pages/history?url=https%3A%2F%2Fexample.com%2Fpricing%2F");
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/pages/history?url=https%3A%2F%2Fexample.com%2Fpricing%2F", { headers: { Authorization: "Bearer mr_ws_…" } });Example response
{
"page": {
"id": "c7a9e1b3-5d7f-4b9c-8e1a-3c5e7a9b1d2f",
"url": "https://acmebikes.com/products/trail-pro-29"
},
"entries": [
{
"crawlId": "d4f6a8c0-2e4a-4c6e-8a0c-4e6a8c0e2a4b",
"at": "2026-10-04T02:41:12.000Z",
"kind": "audit",
"status": 200,
"redirectHops": 0,
"pageScore": 86,
"aeoScore": 71,
"wordCount": 842,
"title": "Trail Pro 29 Mountain Bike | Acme Bikes",
"first": false,
"noSnapshot": false,
"changes": [
{
"field": "title",
"before": "Trail Pro 29 | Acme Bikes",
"after": "Trail Pro 29 Mountain Bike | Acme Bikes"
},
{
"field": "pageScore",
"before": 79,
"after": 86
}
]
},
{
"crawlId": "e5a7c9e1-3f5b-4d7f-9b1d-5f7b9d1f3b5c",
"at": "2026-09-27T02:38:51.000Z",
"kind": "audit",
"status": 200,
"redirectHops": 0,
"pageScore": 79,
"aeoScore": 71,
"wordCount": 836,
"title": "Trail Pro 29 | Acme Bikes",
"first": true,
"noSnapshot": false,
"changes": []
}
],
"more": false,
"note": "One entry per audit or recheck that read this page, newest first.",
"link": "https://app.monoranks.com/sites/3f6c2a1e-8b4d-4c7a-9e21-5d0b7a6f4c13/pages/c7a9e1b3-5d7f-4b9c-8e1a-3c5e7a9b1d2f#history"
}{
"error": {
"code": "bad_limit",
"message": "limit 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": "Page not found."
}
}{
"error": {
"code": "rate_limited",
"message": "More than 1200 requests this hour for this key."
}
}The MCP server does the same with the tool page_history.