Comparison · Two surfaces, one recruiter UI, very different bills and audit rows

Drive the surface a screen reader sees, not the bag of pixels.

An ATS recruiter UI is the unusual case where two architectures look reasonable on paper but only one survives the bill, the redesign, and the compliance attestation. This page does the dual comparison: cost per action against Anthropic's published image-token formula, stability against an enterprise procurement contract, audit-row shape against NYC Local Law 144 and the EU AI Act high-risk hiring rules, and the cases where the screenshot path still earns its place.

Direct answer · Verified 2026-05-04

Drive the accessibility tree first.By Anthropic's published image-token formula width * height / 750, one 1280x800 candidate-page screenshot is approximately 1365 image tokens before any reasoning. The equivalent Playwright locator.ariaSnapshot() for the same region fits in a few hundred tokens. Every major recruiter ATS publishes WCAG 2.1 or 2.2 AA conformance, so the tree is a procurement-locked surface the vendor cannot quietly rotate. And the audit row a tree-driven action produces (role, accessible name, before- and after-tree hash) is the shape regulators ask for under NYC Local Law 144, Illinois HB 3773, Colorado CAIA, and the EU AI Act high-risk hiring rules. Use vision as a typed fallback for genuinely visual decisions, not as the default.

Verified against Anthropic's vision documentation, Playwright ARIA snapshots, WCAG 2.1, and the Workday accessibility statement declaring WCAG 2.2 AA, Section 508, and EN 301 549 conformance.

01The token math

One screenshot is 1300+ tokens. One ARIA subtree is a few hundred.

Anthropic publishes the formula explicitly. The image-token cost of any screenshot is the pixel count divided by 750, with model-specific caps. That is not a marketing claim; it is the per-image calculation that goes onto your invoice every time the model reads a screenshot.

screenshot-budget.ts

Caps verified 2026-05-04 against Anthropic's vision documentation. Sonnet 4.6 caps at 1568 image tokens with a 1568 px long edge; Opus 4.7 caps at 4784 image tokens with a 2576 px long edge. Per-MTok input prices are $3 (Sonnet 4.6) and $5 (Opus 4.7) at the time of writing.

And here is what the model sees instead, on the same page

The same Ashby candidate page, rendered as a Playwright ARIA snapshot. Twenty-two lines, every interactive control labeled with role and accessible name, every state attribute the model needs to act. A subtree of this shape fits in a few hundred tokens and is what the locator.getByRole API walks when the agent fires its action.

candidate-page.aria.yml
0image tokens for one 1280x800 candidate-page screenshot, per Anthropic vision formula
0tokens for the same candidate page rendered as a Playwright ariaSnapshot subtree
0xapproximate per-action cost ratio between the screenshot path and the tree path
0major ATS vendors with published WCAG 2.x AA conformance the tree is locked against

Token figures use Anthropic's published formula (image_tokens = width * height / 750) and direct line counts of the rendered ARIA snapshot. The 6x ratio is approximate; it widens on Opus 4.7 (cap 4784) for a 1920x1080 capture and narrows on smaller screenshots. Vendor count covers Greenhouse, Lever, Workday Recruiting, and Ashby per their published or VPAT-on-request accessibility statements.

02The dual comparison

Same task, two surfaces, eight dimensions that actually matter

A recruiter moves a candidate from phone screen to onsite. The agent has to read the page, find the right control, click it, pick the option, confirm. Below is what that one task costs and produces under each surface.

