MisarMisar Docs
MisarMailMisarBlogMisarReachMisarPostMisarDevMisarCoderMisarSEOMisar PlatformMisar SSO
API Reference

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

POST/seo/crawl/start

Queues a crawl and returns immediately with a job id.

Request body

projectIdstringbodyrequired

The project this audit belongs to.

startUrlstringbodyrequired

Where the crawl begins. Must be an absolute http: or https: URL.

maxPagesnumberbody

Page ceiling for the crawl. Values above 5000 are rejected.

strategystringbody

One of auto, all, manual, none.

Response fields

jobIdstring

Identifier for status and stream calls.

auditIdstring

The audit record id. Currently identical to jobId.

Request
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"
  }'
202 — Accepted
{
  "jobId": "aud_7f3e1b90",
  "auditId": "aud_7f3e1b90"
}
403 — Blocked target
{ "error": "Crawl target is not permitted", "code": "CRAWL_TARGET_BLOCKED" }

Rate limit: 5 requests per 60 s.

Status codes

CodeMeaning
202Crawl queued
400VALIDATION_ERROR — invalid JSON, missing projectId or startUrl, unparseable URL, non-HTTP scheme, or maxPages above 5000
401UNAUTHENTICATED
403CRAWL_TARGET_BLOCKED — the target is not permitted
404NOT_FOUND — project not found
429AUDIT_CAPACITY_REACHED or RATE_LIMITED

Poll status

GET/seo/crawl/:jobId/status

A 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

jobIdstringpathrequired

The job id from POST /seo/crawl/start.

Query parameters

projectIdstringqueryrequired

Owning project. Required — omitting it returns 400.

Response fields

statusobject

The current audit status record.

Request
curl "https://api.misar.io/seo/crawl/aud_7f3e1b90/status?projectId=5b1c7d2e-…" \
  -H "Authorization: Bearer $MISARSEO_API_KEY"

Stream progress

GET/seo/crawl/:jobId/stream

Server-Sent Events for a running crawl.

Path parameters

jobIdstringpathrequired

The job id.

Query parameters

projectIdstringqueryrequired

Owning project.

Response headers

Content-Type: text/event-stream; charset=utf-8
Cache-Control: no-cache, no-transform
Connection: keep-alive
X-Accel-Buffering: no
Request
curl -N "https://api.misar.io/seo/crawl/aud_7f3e1b90/stream?projectId=5b1c7d2e-…" \
  -H "Authorization: Bearer $MISARSEO_API_KEY" \
  -H "Accept: text/event-stream"
Wire format
: ping

event: progress
data: {"status":"crawling"}

event: complete
data: {"status":"done"}

Rate limit: 10 requests per 60 s.

Events

EventMeaning
progressEmitted as the crawl advances. The underlying record is polled roughly every 1.5 s.
completeTerminal success. Carries the final status.
errorTerminal 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

CodeMeaning
200Stream opened
400projectId missing
401UNAUTHENTICATED
404NOT_FOUNDProject not found or Audit not found
429RATE_LIMITED

Start

POST /seo/crawl/start202 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.