Lists the measurements of one keyword on an engine, country and device, newest first, paginated by cursor (limit up to 365): organic position (null = the domain was not in the top 30), absolute position, ranking URL and title, SERP features present, total results and when it was measured; source says whether it was measured by a check or imported. Without engine, country_code and device, the project's first engine, country and device are used. It also reads a combination the project no longer measures (retired_combos in seo_rankings.projects.get): that is its saved history, not today's positions. A position past 30 (an imported one) shows as null. The history is kept forever.
Scope
seo_rankings:read
Permission
View the module
MCP tool
seo_rankings_history_getOn the full surface; on the compact one, mb_execute_operation with id: "seo_rankings.history.get".
Declared cost: up to 368 reads and 0 writes per call (they count against the daily quota).
Parameters
keyword_idstringpathrequired
Keyword id (from seo_rankings.keywords.list).
engineenumqueryoptional
Default: the first engine of the keyword's project.
Values: google, bing
country_codestringqueryoptional
Default: the country of the project's first engine.
deviceenumqueryoptional
Default: the project's first device.
Values: desktop, mobile
limitintegerqueryoptional
How many measurements, newest first (default 90, up to 365).
Default: 90
cursorstringqueryoptional
The next_cursor of the previous page, exactly as it came (same keyword and filters); without it, the newest measurements.
Returns the keywords × dates grid of a project on one engine, country and device (default: the project's first ones; a combination the project no longer measures, listed in retired_combos of seo_rankings.projects.get, can be read too: its saved history, not today's positions). dates lists the check dates (ms, the UTC day at 00:00; newest first): the newest date_limit ones (up to 365; by default the dates that fit in about 250 cells, keywords × dates: 10 with up to 25 keywords, 2 with 100), or, with from, every date from the UTC day of from on (date_limit still caps them, 365 by default, keeping the newest: when the cap cuts, the dates closest to from are the ones left out, without truncated, so ask again with to before the oldest date returned); to (epoch ms, inclusive) ends the window at the UTC day of to, so an older stretch can be read on its own. grid maps each keyword id to its cell per date: position (null = not in the top 30), delta against the previous date shown (null on the oldest one), the ranking URL when there was one, checked_at (the exact time of that measurement, in ms: the newest of that UTC day) and check_id (its id, as in seo_rankings.history.get). Measurements of different engines or countries are separate grids, and the ones of the same collection pass share the same checked_at: check_id is a stable tie-breaker. All keywords of the project are included, active and inactive; a keyword without a cell on a date was not measured that day, and keywords maps each keyword id of grid to its text, so the grid reads on its own. A position past 30 (an imported one) shows as null, like every position outside the top 30. Keyword ids and dates are data keys and are returned as they are. Cost: one read per measurement of the dates returned, plus a short look-ahead without from; one call reads at most 12000 measurements (the declared cost): past that, truncated is true and the oldest dates are left out (every date returned is complete), so ask again with to before the oldest date returned. 400 invalid_range when from is after to; 404 rank_project_not_found. Requires view access to Rankings.
Scope
seo_rankings:read
Permission
View the module
MCP tool
seo_rankings_history_gridOn the full surface; on the compact one, mb_execute_operation with id: "seo_rankings.history.grid".
Declared cost: up to 12000 reads and 0 writes per call (they count against the daily quota).
Parameters
project_idstringpathrequired
Rank project id (from seo_rankings.projects.list).
engineenumqueryoptional
Default: the project's first engine.
Values: google, bing
country_codestringqueryoptional
Default: the country of the project's first engine.
deviceenumqueryoptional
Default: the project's first device.
Values: desktop, mobile
date_limitintegerqueryoptional
How many check dates (columns), newest first, up to 365. Default: the dates that fit in about 250 cells (keywords × dates: 10 with up to 25 keywords, 2 with 100), at least one; with from, every date since from (365 at most).
fromintegerqueryoptional
Only check dates on or after the UTC day of this moment (epoch ms, inclusive).
tointegerqueryoptional
Only check dates on or before the UTC day of this moment (epoch ms, inclusive).
include_keywordsbooleanqueryoptional
true (default) adds keywords, the text of each keyword of the grid (one read per keyword, inside the declared cost); false skips it when you already have them from seo_rankings.keywords.list.
Response
project_idstring
enginestring
country_codestring
devicestring
datesarray<number>
Check dates (ms, the UTC day), newest first: the columns of the grid.
gridobject
keyword id → { date (ms, as in dates) → cell }. A missing cell = not measured that day; position null = measured, not in the top 30.
keywordsobject
keyword id → keyword text, for every keyword in grid (so the grid reads on its own).
truncatedboolean
true = the read ceiling cut the grid: the oldest dates of the window are missing (every date given is complete); ask for them with to.