FeatureScreenshots (vision)Accessibility tree (role + name)
Tokens per step~1365 image tokens for a 1280x800 capture, capped at 1568 (Sonnet 4.6) or 4784 (Opus 4.7).~200 to 400 tokens for the relevant ariaSnapshot subtree; pure text, parses in milliseconds.
Stability across UI redesignsPixel layouts move with every CSS change; vision models silently mis-click after a redesign.Roles and accessible names are part of the VPAT. Rotating them breaks the WCAG conformance claim and every screen reader.
Selector shapeA 1280x800 PNG plus a natural-language instruction. The agent infers affordances from pixels.getByRole('button', { name: 'Move stage' }). The role and the accessible name are a published contract.
Iframes and shadow DOMPixels traverse boundaries trivially, but every frame pays the screenshot token cost again.Tree composes across iframes; assistive tech has to traverse them, so frameLocator + getByRole works as normal.
Audit-row contentFolder of PNGs and inferred actions. Compliance has to reverse-engineer what the agent saw.Role, accessible name, before-tree-hash, after-tree-hash. Replayable, diff-able, attestable.
Compliance fit (LL144, HB 3773, CAIA, EU AI Act)Pixel logs do not show what the candidate was offered, only what the agent rendered.Same surface a screen reader user walks; same surface the WCAG audit covers; one document trail.
Failure mode when the UI changesSilent. The vision model often keeps clicking the same coordinates with a new label.Loud. The role+name pair is missing; the weekly tree-diff health check pages the on-call.
When to fall back to the other oneCaptcha. Cropped avatars. Hand-scanned PDF previews. ATSes with no published a11y tree.Default for Greenhouse, Lever, Workday Recruiting, Ashby, and any vendor with a current VPAT.

Both surfaces ship in real production stacks. Tree-first with typed vision fallback is the architecture every audit ready agentic ATS we have looked at converges on.

03The audit row

What gets written when the recruiter taps approve

The compliance argument lives or dies on this row. A regulator asking what the agent did and what surface the candidate saw will accept a role+name+tree-hash record without further conversation. A folder of PNGs paired with inferred actions becomes a multi-week conversation with the compliance team and an attestation auditors are uncomfortable signing.

audit_log.candidate_actions · row written 2026-04-30T14:11:04Z

The screenshot equivalent of this row would attach a folder of PNG captures, an inferred action label, and no replayable surface for the regulator to walk. The same compliance team that signs off on the tree row would, on the screenshot row, ask the legal team to weigh in.

04The wire-level snippet

Move-stage on Ashby, written against the tree

The same task as the screenshot budget above, expressed through Playwright's accessibility-tree API. No CSS classes, no XPath, no pixel coordinates. The selector targets the published role and accessible name; the audit row pins to the same pair.

ats/move-stage.ts
6x cheaper

“The reason agentic ATS automation breaks at six months is that someone keeps rotating CSS class names, and the reason it stays expensive is the per-screenshot token bill. The tree solves both at once because procurement requires it to be stable.”

Pattern across three 2026 production agentic-ATS deployments

05Where vision still earns its place

Three honest cases for the screenshot

No published accessibility tree. Most internal admin tools that customers build on top of an ATS, plus a small number of pre-VPAT startup ATSes, ship a sparse or absent tree. The tree path falls back to vision until the surface gets fixed, with the audit row flagged surface: vision_fallback so a regulator can see exactly which actions were tree-driven and which were not.

Genuinely visual decisions. Reading a hand-scanned PDF inside an attachment preview, cropping a candidate avatar, judging the layout of a portfolio screenshot. These cases need pixels because the answer is in the pixels. The tree carries the structural metadata; the vision step carries the content. Both surface in the audit row.

Captcha and adversarial visual challenges. Anti-automation surfaces are designed to resist the tree by definition. Pure tree integrations cannot solve them; pure vision integrations sometimes can. The architectural answer is to stop and route to the recruiter rather than to escalate the agent into vision-only mode.

None of these undo the cost or compliance arguments on the default surface. They argue for a typed fallback, not for screenshots as the primary architecture.

06Why ATS specifically

The procurement contract that makes the tree a published API

The tree-versus-screenshots argument is stronger inside the ATS category than in general browser automation, and the reason is procurement. Every ATS vendor selling into a federal agency, a state government, a public university, or most Fortune 1000 enterprises must publish a Voluntary Product Accessibility Template declaring conformance to WCAG 2.1 AA, Section 508, and (for European buyers) EN 301 549. Workday publishes that statement openly. Greenhouse, Lever, and Ashby publish VPATs on request. The conformance is not a marketing checkbox; it is a precondition of the contract.

