Accessibility Checker API

Audit a URL or HTML for WCAG 2.2 A / AA issues with axe-core: missing alt text, labels, link and button names, ARIA errors, headings and more.

GETPOSThttps://apibox.io.vn/v1/a11y-check

Send html (page source) or a public url. The page is parsed into a DOM without a browser and checked with the axe-core rule engine (Deque, MPL-2.0) for the chosen WCAG level (a, aa default, aaa) plus best practices: image alt text, form labels, link and button names, document title and language, heading order, landmarks, lists, tables, ARIA roles and attribute values, duplicate ARIA ids, autocomplete values, zoom blocking in the viewport meta tag, iframes titles and more.

Each violation has the rule id, impact (critical, serious, moderate, minor), WCAG success criteria (e.g. 1.1.1), a help link, and up to max_nodes offending elements with their CSS selector, HTML snippet and what to fix. score (0-100) summarises the result; needs_review lists checks axe could not decide.

Rules that need a rendered page (colour contrast, target size, inline spacing, scrollable regions, focus order) are not run and are listed in not_checked; content added by JavaScript is not seen. Automated checks find only part of the WCAG issues, so also test manually. HTML is limited to 3 MB.

Parameters

NameInTypeRequiredDefault
urlbody|querystringnoPublic page to fetch (HTML up to 3 MB). Use html instead for pages behind a login.
htmlbodystringnoPage source to check (or send it as a text/html body).
levelbody|querystringnoaaWCAG level: a, aa or aaa.
best_practicesbody|querybooleannotrueInclude axe best-practice rules (heading order, landmarks, empty headings…).
max_nodesbody|querynumberno10Offending elements returned per rule (1-100).
include_passesbody|querybooleannofalseAlso list the rules that passed.
experimentalbody|querybooleannofalseInclude axe experimental rules.

Example

curl -X POST "https://apibox.io.vn/v1/a11y-check" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"html":"<!doctype html><html><head><title>Shop</title></head><body><img src=\"logo.png\"><a href=\"/cart\"></a><form><input type=\"email\" placeholder=\"Email\"><button></button></form></body></html>"}'

Response

{
  "source": "html",
  "url": null,
  "level": "AA",
  "score": 75,
  "issues": 8,
  "by_impact": {
    "critical": 2,
    "serious": 2,
    "moderate": 4,
    "minor": 0
  },
  "rules": {
    "checked": 83,
    "failed": 7,
    "needs_review": 1,
    "not_checked": 8
  },
  "violations": [
    {
      "rule": "button-name",
      "impact": "critical",
      "level": "A",
      "wcag": [
        "4.1.2"
      ],
      "best_practice": false,
      "help": "Buttons must have discernible text",
      "description": "Ensure buttons have discernible text",
      "help_url": "https://dequeuniversity.com/rules/axe/4.14/button-name?application=axeAPI",
      "count": 1,
      "nodes": [
        {
          "target": "button",
          "html": "<button></button>",
          "failure": "Element does not have inner text that is visible to screen readers | aria-label attribute does not exist or is empty | …"
        }
      ]
    },
    {
      "rule": "image-alt",
      "impact": "critical",
      "level": "A",
      "wcag": [
        "1.1.1"
      ],
      "best_practice": false,
      "help": "Images must have alternative text",
      "description": "Ensure <img> elements have alternative text or a role of none or presentation",
      "help_url": "https://dequeuniversity.com/rules/axe/4.14/image-alt?application=axeAPI",
      "count": 1,
      "nodes": [
        {
          "target": "img",
          "html": "<img src=\"logo.png\">",
          "failure": "Element does not have an alt attribute | …"
        }
      ]
    },
    "…"
  ],
  "needs_review": [
    {
      "rule": "bypass",
      "impact": "serious",
      "help": "Page must have means to bypass repeated blocks",
      "wcag": [
        "2.4.1"
      ],
      "…": "…"
    }
  ],
  "not_checked": [
    {
      "rule": "avoid-inline-spacing",
      "wcag": [
        "1.4.12"
      ],
      "reason": "needs the CSS object model"
    },
    {
      "rule": "color-contrast",
      "wcag": [
        "1.4.3"
      ],
      "reason": "needs rendered colours and layout"
    },
    "…"
  ],
  "engine": "axe-core 4.14.0 (static DOM, no layout)",
  "ms": 34,
  "note": "Static check without a browser: colour contrast, target size, focus order and anything that depends on CSS layout or scripts are not tested. …"
}

Use cases

  • Check pages before launch for the European Accessibility Act or public-sector rules
  • Add an accessibility gate to CI for static sites and templates
  • Find images without alt text and unlabeled form fields across a site
  • Produce a WCAG issue list for a client audit

FAQ

Is this the same as running axe in a browser?

It runs the same axe-core rules on a static DOM. Rules that need layout or computed colours (colour contrast, target size) cannot run and are listed in not_checked; content rendered by JavaScript is not included.

Which WCAG version is checked?

WCAG 2.0, 2.1 and 2.2 rules up to the level you choose (A, AA by default, or AAA), plus axe best-practice rules unless best_practices=false.

How is the score calculated?

It starts at 100 and subtracts a weight for each failing rule by impact (critical 10, serious 6, moderate 3, minor 1) relative to the number of rules checked. Use it to track progress, not as a compliance certificate.

Related APIs

Start with 1,000 free requests every month. Get free API key →