REST API

One base URL, one bearer key, JSON in and out. Everything the app shows for a website is available here.

Base URL and authentication

https://app.monoranks.com/api/v1
Authorization: Bearer mr_ws_… (or mr_site_…)

Machine-readable description of every endpoint and webhook event: https://app.monoranks.com/api/v1/openapi.json (OpenAPI 3.1). Paste it into Postman, Insomnia, Bruno or a client generator.

Make a workspace key in the app under Settings → API and MCP → New credential. It covers every website, or only the ones you tick. A website key (mr_site_…) is made when the WordPress plugin or the Shopify app connects, and covers one website. Keys are shown once. See API keys and scopes.

Endpoints

All paths below start with the base URL.

Websites and scores

Method and path What it returns Scope
GET /sites Websites this key can read, with their ids sites:read
GET /portfolio Every website the key covers in one call, like the Websites list: scores, change since the last audit and last week, open issues, waiting actions, last audit, next audit, and Search Console clicks (with search:read) sites:read
GET /sites/{siteId} Summary: scores, last audit, open issues, WordPress access, and how fresh each connection’s data is sites:read
GET /sites/{siteId}/scores Current score and 13 weeks of history with score versions sites:read
GET /sites/{siteId}/performance Speed per tested page: the lab test next to real-visitor data from Chrome users, and which of the two each speed finding uses sites:read

Issues and actions

Method and path What it returns Scope
GET /sites/{siteId}/issues Issues, the same list as the Issues screen (default: open, reopened, in progress, recheck queued; status= takes a comma-separated list) issues:read
GET /sites/{siteId}/issues/{issueId} One issue with affected pages, evidence, the AI explanation, the suggested new values and the last approved change issues:read
POST /sites/{siteId}/issues/{issueId}/recheck Queue a recheck; the issue is resolved only when the recheck no longer finds it issues:recheck
GET /sites/{siteId}/actions Actions ordered by priority, with the estimated score gain and how long each has been open (limit, default 25, at most 100) issues:read
POST /sites/{siteId}/actions/{issueId}/apply Approve new SEO titles, descriptions, canonicals or noindex and write them through the WordPress connector actions:apply

Pages

Method and path What it returns Scope
GET /sites/{siteId}/pages Crawled pages (q to search, page, per up to 200) pages:read
GET /sites/{siteId}/pages/{pageId} Page facts, scores and findings pages:read
GET /sites/{siteId}/pages/findings?url= Same, looked up by address pages:read

Search Console

Method and path What it returns Scope
GET /sites/{siteId}/search/summary Totals for 7, 28 or 90 days (days=) against the period before, top pages and queries search:read
GET /sites/{siteId}/search/rows Rows for a date range, by query, page, query and page, or day; paged, or as one CSV file with format=csv search:read

AI visibility and AI readiness

Method and path What it returns Scope
GET /sites/{siteId}/ai-visibility What AI assistants answered to the website’s tracked questions, per week ai:read
GET /sites/{siteId}/ai-visibility/gaps Questions where AI answers name other websites but never this one ai:read
GET /sites/{siteId}/geo AI crawler access in robots.txt, llms.txt and entity signals from the last audit ai:read
GET /sites/{siteId}/geo/llms-txt The live /llms.txt, read now, and a ready-to-publish draft built from your pages ai:read
POST /sites/{siteId}/geo/llms-txt Approve a new /llms.txt and write it through the WordPress connector actions:apply
GET /sites/{siteId}/geo/ai-crawlers What robots.txt, read now, says to each AI crawler, and the rules MonoRanks last wrote ai:read
POST /sites/{siteId}/geo/ai-crawlers Approve allow or deny rules per AI crawler and write them into robots.txt actions:apply
GET /sites/{siteId}/agentic Agentic browsing results (can an AI agent use the page), per tested page and device, with what to fix ai:read
POST /sites/{siteId}/agentic/run Re-run the Agentic browsing check for one page; answers 202 with a job id issues:recheck
GET /sites/{siteId}/agentic/runs/{jobId} The status and result of one re-run ai:read

Audits

Method and path What it returns Scope
GET /sites/{siteId}/audits The latest audits, the one running now, the next weekly audit, the page budgets and the starts left today sites:read
POST /sites/{siteId}/audits Start a full audit now, with an optional pageBudget; answers 202 with an audit id audits:run
GET /sites/{siteId}/audits/{auditId} One audit: status, pages crawled so far, sitemap coverage, why it stopped early sites:read

Public, no key

Method and path What it returns
GET /openapi.json The OpenAPI 3.1 document for all of the above
GET /plans Plans and prices
GET /changelog Release notes as Markdown

Paging

Each list pages its own way, and the OpenAPI document gives the details:

  • GET /portfolio, GET /sites/{siteId}/pages and GET /sites/{siteId}/agentic take page (from 1) and per (default 50, at most 200).
  • GET /sites/{siteId}/search/rows returns nextCursor; send it back as cursor until it is null. limit is 1 to 10,000 (default 1,000).
  • Suggestions on an issue come 100 at a time; see below.
  • GET /sites/{siteId}/actions takes limit; GET /sites/{siteId}/audits takes limit (default 5, at most 25).