The conformance claim is built on roles and accessible names. A button must announce role=button and a name that conveys its purpose. A listbox must enumerate its options. A form input must be labeled. Once those are shipped and audited, changing them silently breaks every screen reader, breaks the VPAT, and risks the next renewal. The role+name surface is a contract the vendor has agreed not to break, the way a CSS class hash never was.

That contract is what the agent gets to script against. A general consumer site has no such guarantee, and the vision-versus-tree argument is weaker there. Inside ATS, the procurement floor is what makes tree-first the architectural default.

The cost argument

Hundreds of tokens, not thousands

The Anthropic-published image formula is unforgiving at recruiter scale. A team running 200 to 300 stage transitions a week pays the screenshot tax on every read; the tree path keeps the read in low hundreds of tokens for the same surface.

The stability argument

A procurement contract, not a refactor target

Roles and accessible names are part of the VPAT every enterprise ATS has to publish. Vendors cannot rotate them without breaking the conformance claim. Pixel layouts and CSS classes have no such guarantee.

The compliance argument

Same view a screen reader gets

The audit row pins to a role, an accessible name, and a tree hash. A regulator can replay the action against the same surface a screen-reader user would have walked. PNG logs cannot.

The one-paragraph version

Tree-first by default, vision typed as a fallback

For ATS automation, drive the published accessibility tree as the default surface. By Anthropic's own image-token formula, screenshots are 4 to 8 times more expensive per action; by every major ATS's own VPAT, the tree is locked against the kind of redesign that breaks CSS-class scrapers; by every 2026 hiring law that touches recruiter automation, the tree-hash audit row is the only shape regulators can replay. Use vision when the answer is genuinely in the pixels and flag the fallback in the audit log. Anything else trades cost, stability, and compliance for a familiarity premium that disappears the first time the vendor changes a button label.

For the wire-level integration walkthrough, see the ATS accessibility tree integration guide, which expands the per-vendor accessible-name dictionary, the approval queue, and the weekly tree-diff health check.

Want to see the tree path on your own pipeline?

Join the waitlist. We will walk through a move-stage on your live ATS through the published accessibility tree, with the audit row attached and the screenshot budget you avoided.

Questions integration engineers actually ask about tree versus screenshots

What is the actual per-action token cost difference between accessibility tree and screenshots?

Anthropic publishes the formula in its vision docs: image_tokens = width * height / 750. A 1280x800 candidate-page screenshot is ~1365 image tokens, capped at 1568 on Claude Sonnet 4.6 once the image crosses ~1.18 megapixels, or up to 4784 tokens on Claude Opus 4.7 (long-edge cap 2576 px). The same candidate page rendered via Playwright's locator.ariaSnapshot() is a YAML subtree of a few hundred tokens for the relevant region. Per recruiter action that is a ratio of roughly 4 to 8 times. At a one-recruiter team running 200 to 300 stage transitions a week, the bill compounds visibly.

Why does the accessibility tree win specifically on ATS automation, not just browser automation in general?

Two reasons. First, every major ATS publishes WCAG 2.1 AA or 2.2 AA conformance because federal procurement requires a VPAT under Section 508 and EU buyers require EN 301 549. That makes the tree dense, semantically labeled, and stable across releases. Second, the audit row a tree-driven action produces (role, accessible name, before-tree-hash, after-tree-hash) is the shape NYC Local Law 144, Illinois HB 3773, Colorado CAIA, and the EU AI Act high-risk hiring rules expect. A screenshot log gives a regulator a bag of pixels; a tree-hash log gives a regulator a replayable surface. Both arguments only hold this strongly inside the ATS category.

Where do screenshots still win?

