{"openapi":"3.1.0","info":{"title":"Accessibility Intelligence API","version":"1.0.0","description":"Check supplied HTML or one public page for images, headings, forms, links, language, keyboard signals, ARIA, and inline colour contrast. The result is not a WCAG conformance claim. Paid with x402 exact USDC on Base. No account is required.","contact":{"email":"support@brainiac.software"},"x-guidance":"BRAINIAC.software is a pay-per-call API for software agents. No account or API key is required.\nPayment uses the x402 protocol with exact USDC on Base (chain id 8453). Each POST operation has a fixed USD price.\nHow to call an operation:\n1. POST a JSON body matching the operation's requestBody schema to the operation path. Include an Idempotency-Key header (64 hex characters, 32 random bytes).\n2. If you have not paid, the server responds 402 with payment requirements in the body. Pay the exact amount to the payTo address on Base.\n3. Retry the identical request with the same Idempotency-Key and add a payment-signature header containing the x402 payment payload. On success (200) the operation result is returned.\n4. Reuse the same Idempotency-Key only for retries of the same operation and request body; it will not be charged twice.\nAll outputs are compliance prechecks, drafts, or data lookups for human review. They are not official determinations, legal advice, identity confirmation, or certified filings. Verify time-sensitive or official data with the cited source before acting."},"servers":[{"url":"https://www.brainiac.software"}],"paths":{"/api/v1/accessibility/html-audit":{"post":{"operationId":"audit_html_accessibility","summary":"Audit HTML accessibility","description":"Run the static image, heading, form, link, language, keyboard, ARIA, and inline-contrast checks. The result is not a WCAG conformance claim.","tags":["accessibility"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"url":{"type":"string","minLength":8,"maxLength":2000,"pattern":"^https?:\\/\\/\\S+$"},"html":{"type":"string","minLength":1,"maxLength":200000}},"additionalProperties":false},"example":{"html":"<html><body><img src=\"hero.png\"><h1>Welcome</h1><h3>Details</h3><form><input type=\"text\" name=\"email\" placeholder=\"Email\"></form><a href=\"/next\">click here</a><div role=\"button\"></div><p style=\"color:#ffffff;background-color:#ffffff\">White</p></body></html>"}}}},"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"Fresh random 32-byte value encoded as 64 hexadecimal characters. Reuse unchanged only for retries of the same operation and request.","schema":{"type":"string","pattern":"^[0-9a-fA-F]{64}$"}}],"responses":{"200":{"description":"Illustrative endpoint-specific JSON response shape. Conditional fields depend on the result and data-source availability.","content":{"application/json":{"schema":{"type":"object","properties":{"checkedAt":{"type":"string"},"wcagCompliance":{"type":"boolean"},"status":{"type":"string"},"source":{"type":"string"},"url":{"type":"string"},"warnings":{"type":"array","items":{}},"counts":{"type":"object","properties":{"confirmed":{"type":"number"},"potential":{"type":"number"},"manual":{"type":"number"}},"additionalProperties":true},"issues":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string"},"code":{"type":"string"},"element":{"type":"string"},"explanation":{"type":"string"},"remediation":{"type":"string"}},"additionalProperties":true}},"limitations":{"type":"array","items":{"type":"string"}}},"additionalProperties":true},"example":{"checkedAt":"2026-11-02T19:00:00.000Z","wcagCompliance":false,"status":"checked","source":"html","url":"","warnings":[],"counts":{"confirmed":6,"potential":1,"manual":8},"issues":[{"kind":"confirmed","code":"alt_missing","element":"img[src=\"hero.png\"]","explanation":"This element has no alt attribute.","remediation":"Add an alt attribute. Use an empty alt only when the image is decorative."},{"kind":"manual","code":"css_images_not_checked","element":"document","explanation":"Images painted by CSS backgrounds were not checked.","remediation":"Check CSS background images in a browser when they convey information."},{"kind":"confirmed","code":"heading_level_skipped","element":"h3","explanation":"This h3 follows h1, so a heading level was skipped.","remediation":"Use the next heading level, or change the heading that came before it."},{"kind":"manual","code":"visual_headings_not_checked","element":"document","explanation":"Text that only looks like a heading was not checked.","remediation":"Use a heading element when text is a heading."},{"kind":"confirmed","code":"control_unlabelled","element":"input[name=\"email\"]","explanation":"This control has a placeholder and no label. A placeholder disappears while typing.","remediation":"Add a label element, an aria-label, or an aria-labelledby reference that exists in the HTML."},{"kind":"manual","code":"form_errors_not_checked","element":"document","explanation":"Error messages and custom widgets were not tested in a browser.","remediation":"Confirm that errors are named and announced when the form is submitted."},{"kind":"potential","code":"link_generic","element":"a[href=\"/next\"]","explanation":"The link text \"click here\" does not name its destination.","remediation":"Use text that says where the link goes."},{"kind":"manual","code":"link_context_not_checked","element":"document","explanation":"Link purpose was judged from the link text only, not from the surrounding sentence.","remediation":"Review a generic link in its sentence when the text is repeated."},{"kind":"confirmed","code":"language_missing","element":"html","explanation":"The page has no lang attribute on the html element.","remediation":"Add a lang attribute, such as lang=\"en\", that matches the page language."},{"kind":"manual","code":"language_not_compared","element":"document","explanation":"The page text was not checked for its human language.","remediation":"Confirm that the lang value matches the language people read on the page."},{"kind":"manual","code":"keyboard_not_operated","element":"document","explanation":"No key was pressed. Focus order and keyboard operation were not tested in a browser.","remediation":"Tab through the page and confirm every action works without a pointer."},{"kind":"confirmed","code":"aria_widget_unnamed","element":"div","explanation":"This button has no accessible name.","remediation":"Add text, an aria-label, or an aria-labelledby reference that exists."},{"kind":"manual","code":"aria_runtime_not_checked","element":"document","explanation":"ARIA states that scripts change were not tested in a browser.","remediation":"Operate the widget and confirm the announced name and state."},{"kind":"confirmed","code":"contrast_below_threshold","element":"p","explanation":"The contrast ratio is 1:1 from the colours on this element. It is below 3:1, the AA threshold used for large text.","remediation":"Change one of the colours so normal text reaches 4.5:1 and large text reaches 3:1."},{"kind":"manual","code":"stylesheet_contrast_not_checked","element":"document","explanation":"Stylesheet, inherited, and user-agent colours were not calculated.","remediation":"Check those pairs in a browser. A passing inline pair does not make the page conform."}],"limitations":["This is a static HTML check. It is not a WCAG conformance claim.","JavaScript is not run, so states that appear only after interaction are not seen.","Contrast is calculated only when both colours are written on the same element.","Checks marked manual need a browser or a person. They are not failures."]}}}},"400":{"description":"Invalid JSON or request schema."},"402":{"description":"Payment Required"},"409":{"description":"Idempotency conflict, in-progress payment, or expired result cache. Reusing the key cannot trigger a second charge."},"413":{"description":"Request body exceeds the 24 MB limit."},"500":{"description":"Operation failed. With upfront settlement this may occur after payment; reuse the same idempotency key to retrieve the stored result."},"503":{"description":"Payment or retry-safe result storage is unavailable; the operation is not run."}},"x-payment-info":{"price":{"mode":"fixed","currency":"USD","amount":"0.05"},"protocols":[{"x402":{}}]}}},"/api/v1/accessibility/image-alt-text-audit":{"post":{"operationId":"audit_image_alt_text","summary":"Audit image alt text","description":"Flag images, image inputs, and areas with no alt attribute. An empty alt is reported as a manual check, not as a confirmed failure.","tags":["accessibility"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"url":{"type":"string","minLength":8,"maxLength":2000,"pattern":"^https?:\\/\\/\\S+$"},"html":{"type":"string","minLength":1,"maxLength":200000}},"additionalProperties":false},"example":{"html":"<html lang=\"en\"><body><img src=\"hero.png\"><img src=\"icon.png\" alt=\"\"><img alt=\"photo.jpg\" src=\"a.jpg\"></body></html>"}}}},"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"Fresh random 32-byte value encoded as 64 hexadecimal characters. Reuse unchanged only for retries of the same operation and request.","schema":{"type":"string","pattern":"^[0-9a-fA-F]{64}$"}}],"responses":{"200":{"description":"Illustrative endpoint-specific JSON response shape. Conditional fields depend on the result and data-source availability.","content":{"application/json":{"schema":{"type":"object","properties":{"checkedAt":{"type":"string"},"wcagCompliance":{"type":"boolean"},"status":{"type":"string"},"source":{"type":"string"},"url":{"type":"string"},"warnings":{"type":"array","items":{}},"issues":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string"},"code":{"type":"string"},"element":{"type":"string"},"explanation":{"type":"string"},"remediation":{"type":"string"}},"additionalProperties":true}},"limitations":{"type":"array","items":{"type":"string"}}},"additionalProperties":true},"example":{"checkedAt":"2026-11-02T19:00:00.000Z","wcagCompliance":false,"status":"checked","source":"html","url":"","warnings":[],"issues":[{"kind":"confirmed","code":"alt_missing","element":"img[src=\"hero.png\"]","explanation":"This element has no alt attribute.","remediation":"Add an alt attribute. Use an empty alt only when the image is decorative."},{"kind":"manual","code":"alt_empty","element":"img[src=\"icon.png\"]","explanation":"The empty alt marks this image as decorative. That intent was not confirmed.","remediation":"Keep the empty alt only when the image adds no information."},{"kind":"potential","code":"alt_generic","element":"img[src=\"a.jpg\"]","explanation":"The alt text \"photo.jpg\" looks like a filename or a placeholder.","remediation":"Replace it with the information the image conveys."},{"kind":"manual","code":"css_images_not_checked","element":"document","explanation":"Images painted by CSS backgrounds were not checked.","remediation":"Check CSS background images in a browser when they convey information."}],"limitations":["This is a static HTML check. It is not a WCAG conformance claim.","JavaScript is not run, so states that appear only after interaction are not seen.","Contrast is calculated only when both colours are written on the same element.","Checks marked manual need a browser or a person. They are not failures."]}}}},"400":{"description":"Invalid JSON or request schema."},"402":{"description":"Payment Required"},"409":{"description":"Idempotency conflict, in-progress payment, or expired result cache. Reusing the key cannot trigger a second charge."},"413":{"description":"Request body exceeds the 24 MB limit."},"500":{"description":"Operation failed. With upfront settlement this may occur after payment; reuse the same idempotency key to retrieve the stored result."},"503":{"description":"Payment or retry-safe result storage is unavailable; the operation is not run."}},"x-payment-info":{"price":{"mode":"fixed","currency":"USD","amount":"0.03"},"protocols":[{"x402":{}}]}}},"/api/v1/accessibility/heading-structure-audit":{"post":{"operationId":"audit_heading_structure","summary":"Audit heading structure","description":"Read heading elements in source order and flag empty headings and skipped levels. A missing h1 is a potential issue, not a confirmed failure.","tags":["accessibility"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"url":{"type":"string","minLength":8,"maxLength":2000,"pattern":"^https?:\\/\\/\\S+$"},"html":{"type":"string","minLength":1,"maxLength":200000}},"additionalProperties":false},"example":{"html":"<html lang=\"en\"><body><h1>Welcome</h1><h3>Details</h3><h2></h2></body></html>"}}}},"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"Fresh random 32-byte value encoded as 64 hexadecimal characters. Reuse unchanged only for retries of the same operation and request.","schema":{"type":"string","pattern":"^[0-9a-fA-F]{64}$"}}],"responses":{"200":{"description":"Illustrative endpoint-specific JSON response shape. Conditional fields depend on the result and data-source availability.","content":{"application/json":{"schema":{"type":"object","properties":{"checkedAt":{"type":"string"},"wcagCompliance":{"type":"boolean"},"status":{"type":"string"},"source":{"type":"string"},"url":{"type":"string"},"warnings":{"type":"array","items":{}},"headings":{"type":"array","items":{"type":"object","properties":{"level":{"type":"number"},"text":{"type":"string"},"element":{"type":"string"}},"additionalProperties":true}},"issues":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string"},"code":{"type":"string"},"element":{"type":"string"},"explanation":{"type":"string"},"remediation":{"type":"string"}},"additionalProperties":true}},"limitations":{"type":"array","items":{"type":"string"}}},"additionalProperties":true},"example":{"checkedAt":"2026-11-02T19:00:00.000Z","wcagCompliance":false,"status":"checked","source":"html","url":"","warnings":[],"headings":[{"level":1,"text":"Welcome","element":"h1"},{"level":3,"text":"Details","element":"h3"},{"level":2,"text":"","element":"h2"}],"issues":[{"kind":"confirmed","code":"heading_level_skipped","element":"h3","explanation":"This h3 follows h1, so a heading level was skipped.","remediation":"Use the next heading level, or change the heading that came before it."},{"kind":"confirmed","code":"heading_empty","element":"h2","explanation":"This heading has no text.","remediation":"Add the heading text, or remove the heading element."},{"kind":"manual","code":"visual_headings_not_checked","element":"document","explanation":"Text that only looks like a heading was not checked.","remediation":"Use a heading element when text is a heading."}],"limitations":["This is a static HTML check. It is not a WCAG conformance claim.","JavaScript is not run, so states that appear only after interaction are not seen.","Contrast is calculated only when both colours are written on the same element.","Checks marked manual need a browser or a person. They are not failures."]}}}},"400":{"description":"Invalid JSON or request schema."},"402":{"description":"Payment Required"},"409":{"description":"Idempotency conflict, in-progress payment, or expired result cache. Reusing the key cannot trigger a second charge."},"413":{"description":"Request body exceeds the 24 MB limit."},"500":{"description":"Operation failed. With upfront settlement this may occur after payment; reuse the same idempotency key to retrieve the stored result."},"503":{"description":"Payment or retry-safe result storage is unavailable; the operation is not run."}},"x-payment-info":{"price":{"mode":"fixed","currency":"USD","amount":"0.03"},"protocols":[{"x402":{}}]}}},"/api/v1/accessibility/form-audit":{"post":{"operationId":"audit_form_accessibility","summary":"Audit form accessibility","description":"Check that controls have a label, an aria-label, or a matching label element. A placeholder or title is not treated as a sufficient name.","tags":["accessibility"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"url":{"type":"string","minLength":8,"maxLength":2000,"pattern":"^https?:\\/\\/\\S+$"},"html":{"type":"string","minLength":1,"maxLength":200000}},"additionalProperties":false},"example":{"html":"<html lang=\"en\"><body><form><label for=\"missing\">Email</label><input type=\"text\" name=\"email\" placeholder=\"Email\"><button></button></form></body></html>"}}}},"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"Fresh random 32-byte value encoded as 64 hexadecimal characters. Reuse unchanged only for retries of the same operation and request.","schema":{"type":"string","pattern":"^[0-9a-fA-F]{64}$"}}],"responses":{"200":{"description":"Illustrative endpoint-specific JSON response shape. Conditional fields depend on the result and data-source availability.","content":{"application/json":{"schema":{"type":"object","properties":{"checkedAt":{"type":"string"},"wcagCompliance":{"type":"boolean"},"status":{"type":"string"},"source":{"type":"string"},"url":{"type":"string"},"warnings":{"type":"array","items":{}},"issues":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string"},"code":{"type":"string"},"element":{"type":"string"},"explanation":{"type":"string"},"remediation":{"type":"string"}},"additionalProperties":true}},"limitations":{"type":"array","items":{"type":"string"}}},"additionalProperties":true},"example":{"checkedAt":"2026-11-02T19:00:00.000Z","wcagCompliance":false,"status":"checked","source":"html","url":"","warnings":[],"issues":[{"kind":"confirmed","code":"label_for_missing","element":"label","explanation":"The label for \"missing\" does not match an id in this HTML.","remediation":"Point the label at the control id, or wrap the control in the label."},{"kind":"confirmed","code":"control_unlabelled","element":"input[name=\"email\"]","explanation":"This control has a placeholder and no label. A placeholder disappears while typing.","remediation":"Add a label element, an aria-label, or an aria-labelledby reference that exists in the HTML."},{"kind":"confirmed","code":"button_unnamed","element":"button","explanation":"This button has no accessible name.","remediation":"Add button text or an aria-label."},{"kind":"manual","code":"form_errors_not_checked","element":"document","explanation":"Error messages and custom widgets were not tested in a browser.","remediation":"Confirm that errors are named and announced when the form is submitted."}],"limitations":["This is a static HTML check. It is not a WCAG conformance claim.","JavaScript is not run, so states that appear only after interaction are not seen.","Contrast is calculated only when both colours are written on the same element.","Checks marked manual need a browser or a person. They are not failures."]}}}},"400":{"description":"Invalid JSON or request schema."},"402":{"description":"Payment Required"},"409":{"description":"Idempotency conflict, in-progress payment, or expired result cache. Reusing the key cannot trigger a second charge."},"413":{"description":"Request body exceeds the 24 MB limit."},"500":{"description":"Operation failed. With upfront settlement this may occur after payment; reuse the same idempotency key to retrieve the stored result."},"503":{"description":"Payment or retry-safe result storage is unavailable; the operation is not run."}},"x-payment-info":{"price":{"mode":"fixed","currency":"USD","amount":"0.04"},"protocols":[{"x402":{}}]}}},"/api/v1/accessibility/link-audit":{"post":{"operationId":"audit_link_accessibility","summary":"Audit link accessibility","description":"Flag links with no accessible name. Generic text such as click here is a potential issue because the surrounding sentence was not judged.","tags":["accessibility"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"url":{"type":"string","minLength":8,"maxLength":2000,"pattern":"^https?:\\/\\/\\S+$"},"html":{"type":"string","minLength":1,"maxLength":200000}},"additionalProperties":false},"example":{"html":"<html lang=\"en\"><body><a href=\"/next\">click here</a><a href=\"/empty\"></a></body></html>"}}}},"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"Fresh random 32-byte value encoded as 64 hexadecimal characters. Reuse unchanged only for retries of the same operation and request.","schema":{"type":"string","pattern":"^[0-9a-fA-F]{64}$"}}],"responses":{"200":{"description":"Illustrative endpoint-specific JSON response shape. Conditional fields depend on the result and data-source availability.","content":{"application/json":{"schema":{"type":"object","properties":{"checkedAt":{"type":"string"},"wcagCompliance":{"type":"boolean"},"status":{"type":"string"},"source":{"type":"string"},"url":{"type":"string"},"warnings":{"type":"array","items":{}},"issues":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string"},"code":{"type":"string"},"element":{"type":"string"},"explanation":{"type":"string"},"remediation":{"type":"string"}},"additionalProperties":true}},"limitations":{"type":"array","items":{"type":"string"}}},"additionalProperties":true},"example":{"checkedAt":"2026-11-02T19:00:00.000Z","wcagCompliance":false,"status":"checked","source":"html","url":"","warnings":[],"issues":[{"kind":"potential","code":"link_generic","element":"a[href=\"/next\"]","explanation":"The link text \"click here\" does not name its destination.","remediation":"Use text that says where the link goes."},{"kind":"confirmed","code":"link_unnamed","element":"a[href=\"/empty\"]","explanation":"This link has no accessible name.","remediation":"Add link text, an image alt, or an aria-label."},{"kind":"manual","code":"link_context_not_checked","element":"document","explanation":"Link purpose was judged from the link text only, not from the surrounding sentence.","remediation":"Review a generic link in its sentence when the text is repeated."}],"limitations":["This is a static HTML check. It is not a WCAG conformance claim.","JavaScript is not run, so states that appear only after interaction are not seen.","Contrast is calculated only when both colours are written on the same element.","Checks marked manual need a browser or a person. They are not failures."]}}}},"400":{"description":"Invalid JSON or request schema."},"402":{"description":"Payment Required"},"409":{"description":"Idempotency conflict, in-progress payment, or expired result cache. Reusing the key cannot trigger a second charge."},"413":{"description":"Request body exceeds the 24 MB limit."},"500":{"description":"Operation failed. With upfront settlement this may occur after payment; reuse the same idempotency key to retrieve the stored result."},"503":{"description":"Payment or retry-safe result storage is unavailable; the operation is not run."}},"x-payment-info":{"price":{"mode":"fixed","currency":"USD","amount":"0.03"},"protocols":[{"x402":{}}]}}},"/api/v1/accessibility/document-language-check":{"post":{"operationId":"check_document_language","summary":"Check document language","description":"Read the lang attribute on the html element. The page text is not compared with that value, and a fragment without html is not marked as a failure.","tags":["accessibility"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"url":{"type":"string","minLength":8,"maxLength":2000,"pattern":"^https?:\\/\\/\\S+$"},"html":{"type":"string","minLength":1,"maxLength":200000}},"additionalProperties":false},"example":{"html":"<html><body><p>Hello</p></body></html>"}}}},"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"Fresh random 32-byte value encoded as 64 hexadecimal characters. Reuse unchanged only for retries of the same operation and request.","schema":{"type":"string","pattern":"^[0-9a-fA-F]{64}$"}}],"responses":{"200":{"description":"Illustrative endpoint-specific JSON response shape. Conditional fields depend on the result and data-source availability.","content":{"application/json":{"schema":{"type":"object","properties":{"checkedAt":{"type":"string"},"wcagCompliance":{"type":"boolean"},"status":{"type":"string"},"source":{"type":"string"},"url":{"type":"string"},"warnings":{"type":"array","items":{}},"language":{"type":"string"},"languageStatus":{"type":"string"},"issues":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string"},"code":{"type":"string"},"element":{"type":"string"},"explanation":{"type":"string"},"remediation":{"type":"string"}},"additionalProperties":true}},"limitations":{"type":"array","items":{"type":"string"}}},"additionalProperties":true},"example":{"checkedAt":"2026-11-02T19:00:00.000Z","wcagCompliance":false,"status":"checked","source":"html","url":"","warnings":[],"language":"","languageStatus":"missing","issues":[{"kind":"confirmed","code":"language_missing","element":"html","explanation":"The page has no lang attribute on the html element.","remediation":"Add a lang attribute, such as lang=\"en\", that matches the page language."},{"kind":"manual","code":"language_not_compared","element":"document","explanation":"The page text was not checked for its human language.","remediation":"Confirm that the lang value matches the language people read on the page."}],"limitations":["This is a static HTML check. It is not a WCAG conformance claim.","JavaScript is not run, so states that appear only after interaction are not seen.","Contrast is calculated only when both colours are written on the same element.","Checks marked manual need a browser or a person. They are not failures."]}}}},"400":{"description":"Invalid JSON or request schema."},"402":{"description":"Payment Required"},"409":{"description":"Idempotency conflict, in-progress payment, or expired result cache. Reusing the key cannot trigger a second charge."},"413":{"description":"Request body exceeds the 24 MB limit."},"500":{"description":"Operation failed. With upfront settlement this may occur after payment; reuse the same idempotency key to retrieve the stored result."},"503":{"description":"Payment or retry-safe result storage is unavailable; the operation is not run."}},"x-payment-info":{"price":{"mode":"fixed","currency":"USD","amount":"0.02"},"protocols":[{"x402":{}}]}}},"/api/v1/accessibility/keyboard-signals":{"post":{"operationId":"check_keyboard_signals","summary":"Check keyboard signals","description":"Flag a positive tabindex and an onclick on a non-control. Keys are not pressed, so keyboard operation stays a manual check.","tags":["accessibility"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"url":{"type":"string","minLength":8,"maxLength":2000,"pattern":"^https?:\\/\\/\\S+$"},"html":{"type":"string","minLength":1,"maxLength":200000}},"additionalProperties":false},"example":{"html":"<html lang=\"en\"><body><div onclick=\"go()\"></div><button tabindex=\"2\">Save</button></body></html>"}}}},"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"Fresh random 32-byte value encoded as 64 hexadecimal characters. Reuse unchanged only for retries of the same operation and request.","schema":{"type":"string","pattern":"^[0-9a-fA-F]{64}$"}}],"responses":{"200":{"description":"Illustrative endpoint-specific JSON response shape. Conditional fields depend on the result and data-source availability.","content":{"application/json":{"schema":{"type":"object","properties":{"checkedAt":{"type":"string"},"wcagCompliance":{"type":"boolean"},"status":{"type":"string"},"source":{"type":"string"},"url":{"type":"string"},"warnings":{"type":"array","items":{}},"issues":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string"},"code":{"type":"string"},"element":{"type":"string"},"explanation":{"type":"string"},"remediation":{"type":"string"}},"additionalProperties":true}},"limitations":{"type":"array","items":{"type":"string"}}},"additionalProperties":true},"example":{"checkedAt":"2026-11-02T19:00:00.000Z","wcagCompliance":false,"status":"checked","source":"html","url":"","warnings":[],"issues":[{"kind":"confirmed","code":"click_without_keyboard","element":"div","explanation":"This element has an onclick attribute and is not a keyboard control.","remediation":"Use a button or link, or add a keyboard handler and a suitable role and tabindex."},{"kind":"confirmed","code":"tabindex_positive","element":"button","explanation":"tabindex=\"2\" puts this element in a custom tab order.","remediation":"Use tabindex=\"0\" or remove tabindex so the element stays in source order."},{"kind":"manual","code":"keyboard_not_operated","element":"document","explanation":"No key was pressed. Focus order and keyboard operation were not tested in a browser.","remediation":"Tab through the page and confirm every action works without a pointer."}],"limitations":["This is a static HTML check. It is not a WCAG conformance claim.","JavaScript is not run, so states that appear only after interaction are not seen.","Contrast is calculated only when both colours are written on the same element.","Checks marked manual need a browser or a person. They are not failures."]}}}},"400":{"description":"Invalid JSON or request schema."},"402":{"description":"Payment Required"},"409":{"description":"Idempotency conflict, in-progress payment, or expired result cache. Reusing the key cannot trigger a second charge."},"413":{"description":"Request body exceeds the 24 MB limit."},"500":{"description":"Operation failed. With upfront settlement this may occur after payment; reuse the same idempotency key to retrieve the stored result."},"503":{"description":"Payment or retry-safe result storage is unavailable; the operation is not run."}},"x-payment-info":{"price":{"mode":"fixed","currency":"USD","amount":"0.04"},"protocols":[{"x402":{}}]}}},"/api/v1/accessibility/aria-attribute-audit":{"post":{"operationId":"audit_aria_attributes","summary":"Audit ARIA attributes","description":"Check roles, boolean ARIA values, and references to ids that exist in this HTML. Runtime ARIA state changes are not tested.","tags":["accessibility"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"url":{"type":"string","minLength":8,"maxLength":2000,"pattern":"^https?:\\/\\/\\S+$"},"html":{"type":"string","minLength":1,"maxLength":200000}},"additionalProperties":false},"example":{"html":"<html lang=\"en\"><body><div role=\"button\"></div><input aria-labelledby=\"missing\"></body></html>"}}}},"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"Fresh random 32-byte value encoded as 64 hexadecimal characters. Reuse unchanged only for retries of the same operation and request.","schema":{"type":"string","pattern":"^[0-9a-fA-F]{64}$"}}],"responses":{"200":{"description":"Illustrative endpoint-specific JSON response shape. Conditional fields depend on the result and data-source availability.","content":{"application/json":{"schema":{"type":"object","properties":{"checkedAt":{"type":"string"},"wcagCompliance":{"type":"boolean"},"status":{"type":"string"},"source":{"type":"string"},"url":{"type":"string"},"warnings":{"type":"array","items":{}},"issues":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string"},"code":{"type":"string"},"element":{"type":"string"},"explanation":{"type":"string"},"remediation":{"type":"string"}},"additionalProperties":true}},"limitations":{"type":"array","items":{"type":"string"}}},"additionalProperties":true},"example":{"checkedAt":"2026-11-02T19:00:00.000Z","wcagCompliance":false,"status":"checked","source":"html","url":"","warnings":[],"issues":[{"kind":"confirmed","code":"aria_widget_unnamed","element":"div","explanation":"This button has no accessible name.","remediation":"Add text, an aria-label, or an aria-labelledby reference that exists."},{"kind":"confirmed","code":"aria_reference_missing","element":"input","explanation":"aria-labelledby points at missing, and that id is not in this HTML.","remediation":"Add the referenced element or correct the id."},{"kind":"manual","code":"aria_runtime_not_checked","element":"document","explanation":"ARIA states that scripts change were not tested in a browser.","remediation":"Operate the widget and confirm the announced name and state."}],"limitations":["This is a static HTML check. It is not a WCAG conformance claim.","JavaScript is not run, so states that appear only after interaction are not seen.","Contrast is calculated only when both colours are written on the same element.","Checks marked manual need a browser or a person. They are not failures."]}}}},"400":{"description":"Invalid JSON or request schema."},"402":{"description":"Payment Required"},"409":{"description":"Idempotency conflict, in-progress payment, or expired result cache. Reusing the key cannot trigger a second charge."},"413":{"description":"Request body exceeds the 24 MB limit."},"500":{"description":"Operation failed. With upfront settlement this may occur after payment; reuse the same idempotency key to retrieve the stored result."},"503":{"description":"Payment or retry-safe result storage is unavailable; the operation is not run."}},"x-payment-info":{"price":{"mode":"fixed","currency":"USD","amount":"0.04"},"protocols":[{"x402":{}}]}}},"/api/v1/accessibility/color-contrast-check":{"post":{"operationId":"check_inline_colour_contrast","summary":"Check inline colour contrast","description":"Calculate a contrast ratio only when both colours are opaque values on the same element. A single colour is not compared with an assumed background.","tags":["accessibility"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"url":{"type":"string","minLength":8,"maxLength":2000,"pattern":"^https?:\\/\\/\\S+$"},"html":{"type":"string","minLength":1,"maxLength":200000}},"additionalProperties":false},"example":{"html":"<html lang=\"en\"><body><p style=\"color:#ffffff;background-color:#ffffff\">White</p><p style=\"color:#767676\">Grey</p></body></html>"}}}},"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"Fresh random 32-byte value encoded as 64 hexadecimal characters. Reuse unchanged only for retries of the same operation and request.","schema":{"type":"string","pattern":"^[0-9a-fA-F]{64}$"}}],"responses":{"200":{"description":"Illustrative endpoint-specific JSON response shape. Conditional fields depend on the result and data-source availability.","content":{"application/json":{"schema":{"type":"object","properties":{"checkedAt":{"type":"string"},"wcagCompliance":{"type":"boolean"},"status":{"type":"string"},"source":{"type":"string"},"url":{"type":"string"},"warnings":{"type":"array","items":{}},"issues":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string"},"code":{"type":"string"},"element":{"type":"string"},"explanation":{"type":"string"},"remediation":{"type":"string"}},"additionalProperties":true}},"limitations":{"type":"array","items":{"type":"string"}}},"additionalProperties":true},"example":{"checkedAt":"2026-11-02T19:00:00.000Z","wcagCompliance":false,"status":"checked","source":"html","url":"","warnings":[],"issues":[{"kind":"confirmed","code":"contrast_below_threshold","element":"p","explanation":"The contrast ratio is 1:1 from the colours on this element. It is below 3:1, the AA threshold used for large text.","remediation":"Change one of the colours so normal text reaches 4.5:1 and large text reaches 3:1."},{"kind":"manual","code":"contrast_incomplete","element":"p","explanation":"Only one of the foreground and background colours is written on this element. The other colour was not guessed.","remediation":"Set both color and background-color on the element, or check the pair in a browser."},{"kind":"manual","code":"stylesheet_contrast_not_checked","element":"document","explanation":"Stylesheet, inherited, and user-agent colours were not calculated.","remediation":"Check those pairs in a browser. A passing inline pair does not make the page conform."}],"limitations":["This is a static HTML check. It is not a WCAG conformance claim.","JavaScript is not run, so states that appear only after interaction are not seen.","Contrast is calculated only when both colours are written on the same element.","Checks marked manual need a browser or a person. They are not failures."]}}}},"400":{"description":"Invalid JSON or request schema."},"402":{"description":"Payment Required"},"409":{"description":"Idempotency conflict, in-progress payment, or expired result cache. Reusing the key cannot trigger a second charge."},"413":{"description":"Request body exceeds the 24 MB limit."},"500":{"description":"Operation failed. With upfront settlement this may occur after payment; reuse the same idempotency key to retrieve the stored result."},"503":{"description":"Payment or retry-safe result storage is unavailable; the operation is not run."}},"x-payment-info":{"price":{"mode":"fixed","currency":"USD","amount":"0.04"},"protocols":[{"x402":{}}]}}},"/api/v1/accessibility/remediation-report":{"post":{"operationId":"report_accessibility_remediation","summary":"Report accessibility remediation","description":"Combine the static checks and list confirmed issues before potential issues and manual checks. The report does not claim WCAG conformance.","tags":["accessibility"],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"url":{"type":"string","minLength":8,"maxLength":2000,"pattern":"^https?:\\/\\/\\S+$"},"html":{"type":"string","minLength":1,"maxLength":200000}},"additionalProperties":false},"example":{"html":"<html><body><img src=\"hero.png\"><h1>Welcome</h1><h3>Details</h3><form><input type=\"text\" name=\"email\" placeholder=\"Email\"></form><a href=\"/next\">click here</a><div role=\"button\"></div><p style=\"color:#ffffff;background-color:#ffffff\">White</p></body></html>"}}}},"parameters":[{"name":"Idempotency-Key","in":"header","required":true,"description":"Fresh random 32-byte value encoded as 64 hexadecimal characters. Reuse unchanged only for retries of the same operation and request.","schema":{"type":"string","pattern":"^[0-9a-fA-F]{64}$"}}],"responses":{"200":{"description":"Illustrative endpoint-specific JSON response shape. Conditional fields depend on the result and data-source availability.","content":{"application/json":{"schema":{"type":"object","properties":{"checkedAt":{"type":"string"},"wcagCompliance":{"type":"boolean"},"status":{"type":"string"},"source":{"type":"string"},"url":{"type":"string"},"warnings":{"type":"array","items":{}},"summary":{"type":"string"},"counts":{"type":"object","properties":{"confirmed":{"type":"number"},"potential":{"type":"number"},"manual":{"type":"number"}},"additionalProperties":true},"issues":{"type":"array","items":{"type":"object","properties":{"kind":{"type":"string"},"code":{"type":"string"},"element":{"type":"string"},"explanation":{"type":"string"},"remediation":{"type":"string"}},"additionalProperties":true}},"limitations":{"type":"array","items":{"type":"string"}}},"additionalProperties":true},"example":{"checkedAt":"2026-11-02T19:00:00.000Z","wcagCompliance":false,"status":"checked","source":"html","url":"","warnings":[],"summary":"Static HTML checks found 6 confirmed issues, 1 potential issues, and 8 checks that need a browser or a person. This is not a WCAG conformance claim.","counts":{"confirmed":6,"potential":1,"manual":8},"issues":[{"kind":"confirmed","code":"alt_missing","element":"img[src=\"hero.png\"]","explanation":"This element has no alt attribute.","remediation":"Add an alt attribute. Use an empty alt only when the image is decorative."},{"kind":"confirmed","code":"heading_level_skipped","element":"h3","explanation":"This h3 follows h1, so a heading level was skipped.","remediation":"Use the next heading level, or change the heading that came before it."},{"kind":"confirmed","code":"control_unlabelled","element":"input[name=\"email\"]","explanation":"This control has a placeholder and no label. A placeholder disappears while typing.","remediation":"Add a label element, an aria-label, or an aria-labelledby reference that exists in the HTML."},{"kind":"confirmed","code":"language_missing","element":"html","explanation":"The page has no lang attribute on the html element.","remediation":"Add a lang attribute, such as lang=\"en\", that matches the page language."},{"kind":"confirmed","code":"aria_widget_unnamed","element":"div","explanation":"This button has no accessible name.","remediation":"Add text, an aria-label, or an aria-labelledby reference that exists."},{"kind":"confirmed","code":"contrast_below_threshold","element":"p","explanation":"The contrast ratio is 1:1 from the colours on this element. It is below 3:1, the AA threshold used for large text.","remediation":"Change one of the colours so normal text reaches 4.5:1 and large text reaches 3:1."},{"kind":"potential","code":"link_generic","element":"a[href=\"/next\"]","explanation":"The link text \"click here\" does not name its destination.","remediation":"Use text that says where the link goes."},{"kind":"manual","code":"css_images_not_checked","element":"document","explanation":"Images painted by CSS backgrounds were not checked.","remediation":"Check CSS background images in a browser when they convey information."},{"kind":"manual","code":"visual_headings_not_checked","element":"document","explanation":"Text that only looks like a heading was not checked.","remediation":"Use a heading element when text is a heading."},{"kind":"manual","code":"form_errors_not_checked","element":"document","explanation":"Error messages and custom widgets were not tested in a browser.","remediation":"Confirm that errors are named and announced when the form is submitted."},{"kind":"manual","code":"link_context_not_checked","element":"document","explanation":"Link purpose was judged from the link text only, not from the surrounding sentence.","remediation":"Review a generic link in its sentence when the text is repeated."},{"kind":"manual","code":"language_not_compared","element":"document","explanation":"The page text was not checked for its human language.","remediation":"Confirm that the lang value matches the language people read on the page."},{"kind":"manual","code":"keyboard_not_operated","element":"document","explanation":"No key was pressed. Focus order and keyboard operation were not tested in a browser.","remediation":"Tab through the page and confirm every action works without a pointer."},{"kind":"manual","code":"aria_runtime_not_checked","element":"document","explanation":"ARIA states that scripts change were not tested in a browser.","remediation":"Operate the widget and confirm the announced name and state."},{"kind":"manual","code":"stylesheet_contrast_not_checked","element":"document","explanation":"Stylesheet, inherited, and user-agent colours were not calculated.","remediation":"Check those pairs in a browser. A passing inline pair does not make the page conform."}],"limitations":["This is a static HTML check. It is not a WCAG conformance claim.","JavaScript is not run, so states that appear only after interaction are not seen.","Contrast is calculated only when both colours are written on the same element.","Checks marked manual need a browser or a person. They are not failures."]}}}},"400":{"description":"Invalid JSON or request schema."},"402":{"description":"Payment Required"},"409":{"description":"Idempotency conflict, in-progress payment, or expired result cache. Reusing the key cannot trigger a second charge."},"413":{"description":"Request body exceeds the 24 MB limit."},"500":{"description":"Operation failed. With upfront settlement this may occur after payment; reuse the same idempotency key to retrieve the stored result."},"503":{"description":"Payment or retry-safe result storage is unavailable; the operation is not run."}},"x-payment-info":{"price":{"mode":"fixed","currency":"USD","amount":"0.12"},"protocols":[{"x402":{}}]}}}},"components":{"schemas":{"ApiError":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}}}}}}}}