JSON output
--json prints one object with ok, command,
result on success, warnings, errors, and
meta. Commands that load a page or control a screen reader session add
target. mcp and help-all have no
--json option and print text only.
a1 axe http://localhost:3000 --level AA --json {
"ok": true,
"command": { "family": "axe", "subcommand": "axe", "version": "0.1.0", "wcagVersion": "2.2" },
"target": { "kind": "url", "value": "http://localhost:3000/" },
"result": { "violations": [], "passes": [], "incomplete": [], "inapplicable": [], "..." : "..." },
"warnings": [],
"errors": [],
"meta": { "schemaVersion": "1", "startedAt": "...", "completedAt": "...", "durationMs": 842 }
}
A failure prints the same fields with ok: false and no
result. errors has one or more entries with a
code, a message, and sometimes details.
a1 wcag show 9.9.9 --json {
"ok": false,
"command": { "family": "wcag", "subcommand": "show", "version": "0.1.0", "wcagVersion": "2.2" },
"warnings": [],
"errors": [
{ "code": "criterion-not-found", "message": "Criterion lookup failed for \"9.9.9\".", "details": { "lookupKey": "9.9.9" } }
],
"meta": { "schemaVersion": "1", "startedAt": "...", "completedAt": "...", "durationMs": 13 }
}
Check ok, not the exit code, when a command can succeed with a failed
check inside it. a1 axe keeps ok: true when violations
remain after --fail-on filtering. The verdict is
result.verdict, and the exit code returns the same verdict as a number,
for a shell to check.
Exit codes
sr command run with no active session.a1 doctor --strict.a1 axe or a1 audit violation past --fail-on, or a failed sr find, sr goto, sr wait --for, sr expect, or sr batch step.Exit code 4 is the one to fail a build on. It means the command ran to completion and found something wrong, not that the command itself is broken.
a1 axe http://localhost:3000 --level AA --fail-on serious
echo "exit code: $?" Shell scripts
A CI step or a pre-commit hook needs nothing beyond the exit code. No JSON parsing is required to fail a build.
#!/usr/bin/env bash
set -e
a1 axe http://localhost:3000/checkout --level AA --fail-on serious
For a one-line result from a command that moves the screen reader, --phrase
prints the last announcement alone, with no JSON to parse. It needs an active session.
sr start is the command that takes --sr.
a1 sr start --sr virtual http://localhost:3000/checkout --json
a1 sr next --phrase heading, Checkout, level 1
Both text and JSON output print to stdout. A human-readable error line prints to
stderr alongside the JSON, so a1 ... --json 2>/dev/null is safe to
pipe into a JSON parser.
Reading JSON with jq
a1 axe http://localhost:3000 --level AA --json 2>/dev/null \
| jq -r '.result.violations[] | "\(.id) (\(.impact))"' button-name (critical) result.verdict is the pass or fail decision after
--fail-on and --baseline. Read it instead of counting
violations yourself when a baseline is in play.
a1 audit http://localhost:3000 --json 2>/dev/null | jq -r '.result.nextCommands[]' a1 wcag rule button-name Baselines
axe and audit both take --baseline <file>
and --update-baseline. On a site with existing findings, accept them
once, then fail only on new ones.
a1 axe http://localhost:3000 --level AA --baseline a11y-baseline.json --update-baseline
git add a11y-baseline.json
Commit the file. Every later run without --update-baseline compares
against it, keyed by rule id and node target, and exits 4 only for a finding the
baseline does not already list.
a1 axe http://localhost:3000 --level AA --baseline a11y-baseline.json Testing HTML without a server
axe, tree, and audit take a file path,
- for HTML on stdin, or --html for inline markup, so a
pre-commit hook can check a component file directly.
echo '<button></button>' | a1 axe - --json
a1 axe --html '<img src="logo.png">' --json
a1 axe src/components/Dialog.html --json 