---
title: "Scan a page or site for WCAG issues"
method: POST
path: "/scan"
---

# Scan a page or site for WCAG issues

`POST /scan`

## Request

- Base URL: `https://api.lazynext.com`
- URL: `https://api.lazynext.com/scan`
- Auth: none declared

Provide `url` (public http/https page — rendered via headless browser at a mobile 390×844 viewport by default; `viewport: "desktop"` opts out) or raw `html` (static rules only). `site: true` crawls same-origin pages — 3 pages free, 10 Pro. Free URL scans consume the 3/day/IP quota; `html` scans do not. A Pro `license` email unlocks higher limits, deeper crawls, and `email_report`.

## Request body

- ScanRequest
  - `url` string, uri: Public http/https page. Rendered via headless browser; consumes daily quota.
  - `html` string: Raw markup to scan statically (≤512KB, no quota).
  - `site` boolean: Crawl same-origin pages (3 free / 10 Pro) and add cross-page checks.
  - `license` string, email: Pro purchase email — higher limits, deeper crawls, monitoring.
  - `email_report` boolean: Pro only: email the report to the license address.
  - `viewport` 'mobile' | 'desktop': Rendered-scan viewport profile — mobile emulates a 390×844 handset (touch + mobile UA, the default); desktop keeps the pre-mobile baseline render. Ignored for `html` scans and site crawls.

## Response `200`

OK

- ScanResult
  - `score` number, required
  - `score_model` 'weighted-v1': Scoring model version — weighted-v1 sums findings weighted by WCAG level and detection confidence (warn-class heuristics count half), repeat instances of the same rule at half marginal weight. Level-A confirmed failures still weigh 1.0.
  - `issues` Issue[], required
    - `rule` string: Emitted rule id — `wcag-N.N.N`, `sec508-*`, or `bp-*` (best practice, not a numbered criterion)
    - `level` 'A' | 'AA' | 'AAA' | 'BP'
    - `message` string
    - `url` string: Per-page attribution on site scans
    - `recommendation` string: Fix guidance joined from the ruleset
  - `rendered` boolean, required: true when the headless-browser path ran (false = static fallback)
  - `viewport` 'mobile' | 'desktop': Viewport the render ran at — present only when rendered: true
  - `plan` 'free' | 'pro', required
  - `report` string, uri: Shareable report URL (30-day TTL)
  - `render_error` string: Present when rendering failed and the static fallback ran
  - `site` boolean
  - `pages` object[]: Per-page rollups for site scans
    - `url` string
    - `score` number
    - `count` number
  - `section508` Section508: 36 CFR 1194 clause mapping derived from the WCAG findings
    - `basis` string, required: Incorporation basis — 508 defines no web test rules of its own; E205.4 incorporates WCAG 2.0 AA by reference
    - `conforms` boolean, required: true when no WCAG criterion fired
    - `criteria_failed` string[], required: Sorted `wcag-*` rule ids that fired
    - `clauses_implicated` string[], required: Chapter 3 Functional Performance Criteria (302.x) the failures map onto — the language a VPAT/procurement review cites
    - `clause_count` number, required
  - `benchmark` object: Percentile vs the public scan corpus — present once ≥10 distinct sites are on record
    - `pct` number
    - `sites` number

## Other responses

- `400`: Provide `{"url"}` or `{"html"}`
- `402`: Free limit reached (3/day) — `upgrade` points at /checkout
- `413`: `html` larger than 512KB
- `429`: Daily scan quota exceeded (Pro IP or license ceiling)
- `502`: Page fetch/crawl failed — `detail` carries the reason

---

[API](https://skmtc.dev/lazynext/apis/lazynext-accessibility-checker-api.md) · [All operations](https://skmtc.dev/lazynext/apis/lazynext-accessibility-checker-api/llms.txt) · [OpenAPI document](https://skmtc.dev/lazynext/apis/lazynext-accessibility-checker-api/revisions/b7e06b008177?raw)
