Start an audit
POST
/sites/{siteId}/audits- Scope
audits:run- MCP tool
start_audit
Start a full audit The same as the Run audit button: one crawl per website at a time, and at most 3 audits per website in 24 hours through the API and MCP. Answers at once; poll GET /sites/{siteId}/audits/{auditId}.
Parameters
| Name | In | Details |
|---|---|---|
siteIdRequired | path | stringWebsite id, from GET /sites. |
Request body
| Field | Details |
|---|---|
pageBudget | integer · min 1; Most pages to crawl: at least 50 (or the plan limit when lower), at most the plan's pages per audit. Default: the website's audit budget, capped at that limit. A bigger budget than the website's own gets a longer time limit (at most 120 minutes). |
{
"pageBudget": 500
}Response
202 · application/json
| Field | Details |
|---|---|
queued | true or false · required; Always true |
auditId | string · required; Id to poll |
status | queued | running | done | failed | cancelled · required; queued |
pageBudget | integer · required; Most pages it crawls |
timeLimitMinutes | integer · required; Time limit, in minutes |
cappedByPlan | true or false · required; True when the plan's limit lowered the budget |
planLimit | integer · required; The plan's pages per audit |
startsLeftToday | integer · required; API and MCP starts left in the 24 hours |
poll | string · required; Where to poll its status |
link | string · required; The Audit screen in the app |
note | string · required; What happens next |
Notes
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
| Status | Meaning |
|---|---|
400 | Bad request. Codes: bad_page_budget, over_plan_limit. |
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. |
409 | Conflict with the current state. Codes: already_running. |
429 | A limit is reached. rate_limited: too many requests this hour for this key. Codes: rate_limited, too_many_audits. |
Example request
curl -X POST \
-H "Authorization: Bearer mr_ws_…" \
-H "Content-Type: application/json" \
-d '{"pageBudget":500}' \
"https://app.monoranks.com/api/v1/sites/SITE_ID/audits"const res = await fetch("https://app.monoranks.com/api/v1/sites/SITE_ID/audits", {
method: "POST",
headers: { Authorization: "Bearer mr_ws_…", "Content-Type": "application/json" },
body: JSON.stringify({
"pageBudget": 500
}),
});
if (!res.ok) throw new Error((await res.json()).error.message);
const data = await res.json();import requests
res = requests.post(
"https://app.monoranks.com/api/v1/sites/SITE_ID/audits",
headers={"Authorization": "Bearer mr_ws_…"},
json={
"pageBudget": 500,
},
)
res.raise_for_status()
data = res.json()<?php
$ch = curl_init("https://app.monoranks.com/api/v1/sites/SITE_ID/audits");
curl_setopt_array($ch, [
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_HTTPHEADER => ["Authorization: Bearer mr_ws_…", "Content-Type: application/json"],
CURLOPT_POSTFIELDS => '{"pageBudget":500}',
CURLOPT_RETURNTRANSFER => true,
]);
$data = json_decode(curl_exec($ch), true);import axios from "axios";
const { data } = await axios.post(
"https://app.monoranks.com/api/v1/sites/SITE_ID/audits",
{
"pageBudget": 500
},
{ headers: { Authorization: "Bearer mr_ws_…" } },
);Example response
{
"queued": true,
"auditId": "d4f6a8c0-2e4a-4c6e-8a0c-4e6a8c0e2a4b",
"status": "queued",
"pageBudget": 500,
"timeLimitMinutes": 30,
"cappedByPlan": false,
"planLimit": 500,
"startsLeftToday": 2,
"poll": "https://app.monoranks.com/api/v1/sites/3f6c2a1e-8b4d-4c7a-9e21-5d0b7a6f4c13/audits/d4f6a8c0-2e4a-4c6e-8a0c-4e6a8c0e2a4b",
"link": "https://app.monoranks.com/sites/3f6c2a1e-8b4d-4c7a-9e21-5d0b7a6f4c13/audit",
"note": "Queued: a full audit crawls the website, then rebuilds issues, scores and the llms.txt draft."
}{
"error": {
"code": "bad_page_budget",
"message": "pageBudget must be at least 50."
}
}{
"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": "already_running",
"message": "An audit of this website is already running (id d4f6a8c0-2e4a-4c6e-8a0c-4e6a8c0e2a4b); one crawl runs at a time.",
"auditId": "d4f6a8c0-2e4a-4c6e-8a0c-4e6a8c0e2a4b",
"kind": "audit",
"status": "running",
"poll": "https://app.monoranks.com/api/v1/sites/3f6c2a1e-8b4d-4c7a-9e21-5d0b7a6f4c13/audits/d4f6a8c0-2e4a-4c6e-8a0c-4e6a8c0e2a4b"
}
}{
"error": {
"code": "rate_limited",
"message": "More than 1200 requests this hour for this key."
}
}The MCP server does the same with the tool start_audit.