Three cases. First, surfaces with no published accessibility tree (rare on Greenhouse, Lever, Workday, Ashby, but common on internal admin tools or pre-VPAT startup ATSes). Second, genuinely visual decisions like cropping a candidate avatar or reading a hand-scanned PDF inside an attachment preview, which require pixel input the tree does not encode. Third, captcha and visual challenges intended to defeat automation, which the tree cannot help with by design. The pragmatic shape is tree-first with vision as a typed fallback flagged in the audit log.

How does locator.getByRole compare to a CSS selector against the same element?

The CSS selector targets an internal implementation detail. div.candidate-row .stage-btn--rev4 survives until the next refactor, and class hashes rotate on every release of every modern ATS. locator.getByRole('button', { name: 'Move stage' }) targets a published surface the vendor cannot quietly rotate without breaking screen readers and the VPAT. The role+name pair is in everything but name a public API the procurement contract guarantees. The CSS path has no such guarantee.

Does the tree handle iframes and shadow DOM the way screenshots do?

Better, in practice. The accessibility tree composes across iframe boundaries because assistive technology has to traverse them; Playwright's frameLocator drops in and getByRole works as normal. Closed shadow DOM is a problem for both DOM scrapers and a11y trees, but most ATS UIs avoid closed shadow roots because they would also break screen readers and fail the WCAG audit. Screenshots traverse iframes trivially because pixels do not care about boundaries, but they pay the token cost on every frame, and they cannot tell a regulator what the recruiter actually saw.

What happens when a vendor changes the accessible name on a button?

The integration breaks loudly on the next snapshot diff. A weekly health check captures the candidate flow against a fixture and diffs role+name pairs against the per-vendor dictionary. A rotated verb (Greenhouse 'Move' becoming 'Advance to stage') triggers a page to the on-call. Vendors do not announce these changes, so the diff is the only signal. The screenshot equivalent is harder: a vision model often silently keeps clicking the same place even when the rendered label has changed, which is worse than a loud break.

Is the tree-driven approach compatible with Anthropic computer use and OpenAI Operator?

Yes. Anthropic's computer use tool exposes accessibility-snapshot mode in addition to screenshots; the input is the same role-and-name surface a Playwright getByRole call walks. OpenAI Operator's underlying model is multimodal and can be steered with a textual ARIA snapshot in the prompt instead of a raw screenshot, which trades a few hundred tokens of structured input for the per-image cost. The pattern is to feed the model the tree first and only attach a screenshot when the answer requires a visual decision the tree cannot encode.

How do you produce an ARIA snapshot in Playwright?

page.locator('body').ariaSnapshot() returns a YAML representation of the accessible structure under the locator, with role, accessible name, and ARIA attributes like checked, expanded, level. The output is small enough to fit in a model context, stable enough to assert against in tests, and structured enough to feed into an action planner. The same surface drives the locator.getByRole API, so the snapshot you read and the selector you write target identical nodes.

What does a tree-driven audit row look like that a screenshot log cannot match?

Tool ats.move_stage, vendor ashby, target_role button, target_name 'Move stage', from_stage 'Phone screen', to_stage 'Onsite', before_tree_sha256, after_tree_sha256, actor_agent, approved_by, approval_latency_ms, queue_surface. A regulator can replay that row against the same surface a screen-reader user would have walked, because role and name are the contract. The screenshot equivalent is a folder of 1280x800 PNGs the compliance team has to reverse-engineer into actions; the diff is human, slow, and hard to attest.

Where does 10xats sit on this comparison?

Tree-first by default, vision typed as a fallback. Every named agent that drives an ATS UI uses role+name selectors against the published tree and falls back to the public API when the surface exists there. The fallback to vision is reserved for genuinely visual decisions and is flagged in the audit row so a regulator can see which actions were tree-driven and which were not. Every action sits in the recruiter approval queue as a draft with the tree snapshot attached. We do this because it is the only architecture we have found that survives an ATS UI redesign and produces an audit log a 2026 hiring-law regulator will accept.

How did this page land for you?

React to reveal totals

Comments ()

Leave a comment to see what others are saying.

Public and anonymous. No signup.