{"openapi":"3.1.0","info":{"title":"ADAGuard Public API v1","description":"Programmatic access to ADAGuard scanning. Authenticate every request with the X-API-Key header.","version":"1.0.0"},"servers":[{"url":"/v1"}],"paths":{"/scan":{"post":{"tags":["Public API v1"],"summary":"Create Scan V1","description":"Start an API scan — and record the attempt, whatever happens (services/scan_tracking).","operationId":"create_scan_v1_scan_post","parameters":[{"name":"Idempotency-Key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Idempotency-Key"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScanRequest"}}}},"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/standards":{"get":{"tags":["Public API v1"],"summary":"List Standards","description":"Every `standard` a scan can be scored against, legal standards first.","operationId":"list_standards_standards_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/scan/{scan_id}/status":{"get":{"tags":["Public API v1"],"summary":"Get Scan Status V1","description":"Poll scan progress.\n\nCall repeatedly until `status` is `completed` or `failed`.\nUse `poll_again_in` (seconds) as a hint for your retry interval.\n\n**auth_status values**\n- `not_requested`   — no auth session was provided\n- `authenticated`   — scan ran with the stored session\n- `expired_fallback`— session had expired; scan fell back to public pages\n- `public_only`     — site detected as public (no auth needed)","operationId":"get_scan_status_v1_scan__scan_id__status_get","parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","title":"Scan Id"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/scan/{scan_id}/report":{"get":{"tags":["Public API v1"],"summary":"Get Scan Report V1","description":"Download a scan report.\n\n**Formats**\n- `json` (default) — structured data, ideal for CI/CD parsing\n- `html`           — self-contained HTML report (attach to Jira tickets / emails)\n- `csv`            — spreadsheet-friendly issue list for QA teams\n- `pdf`            — professional PDF for compliance / executive sharing","operationId":"get_scan_report_v1_scan__scan_id__report_get","parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","title":"Scan Id"}},{"name":"format","in":"query","required":false,"schema":{"type":"string","pattern":"^(json|html|csv|pdf)$","default":"json","title":"Format"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/scan/{scan_id}":{"get":{"tags":["Public API v1"],"summary":"Get Scan V1","description":"Get full scan results including all issues.\n\nThe `passed` field is populated when `min_score` was set at scan creation.\n`auth_status` indicates whether authenticated scanning was used.","operationId":"get_scan_v1_scan__scan_id__get","parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","title":"Scan Id"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}},"delete":{"tags":["Public API v1"],"summary":"Delete Scan V1","description":"Permanently delete a scan and its stored data.\n\nThis action cannot be undone.","operationId":"delete_scan_v1_scan__scan_id__delete","parameters":[{"name":"scan_id","in":"path","required":true,"schema":{"type":"string","title":"Scan Id"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth-sessions":{"get":{"tags":["Public API v1"],"summary":"List Auth Sessions V1","description":"List the Authenticated Targets stored for this account.\n\nEach entry has a `target_key` (a stable, human-named alias such as\n'production-admin') and a `name`. Pass the `target_key` as `auth_target`\nwhen starting a scan — or use `auth_target: \"latest\"` for your most recent\ntarget. The `session_id` field is kept equal to `target_key` for backward\ncompatibility with the legacy `auth_session_id` parameter.\n\nTargets are created and named via the ADAGuard dashboard:\n**Settings → Authenticated Targets** (Add Target → Launch Browser).\n\nA target with `status: \"expired\"` will trigger `auth_status: \"expired_fallback\"`\nin scan results — the scan runs but only covers public pages.","operationId":"list_auth_sessions_v1_auth_sessions_get","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/auth-sessions/{session_id}":{"delete":{"tags":["Public API v1"],"summary":"Delete Auth Session V1","description":"Revoke (delete) a stored Authenticated Target for this account.\n\nPass the `target_key` (equivalently the `session_id`) from\n`GET /v1/auth-sessions`. Deleting a target immediately removes its stored\nsession so it can no longer be used to start authenticated scans — the API\nkill-switch for incident response, matching the dashboard's delete action.\n\nReturns 404 if no target with that id exists for this account.\nRequires the `scans:write` scope.","operationId":"delete_auth_session_v1_auth_sessions__session_id__delete","parameters":[{"name":"session_id","in":"path","required":true,"schema":{"type":"string","title":"Session Id"}},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/scans":{"get":{"tags":["Public API v1"],"summary":"List Scans V1","description":"List scans with optional URL filtering.\n\nUse `?url=https://example.com` to retrieve scan history for a specific site.\nResults are sorted newest first and include a `passed` field for scans\nthat used the `min_score` CI/CD gate.","operationId":"list_scans_v1_scans_get","parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":10,"title":"Limit"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"title":"Offset"}},{"name":"url","in":"query","required":false,"schema":{"anyOf":[{"type":"string","maxLength":2048},{"type":"null"}],"description":"Filter by URL prefix (e.g. https://example.com)","title":"Url"},"description":"Filter by URL prefix (e.g. https://example.com)"},{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/scans/stats":{"get":{"tags":["Public API v1"],"summary":"Get Scan Stats V1","description":"Get scan usage statistics for the authenticated account.","operationId":"get_scan_stats_v1_scans_stats_get","parameters":[{"name":"x-api-key","in":"header","required":false,"schema":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"X-Api-Key"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/badge/{domain}.svg":{"get":{"tags":["Public API v1","Badges"],"summary":"Get Score Badge","description":"Public live accessibility score badge for a domain.\n\nReturns a shields.io-style SVG badge showing the most recent completed\nscan score for the given domain. No API key required.\n\nEmbed in your README:\n```markdown\n[![Accessibility](https://api.adaguard.io/v1/badge/adaguard.io.svg)](https://app.adaguard.io)\n```\n\nRefreshes every 5 minutes (Cache-Control: max-age=300).","operationId":"get_score_badge_badge__domain__svg_get","parameters":[{"name":"domain","in":"path","required":true,"schema":{"type":"string","title":"Domain"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ScanRequest":{"properties":{"url":{"type":"string","maxLength":2083,"minLength":1,"format":"uri","title":"Url","description":"Public URL to scan (http/https only, no private IPs)"},"max_pages":{"type":"integer","maximum":5000.0,"minimum":1.0,"title":"Max Pages","description":"Maximum pages to scan in crawl/sitemap/layout modes. Capped to your plan limit (Professional: 500, Business: 1 000, Enterprise: 5 000 — API access starts at Professional). Ignored for single mode.","default":1},"standard":{"anyOf":[{"type":"string","maxLength":32},{"type":"null"}],"title":"Standard","description":"What the score counts: a legal standard (ada, section508, en301549, aoda, aca) or a WCAG version and level (e.g. wcag21-aa, wcag22-aa). Default: the website's or account's setting, else wcag21-aa. Findings outside it are reported but not scored."},"scan_mode":{"type":"string","pattern":"^(single|crawl|sitemap|layout|all_pages|unique_layouts)$","title":"Scan Mode","description":"How to discover pages. Use 'single' for one-URL CI checks.","default":"single"},"min_score":{"anyOf":[{"type":"integer","maximum":100.0,"minimum":0.0},{"type":"null"}],"title":"Min Score","description":"CI/CD gate threshold (0-100). The result includes passed=true if score ≥ min_score, false otherwise."},"auth_target":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Auth Target","description":"Named authenticated target to scan with — either a target_key (e.g. 'production-admin') or the keyword 'latest' for your most recently captured session. Create and name targets in the dashboard (Settings → Authenticated Targets); list them via GET /v1/auth-sessions. The target is a stable alias — its underlying session rotates on recapture, so this value keeps working. Takes precedence over auth_session_id. If the session has expired the scan falls back to public pages and auth_status='expired_fallback'."},"auth_session_id":{"anyOf":[{"type":"string"},{"type":"null"}],"title":"Auth Session Id","description":"Legacy: ID of a stored authenticated session. Prefer auth_target. Still supported and resolved against your Authenticated Targets. If the session has expired the scan automatically falls back to scanning public pages and auth_status='expired_fallback'."},"include_subdomains":{"type":"boolean","title":"Include Subdomains","description":"Whether to crawl pages on subdomains of the target domain (e.g. api.example.com, blog.example.com). Set to false to restrict crawling to the exact hostname only. Only applies in crawl/sitemap/layout modes.","default":true},"exclude_paths":{"anyOf":[{"items":{"type":"string"},"type":"array","maxItems":100},{"type":"null"}],"title":"Exclude Paths","description":"Glob patterns for URLs to skip, e.g. [\"/admin\", \"/checkout/*\", \"*.pdf\"]. Merged with any exclusions saved on the matching website in your dashboard — a scan adds to those rather than replacing them. Only applies in crawl/sitemap/layout modes."}},"type":"object","required":["url"],"title":"ScanRequest","description":"Request body for POST /v1/scan.\n\nscan_mode\n---------\nsingle   → scan only the given URL (default — fastest, CI/CD friendly)\ncrawl    → follow internal links up to max_pages\nsitemap  → discover URLs from sitemap.xml first, then crawl\nlayout   → crawl + deduplicate structurally similar pages\n\nLegacy aliases still accepted: all_pages, unique_layouts"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}}}}