Site Audit
Start a crawl, poll its status, and stream live progress over SSE — /seo/crawl/start, /seo/crawl/:jobId/status, /seo/crawl/:jobId/stream.
Site audits crawl a domain and report technical SEO issues. Crawls are asynchronous: start one, then either poll or subscribe to the event stream.
Start a crawl
/seo/crawl/startQueues a crawl and returns immediately with a job id.
Request body
projectIdstringbodyrequiredThe project this audit belongs to.
startUrlstringbodyrequiredWhere the crawl begins. Must be an absolute http: or https: URL.
maxPagesnumberbodyPage ceiling for the crawl. Values above 5000 are rejected.
strategystringbodyOne of auto, all, manual, none.
Response fields
jobIdstringIdentifier for status and stream calls.
auditIdstringThe audit record id. Currently identical to jobId.
curl -X POST https://api.misar.io/seo/crawl/start \
-H "Authorization: Bearer $MISARSEO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"projectId": "5b1c7d2e-…",
"startUrl": "https://acme.com",
"maxPages": 500,
"strategy": "auto"
}'{
"jobId": "aud_7f3e1b90",
"auditId": "aud_7f3e1b90"
}{ "error": "Crawl target is not permitted", "code": "CRAWL_TARGET_BLOCKED" }Rate limit: 5 requests per 60 s.
Status codes
| Code | Meaning |
|---|---|
202 | Crawl queued |
400 | VALIDATION_ERROR — invalid JSON, missing projectId or startUrl, unparseable URL, non-HTTP scheme, or maxPages above 5000 |
401 | UNAUTHENTICATED |
403 | CRAWL_TARGET_BLOCKED — the target is not permitted |
404 | NOT_FOUND — project not found |
429 | AUDIT_CAPACITY_REACHED or RATE_LIMITED |
Poll status
/seo/crawl/:jobId/statusA cheap point-in-time read. Not rate limited, so it is safe to poll — though the stream is preferable for a live UI.
Path parameters
jobIdstringpathrequiredThe job id from POST /seo/crawl/start.
Query parameters
projectIdstringqueryrequiredOwning project. Required — omitting it returns 400.
Response fields
statusobjectThe current audit status record.
curl "https://api.misar.io/seo/crawl/aud_7f3e1b90/status?projectId=5b1c7d2e-…" \
-H "Authorization: Bearer $MISARSEO_API_KEY"Stream progress
/seo/crawl/:jobId/streamServer-Sent Events for a running crawl.
Path parameters
jobIdstringpathrequiredThe job id.
Query parameters
projectIdstringqueryrequiredOwning project.
Response headers
Content-Type: text/event-stream; charset=utf-8
Cache-Control: no-cache, no-transform
Connection: keep-alive
X-Accel-Buffering: nocurl -N "https://api.misar.io/seo/crawl/aud_7f3e1b90/stream?projectId=5b1c7d2e-…" \
-H "Authorization: Bearer $MISARSEO_API_KEY" \
-H "Accept: text/event-stream": ping
event: progress
data: {"status":"crawling"}
event: complete
data: {"status":"done"}Rate limit: 10 requests per 60 s.
Events
| Event | Meaning |
|---|---|
progress | Emitted as the crawl advances. The underlying record is polled roughly every 1.5 s. |
complete | Terminal success. Carries the final status. |
error | Terminal failure. The payload carries a code — TIMEOUT, LOOKUP_FAILED, or CRAWL_FAILED. |
Keep-alive and hard timeout
The stream emits a : ping comment every 15 seconds so intermediaries do not close an idle connection, and it terminates after a hard 10-minute ceiling regardless of crawl state. A crawl longer than that must be followed with the status endpoint.
Status codes
| Code | Meaning |
|---|---|
200 | Stream opened |
400 | projectId missing |
401 | UNAUTHENTICATED |
404 | NOT_FOUND — Project not found or Audit not found |
429 | RATE_LIMITED |
Recommended flow
Start
POST /seo/crawl/start → 202 with a jobId.
Watch
Open GET /seo/crawl/:jobId/stream for a live UI, or poll GET /seo/crawl/:jobId/status from a worker.
Handle the ceiling
If the stream closes on the 10-minute timeout without a terminal event, fall back to polling the status endpoint.