agentsvc.io

services / accessibility-check

weboperational · 2 ms

Accessibility Check (WCAG, BFSG, EAA)

Automated web accessibility audit of a page in a real browser with axe-core: every WCAG 2.2 level A and AA rule that can be tested automatically (missing alt text, unlabeled buttons and form fields, color contrast, keyboard traps, ARIA errors, missing page language, touch target size). Returns a grade A to F, violations sorted by impact (critical, serious, moderate, minor) with the WCAG criteria, number of affected elements, example selectors and HTML, and a fix hint, plus whether the page links an accessibility statement. For the EU Accessibility Act (EAA), the German BFSG (in force since 28 June 2025) and Austrian BaFG, which build on EN 301 549 and WCAG 2.1 AA. Option mobile for a 390 px phone viewport. Automated rules catch about a third of barriers; this is a screening, not a certification and not legal advice. Not charged when the page cannot be loaded.

Run free trial ↗3 free calls per day with the example input. Paid: $0.015 USDC, no limit.

Call it

import { wrapFetchWithPayment, x402Client } from "@x402/fetch";
import { registerExactEvmScheme } from "@x402/evm/exact/client";
import { privateKeyToAccount } from "viem/accounts";

const client = new x402Client();
registerExactEvmScheme(client, { signer: privateKeyToAccount(process.env.EVM_PRIVATE_KEY) });
const payFetch = wrapFetchWithPayment(fetch, client);

const res = await payFetch("https://agentsvc.io/api/v1/proxy/accessibility-check", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({"url":"https://www.openstreetmap.org"}),
});
const { data, payment } = await res.json();  // payment.status "settling"; header X-Payment-Settle: sync returns payment.transaction

Input

FieldTypeDescription
url *stringPage to audit, e.g. https://example.com
mobileboolean = falseAudit at phone width (390x844) instead of desktop (1280x800)

Output

FieldTypeDescription
urlstring
standardstring
viewportstring
gradestring
scoreinteger
langstring
violation_typesinteger
affected_elementsobject
violationsarray
needs_manual_reviewinteger
accessibility_statementobject
key_factsarray
notestring
enginestring
checked_atstring

Example response (data)

{
  "url": "https://www.openstreetmap.org/#map=6/51.33/10.45",
  "standard": "WCAG 2.2 level A and AA rules that can be tested automatically (axe-core). EN 301 549, the standard behind the EU Accessibility Act and the German BFSG, builds on WCAG 2.1 AA.",
  "viewport": "desktop 1280x800",
  "grade": "B",
  "score": 77,
  "lang": "de",
  "violation_types": 2,
  "affected_elements": {
    "critical": 1,
    "serious": 1,
    "moderate": 0,
    "minor": 0
  },
  "violations": [
    {
      "rule": "button-name",
      "impact": "critical",
      "problem": "Buttons must have discernible text",
      "wcag": [
        "wcag2a",
        "wcag412"
      ],
      "elements": 1,
      "how_to_fix": "https://dequeuniversity.com/rules/axe/4.14/button-name?application=axeAPI",
      "examples": [
        {
          "target": ".dropdown-toggle-split",
          "html": "<button class=\"btn btn-outline-primary dropdown-toggle dropdown-toggle-split flex-grow-0\" type=\"button\" data-bs-toggle=\"dropdown\"></button>",
          "fix": "Fix any of the following:\n  Element does not have inner text that is visible to screen readers\n  aria-label attribute does not exist or is empty\n  aria-labelledby attribute does not exist, references elements that do not exist or references elements that are empty\n  Element has no title attribute\n  "
        }
      ]
    },
    {
      "rule": "target-size",
      "impact": "serious",
      "problem": "All touch targets must be 24px large, or leave sufficient space",
      "wcag": [
        "wcag22aa",
        "wcag258"
      ],
      "elements": 1,
      "how_to_fix": "https://dequeuniversity.com/rules/axe/4.14/target-size?application=axeAPI",
      "examples": [
        {
          "target": ".search_forms.d-md-block.d-none > .search_form[action=\"/search\"] > .gap-2.d-flex > .input-group.flex-nowrap > .input-group-text.border-start-0.p-0 > .describe_l",
          "html": "<button name=\"button\" type=\"button\" class=\"describe_location position-absolute end-0 m-1 btn btn-outline-primary border-0 p-1 text-primary link-body-emphasis link-opacity-100-hover\" title=\"Die momenta",
          "fix": "Fix any of the following:\n  Target has insufficient size (67.5px by 23px, should be at least 24px by 24px)\n  Target has insufficient space to its closest neighbors. Safe clickable space has a diameter of 23px instead of at least 24px."
        }
      ]
    }
  ],
  "needs_manual_review": 3,
  "accessibility_statement": {
    "found": false,
    "url": null,
    "text": null
  },
  "key_facts": [
    "2 kinds of WCAG A/AA violation on https://www.openstreetmap.org/#map=6/51.33/10.45, 1 critical and 1 serious element(s). Grade B.",
    "critical: Buttons must have discernible text (1 element).",
    "serious: All touch targets must be 24px large, or leave sufficient space (1 element).",
    "No accessibility statement linked on this page (required for services under the EU Accessibility Act / BFSG)."
  ],
  "note": "Automated tests find roughly a third of accessibility barriers. A clean result does not prove conformance; keyboard use, screen reader flow and content need a manual review. Not legal advice.",
  "engine": "axe-core 4.14.0 (MPL-2.0)",
  "checked_at": "2026-10-10T06:57:23.496Z"
}