{
  "openapi": "3.1.1",
  "info": {
    "title": "Accessibility Snapshot API",
    "version": "1.0.0",
    "summary": "Static WCAG 2.2 snapshot of a page: findings by severity, evidence and manual checks.",
    "description": "Every endpoint performs the same calculation as the human page and returns inputs, result, units, assumptions, sources, warnings and computedAt. MCP endpoint: /mcp."
  },
  "servers": [
    {
      "url": "https://a11ysnapshot.usefulweb.site"
    }
  ],
  "paths": {
    "/api/v1/calculate": {
      "post": {
        "operationId": "calculate",
        "summary": "Static WCAG 2.2 snapshot of a page: findings by severity, evidence and manual checks.",
        "description": "Fetch a public URL or paste HTML to get a deterministic accessibility snapshot: page language, title, image alternatives, form labels, button and link names, heading outline, landmarks, tables, iframes, zoom blocking and more — each finding mapped to a WCAG 2.2 success criterion with the offending element. It also lists what must be checked by hand.\n\nMethodology:\n- The HTML is parsed by a tolerant tokenizer/tree builder; no JavaScript is executed and no CSS is computed, so content injected by scripts is not seen.\n- 28 rules run: language, title, text alternatives, form labels, button/link names, headings, duplicate ids, viewport zoom, data tables, iframe titles, autoplaying media, landmarks, skip link, tabindex and aria-hidden misuse.\n- Each finding is classed as \"failure\" (strong evidence of a WCAG 2.2 success-criterion failure), \"best-practice\" (recommended but not a strict failure, e.g. heading order or duplicate ids — SC 4.1.1 Parsing is obsolete in WCAG 2.2) or \"needs-review\".\n- Accessible names are approximated from aria-labelledby, aria-label, label elements, content text, image alt and title, in that order.\n- Criteria that need rendering or human judgement (colour, contrast, keyboard, focus visibility, captions…) are listed as manual checks.\n\nAutomated static checks can only detect some failures. They cannot establish WCAG 2.2 conformance: conformance requires a full manual review of every page state (WCAG 2.2 §5.2), including rendered contrast, keyboard operation and assistive-technology testing.",
        "tags": [
          "developer"
        ],
        "x-mcp-tool": "a11y_snapshot",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/A11ySnapshotInput"
              },
              "examples": {
                "example1": {
                  "summary": "Landing page with common problems",
                  "value": {
                    "html": "<!doctype html>\n<html>\n<head><meta name=\"viewport\" content=\"width=device-width, user-scalable=no\"><title></title></head>\n<body>\n<div class=\"nav\"><a href=\"/\"><img src=\"logo.png\"></a> <a href=\"/shop\">Shop</a> <a href=\"/blog\">Blog</a> <a href=\"/help\">Help</a> <a href=\"/about\">About</a> <a href=\"/cart\"><svg aria-hidden=\"true\"></svg></a></div>\n<h1>Spring sale</h1>\n<h3>Newsletter</h3>\n<form><input type=\"email\" name=\"email\" placeholder=\"Your email\"><button><svg aria-hidden=\"true\"></svg></button></form>\n<p>Read our offers <a href=\"/offers\">click here</a>.</p>\n<iframe src=\"https://www.youtube.com/embed/xyz\"></iframe>\n</body>\n</html>",
                    "maxFindings": 100
                  }
                },
                "example2": {
                  "summary": "Well-structured contact page",
                  "value": {
                    "html": "<!doctype html>\n<html lang=\"en\">\n<head><meta name=\"viewport\" content=\"width=device-width, initial-scale=1\"><title>Contact – Example Ltd</title></head>\n<body>\n<a class=\"skip-link\" href=\"#main\">Skip to main content</a>\n<header><nav aria-label=\"Main\"><a href=\"/\">Home</a> <a href=\"/products\">Products</a> <a href=\"/pricing\">Pricing</a> <a href=\"/support\">Support</a> <a href=\"/contact\">Contact</a></nav></header>\n<main id=\"main\">\n<h1>Contact us</h1>\n<form><label for=\"name\">Name</label><input id=\"name\" name=\"name\" autocomplete=\"name\"><label for=\"msg\">Message</label><textarea id=\"msg\" name=\"msg\"></textarea><button type=\"submit\">Send</button></form>\n<img src=\"/team.jpg\" alt=\"Our support team in the Berlin office\">\n</main>\n</body>\n</html>",
                    "maxFindings": 50
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Calculation result envelope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/A11ySnapshotResult"
                }
              }
            }
          },
          "400": {
            "description": "Malformed JSON body.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Invalid input (see errors[]).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded (see Retry-After).",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/tool": {
      "get": {
        "operationId": "getToolDefinition",
        "summary": "Inputs, output schema and examples for this tool",
        "responses": {
          "200": {
            "description": "Tool definition.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Problem": {
        "type": "object",
        "description": "RFC 9457 problem details. 422 responses include per-field `errors`.",
        "required": [
          "type",
          "title",
          "status",
          "detail"
        ],
        "properties": {
          "type": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer"
          },
          "detail": {
            "type": "string"
          },
          "code": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "field",
                "message"
              ],
              "properties": {
                "field": {
                  "type": "string"
                },
                "message": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "A11ySnapshotInput": {
        "type": "object",
        "additionalProperties": false,
        "properties": {
          "url": {
            "title": "Page URL",
            "description": "Fetched once, server-side, with the static HTML only (no JavaScript is executed).",
            "type": "string",
            "format": "uri"
          },
          "html": {
            "title": "Or paste HTML",
            "description": "Takes precedence over the URL. Useful for pages behind a login or local drafts.",
            "type": "string",
            "maxLength": 500000
          },
          "maxFindings": {
            "title": "Max findings listed",
            "type": "integer",
            "minimum": 5,
            "maximum": 500,
            "default": 100
          }
        },
        "required": []
      },
      "A11ySnapshotResult": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "schemaVersion",
          "tool",
          "computedAt",
          "inputs",
          "summary",
          "result",
          "units",
          "assumptions",
          "sources",
          "warnings",
          "presentation",
          "links"
        ],
        "properties": {
          "schemaVersion": {
            "type": "string",
            "const": "1.0"
          },
          "tool": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "id",
              "name",
              "version"
            ],
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "version": {
                "type": "string"
              }
            }
          },
          "computedAt": {
            "type": "string",
            "format": "date-time"
          },
          "inputs": {
            "type": "object",
            "description": "Normalised inputs actually used, including applied defaults."
          },
          "summary": {
            "type": "string"
          },
          "result": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "origin",
              "stats",
              "totals",
              "findings",
              "findingsTruncated",
              "manualChecks",
              "criteriaWithFailures",
              "conformanceStatement"
            ],
            "properties": {
              "origin": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "kind",
                  "truncated"
                ],
                "properties": {
                  "kind": {
                    "type": "string",
                    "enum": [
                      "url",
                      "pasted"
                    ]
                  },
                  "requestedUrl": {
                    "type": "string"
                  },
                  "finalUrl": {
                    "type": "string"
                  },
                  "status": {
                    "type": "integer"
                  },
                  "contentType": {
                    "type": "string"
                  },
                  "fetchedAt": {
                    "type": "string"
                  },
                  "truncated": {
                    "type": "boolean"
                  }
                }
              },
              "stats": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "elements",
                  "images",
                  "imagesWithAlt",
                  "links",
                  "buttons",
                  "formControls",
                  "headings",
                  "h1Count",
                  "landmarks",
                  "tables",
                  "iframes",
                  "media",
                  "lang",
                  "title"
                ],
                "properties": {
                  "elements": {
                    "type": "integer"
                  },
                  "images": {
                    "type": "integer"
                  },
                  "imagesWithAlt": {
                    "type": "integer"
                  },
                  "links": {
                    "type": "integer"
                  },
                  "buttons": {
                    "type": "integer"
                  },
                  "formControls": {
                    "type": "integer"
                  },
                  "headings": {
                    "type": "integer"
                  },
                  "h1Count": {
                    "type": "integer"
                  },
                  "landmarks": {
                    "type": "integer"
                  },
                  "tables": {
                    "type": "integer"
                  },
                  "iframes": {
                    "type": "integer"
                  },
                  "media": {
                    "type": "integer"
                  },
                  "lang": {
                    "type": [
                      "string",
                      "null"
                    ]
                  },
                  "title": {
                    "type": [
                      "string",
                      "null"
                    ]
                  }
                }
              },
              "totals": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "findings",
                  "failures",
                  "bestPractice",
                  "needsReview",
                  "critical",
                  "serious",
                  "moderate",
                  "minor"
                ],
                "properties": {
                  "findings": {
                    "type": "integer"
                  },
                  "failures": {
                    "type": "integer"
                  },
                  "bestPractice": {
                    "type": "integer"
                  },
                  "needsReview": {
                    "type": "integer"
                  },
                  "critical": {
                    "type": "integer"
                  },
                  "serious": {
                    "type": "integer"
                  },
                  "moderate": {
                    "type": "integer"
                  },
                  "minor": {
                    "type": "integer"
                  }
                }
              },
              "findings": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "ruleId",
                    "title",
                    "wcag",
                    "level",
                    "kind",
                    "severity",
                    "message",
                    "selector",
                    "line",
                    "snippet"
                  ],
                  "properties": {
                    "ruleId": {
                      "type": "string"
                    },
                    "title": {
                      "type": "string"
                    },
                    "wcag": {
                      "type": "array",
                      "items": {
                        "type": "string",
                        "pattern": "^\\d\\.\\d\\.\\d+$"
                      }
                    },
                    "level": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "enum": [
                        "A",
                        "AA",
                        null
                      ]
                    },
                    "kind": {
                      "type": "string",
                      "enum": [
                        "failure",
                        "best-practice",
                        "needs-review"
                      ]
                    },
                    "severity": {
                      "type": "string",
                      "enum": [
                        "critical",
                        "serious",
                        "moderate",
                        "minor"
                      ]
                    },
                    "message": {
                      "type": "string"
                    },
                    "selector": {
                      "type": "string"
                    },
                    "line": {
                      "type": "integer",
                      "minimum": 1
                    },
                    "snippet": {
                      "type": "string"
                    }
                  }
                }
              },
              "findingsTruncated": {
                "type": "boolean"
              },
              "manualChecks": {
                "type": "array",
                "items": {
                  "type": "object",
                  "additionalProperties": false,
                  "required": [
                    "sc",
                    "title",
                    "level",
                    "reason"
                  ],
                  "properties": {
                    "sc": {
                      "type": "string"
                    },
                    "title": {
                      "type": "string"
                    },
                    "level": {
                      "type": "string",
                      "enum": [
                        "A",
                        "AA"
                      ]
                    },
                    "reason": {
                      "type": "string"
                    }
                  }
                }
              },
              "criteriaWithFailures": {
                "type": "array",
                "items": {
                  "type": "string"
                },
                "description": "WCAG 2.2 success criteria with at least one automated failure."
              },
              "conformanceStatement": {
                "type": "string"
              }
            }
          },
          "units": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "assumptions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "type": "object",
              "additionalProperties": false,
              "required": [
                "title"
              ],
              "properties": {
                "title": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                },
                "publisher": {
                  "type": "string"
                },
                "retrievedAt": {
                  "type": "string"
                },
                "note": {
                  "type": "string"
                }
              }
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "presentation": {
            "type": "array",
            "items": {
              "type": "object"
            },
            "description": "Display blocks used by the human page (same data)."
          },
          "links": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "human",
              "api",
              "openapi",
              "methodology"
            ],
            "properties": {
              "human": {
                "type": "string",
                "format": "uri"
              },
              "api": {
                "type": "string",
                "format": "uri"
              },
              "openapi": {
                "type": "string",
                "format": "uri"
              },
              "methodology": {
                "type": "string",
                "format": "uri"
              }
            }
          }
        }
      }
    }
  }
}