docs / endpoint

POST /v1/site/audit

Crawl and audit a whole site; billed per delivered page (sum of enabled checks x pages delivered).

Credits: 2 credits per delivered page per enabled check -- billed on what's actually delivered, never a flat rate. Timeout: 600s

Parameters

NameTypeRequiredDefaultDescription
domain string required Domain or URL to crawl -- the hostname is extracted from either form. Required, max 253 chars.
max_pages integer required Maximum number of pages to crawl before stopping. 1-500.
checks array optional ["crawl"] Which checks to run per crawled page. Optional, default ["crawl"]. Duplicates removed, order preserved. Array of: crawl, lighthouse, accessibility.
device string optional "mobile" One of: mobile, desktop. Optional, default "mobile".

Request

→ requestPOST /v1/site/audit
POST /v1/site/audit HTTP/1.1
Authorization: Bearer sof_live_your_key_here
Content-Type: application/json

{
  "domain": "example.com",
  "max_pages": 5,
  "checks": [
    "crawl",
    "lighthouse"
  ],
  "device": "mobile"
}

Response

Wrapped in the standard envelope -- id, object, created_at, elapsed_ms, cache, credits -- documented once on The Contract. The body below is a real envelope with this endpoint's data shape; values vary per request, and a marks an array cut short for display.

← response200
{
  "id": "site_5sunoif4ajelb7hud3biu4dd",
  "request_id": "req_6wkqmjzhgbdmfhhqer7roiz2re",
  "object": "site_audit",
  "created_at": "2026-08-09T07:21:20Z",
  "elapsed_ms": 180,
  "cache": "miss",
  "credits": {
    "charged": 12,
    "balance": 9857
  },
  "data": {
    "domain": "example.com",
    "pages_requested": 5,
    "pages_crawled": 4,
    "pages_delivered": 3,
    "credits_charged": 12,
    "pages": [
      {
        "url": "https://example.com/",
        "status": "ok",
        "crawl": {
          "http_status": 200,
          "links": {
            "internal": 2,
            "external": 0
          }
        },
        "lighthouse": {
          "device": "mobile",
          "scores": {
            "performance": 90,
            "accessibility": 91,
            "best_practices": 93,
            "seo": 80
          }
        }
      },
      "…"
    ],
    "summary": {
      "score": {
        "value": 82,
        "band": "excellent",
        "grade": "A"
      },
      "axes": [
        {
          "key": "speed",
          "score": 73,
          "band": "good"
        }
      ],
      "issues": {
        "critical": 2,
        "major": 1,
        "minor": 1
      },
      "broken_links": 1,
      "pages_with_errors": 1
    }
  }
}

Response fields

What each field in data (above) means.

FieldDescription
data.domain The resolved hostname that was crawled.
data.pages_requested max_pages from the request, echoed back.
data.pages_crawled Number of pages the crawl actually visited (can be less than pages_requested on a smaller site, never more).
data.pages_delivered Number of pages that passed every enabled check -- the billing unit.
data.credits_charged Actual credits charged for this call: pages_delivered times the enabled checks' per-page cost -- 0 on a replay, since a replay is never re-billed. Always equal to the envelope's own credits.charged.
data.pages One row per crawled page, whether delivered or not.
data.pages[].url The page URL.
data.pages[].status "ok" if every enabled check passed for this page, "error" otherwise -- an error page isn't billed.
data.pages[].crawl This page's crawl-check result, when the crawl check is enabled and passed -- same shape as the page/crawl endpoint's data.
data.pages[].crawl.http_status HTTP status code for this page.
data.pages[].crawl.links Outbound link counts for this page.
data.pages[].crawl.links.internal Links pointing at the same site.
data.pages[].crawl.links.external Links pointing off-site.
data.pages[].lighthouse This page's lighthouse-check result, when the lighthouse check is enabled and passed -- same scores/metrics shape as the page/lighthouse endpoint's data, but without that endpoint's audits/screenshots (kept lean per-page so a multi-page site audit doesn't balloon).
data.pages[].lighthouse.device Device profile the audit ran under.
data.pages[].lighthouse.scores The same four 0-100 category scores as the standalone lighthouse endpoint.
data.summary Site-wide rollup computed across every delivered page.
data.summary.score Overall site score.
data.summary.score.value 0-100 overall score.
data.summary.score.band "excellent" (80+), "good" (50+), or "improve" (below 50).
data.summary.score.grade Letter grade A-F derived from value.
data.summary.axes Per-dimension scores (speed, accessibility) for whichever checks were enabled.
data.summary.axes[].key Which dimension this axis measures, e.g. "speed".
data.summary.axes[].score 0-100 score for this axis.
data.summary.axes[].band Same excellent/good/improve banding as score.band, for this axis.
data.summary.issues Accessibility issues found, bucketed by severity (only populated when the accessibility check is enabled).
data.summary.issues.critical Count of critical-severity issues.
data.summary.issues.major Count of major-severity issues.
data.summary.issues.minor Count of minor-severity issues.
data.summary.broken_links Count of internal links returning a non-2xx status, across delivered pages.
data.summary.pages_with_errors Count of pages that failed to load cleanly or failed the crawl check.