Suggested values on an issue

For an issue MonoRanks can fix (SEO title, meta description, canonical or redirect), GET /sites/{siteId}/issues/{issueId} also returns suggestions: for each affected page, the current value and the value MonoRanks suggests. These are the same values the app shows before you press Apply.

"suggestions": [
  { "url": "https://example.com/pricing/", "pageId": "…", "current": "Pricing", "suggested": "Pricing | Example", "writable": true }
],
"suggestionsTotal": 240,
"suggestionsOffset": 0,
"suggestionsLimit": 100,
"suggestionsNextOffset": 100,
"suggestionsTruncated": true
  • Paging. Each call returns up to 100. For the next ones, call again with ?suggestions_offset= set to suggestionsNextOffset; it is null after the last page. suggestions_limit (1 to 100) sets the page size. The spellings suggestionsOffset and suggestionsLimit work too.
  • suggested is null when MonoRanks has no good new value for that page. A title that is too long is shortened by fixed rules that keep the page’s topic and never cut a phrase in half; when no shorter title works, suggested is null and you can draft one in the app.
  • suggestionsNote (titles only) is set when the website changes the letter case of titles on the page, for example Rank Math’s Capitalize Titles setting.
  • writable is false, with notWritableReason, when apply cannot write that page, for example a category archive that is not a WordPress post or page. Do not send those to apply.
  • advice (meta descriptions only) says when a page may not need a description: a legal page or an archive (leave it empty or set noindex), an empty archive (add posts or set noindex), or a login, account, cart or checkout page (set noindex; no description is suggested).
  • titleTemplate (titles that are too long) is set when one shared ending from the SEO plugin’s title template makes most titles too long, so one change to the template fixes them all.
  • lastRecheck says what the last recheck found. A recheck reads every listed page again, fresh, so pages you already fixed leave the list. A page that did not answer stays listed and is counted in lastRecheck.notRechecked.
  • lastChange is the last approved batch, with each change’s status. not_live means it was written but the page still shows another value; notLiveReason says why, including whether the website’s page cache was cleared after the write. A recheck looks at such changes again. Titles and descriptions count as live when only the letter case, spaces, quotes or dashes differ; liveNote then says what changed them.

Send the values you approve to POST /sites/{siteId}/actions/{issueId}/apply as { "changes": [ { "url": "…", "value": "…" } ] } (at most 500). Through the API, apply writes SEO titles, meta descriptions, canonicals and noindex; image alt text and redirects are applied in the app.

Personal email addresses in the page text MonoRanks stores are hidden, for example j•••@gmail.com.

Example

curl -H "Authorization: Bearer mr_ws_…" \
  "https://app.monoranks.com/api/v1/sites/SITE_ID/actions?limit=5"
{
  "waiting": 1,
  "actions": [
    { "rank": 1, "issueId": "…", "title": "Missing meta description", "severity": "serious", "effort": "low",
      "priority": 8.4, "estimatedScoreGain": 3.2, "status": "open", "ageDays": 16, "waitingWeeks": 2,
      "writableField": "seo_description", "link": "https://app.monoranks.com/sites/SITE_ID/actions/…" }
  ]
}

Start an audit

curl -X POST -H "Authorization: Bearer mr_ws_…" -H "Content-Type: application/json" \
  -d '{ "pageBudget": 1000 }' "https://app.monoranks.com/api/v1/sites/SITE_ID/audits"

The call answers 202 at once with an auditId and a poll address; follow it with GET /sites/{siteId}/audits/{auditId} about once a minute. pageBudget is optional and can be at most your plan’s pages per audit: Free 200, Starter 500, Agency 1,000, Enterprise 10,000. Only one crawl runs per website at a time, and at most 3 audits per website a day can be started through the API and MCP. The weekly audit runs as usual.

Errors and limits

Errors are { "error": { "code": "…", "message": "…" } }:

Status Meaning
400 a bad parameter or body, for example a bad date range, a page budget above the plan, or a page that cannot be written
401 key missing, unknown or revoked
403 scope missing, website not covered by the key, or the key’s owner lost access
404 no such website, issue, page, audit or route
409 something is already queued or running (a recheck, an audit, the same Agentic browsing run), or the website has no WordPress connector that can write
429 hourly limit reached (1,200 requests per key per hour), the daily speed test budget is used up, or 3 audits were already started today
503 the API or this feature is switched off for now

A key acts as the person who created it. If that person leaves the workspace or becomes a client viewer, the key stops working.

Common questions

Is there an SDK?

Not yet. The OpenAPI document at /api/v1/openapi.json works with the usual generators (openapi-generator, Kiota, oazapfts) if you want typed clients.

Can I write data through the API?

A few writes exist, each behind its own scope: queue a recheck or re-run the Agentic browsing check (issues:recheck), start a full audit (audits:run), and approve new SEO titles, descriptions, canonicals, an llms.txt file or AI crawler rules that MonoRanks then writes through the WordPress connector (actions:apply). Every approved write can be undone in the app for 30 days. Everything else is read-only.

What about the public endpoints?

GET /api/v1/plans and GET /api/v1/changelog need no key; the website uses them to show prices and release notes.