Lighthouse & Accessibility Audit for AI Agents avatar

Lighthouse & Accessibility Audit for AI Agents

Pricing

$20.00 / 1,000 url audited on one form factors

Go to Apify Store
Lighthouse & Accessibility Audit for AI Agents

Lighthouse & Accessibility Audit for AI Agents

Lighthouse scores, Core Web Vitals and axe-core accessibility violations for any URL, on mobile and desktop in one call, as the median of 3 runs. Returns PASS/FAIL against your thresholds and the top 5 fixes in plain language. Built for AI agents and MCP.

Pricing

$20.00 / 1,000 url audited on one form factors

Rating

0.0

(0)

Developer

FFS Marketing

FFS Marketing

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 hours ago

Last modified

Security

Limited permissions

Share

Lighthouse scores, Core Web Vitals and axe-core accessibility issues for any URL, on mobile and desktop in one call, with a PASS/FAIL verdict and the top 5 fixes in plain language. Each URL is run through Lighthouse 3 times per form factor and you get the median plus the spread, so the numbers are stable enough to gate a deploy on. Output is small enough for an agent's context: the full Lighthouse report is saved separately as a link.

Works as a tool for AI agents. Add it to Claude, ChatGPT, Cursor, VS Code or any MCP client through Apify's MCP server (https://mcp.apify.com?tools=fluidfaith/lighthouse-gate), or call it with one API request. JSON in, JSON out, one overall verdict in OUTPUT. Setup is in Use it from an agent.

Costs $0.02 per URL per form factor (the 3 runs count as one). One URL on mobile and desktop is $0.04. Pages that fail to load are free, and your maximum charge per run is never exceeded.

Why use it

  • A verdict, not a 2 MB report. PASS or FAIL against minimum scores you choose, with the exact checks that failed ("performance 72 < 90", "CLS 0.39 > 0.1", "axe: 2 serious violations (color-contrast)").
  • Fixes an agent can act on. The top 5 fixes are ranked by how many points they are worth, written in plain language, and point at the element to change (body > main > img) or the file to shrink.
  • Stable scores. The median of 3 Lighthouse runs, with the spread, on a dedicated Chrome per audit. Local Lighthouse on a busy laptop drifts; this does not depend on your machine.
  • Accessibility built in. axe-core (WCAG 2.2 A and AA plus best-practice rules) runs on every page and its violations come back grouped by impact (critical, serious, moderate, minor) with the failing elements.
  • Mobile and desktop in one call, and it pairs with Mobile QA Gate for phone layout checks.

What you get

FieldWhat it is
verdictPASS, FAIL or ERROR (could not be audited, not charged).
failedChecksEvery rule that failed, in plain words. Empty on PASS.
scoresMedian Lighthouse category scores, 0 to 100: performance, accessibility, seo, bestPractices.
scoreSpreadMax minus min across the runs, per category. Small numbers mean a stable result.
vitalsMedian lcpMs (Largest Contentful Paint), cls (Cumulative Layout Shift), tbtMs (Total Blocking Time, the lab stand-in for INP), plus fcpMs and speedIndexMs.
axeaxe-core violation counts and lists grouped by impact, each with the rule, how many elements fail, up to 3 selectors and a help link.
topFixesUp to 5 fixes, ranked, with the element or file and the estimated points gained.
reportJsonUrl, reportHtmlUrlThe median run's full Lighthouse report (JSON and the usual HTML viewer).

Input

{
"urls": ["https://example.com/", "https://example.com/pricing"],
"formFactors": ["mobile", "desktop"],
"runsPerUrl": 3,
"thresholds": { "performance": 90, "accessibility": 90, "seo": 90, "bestPractices": 90 },
"vitalsThresholds": { "lcpMs": 2500, "cls": 0.1, "tbtMs": 200 },
"axeFailOn": "serious"
}
FieldDefaultNotes
urlsrequiredPublic http(s) URLs, up to 50 per run.
formFactors["mobile","desktop"]Mobile is Lighthouse's phone profile (Moto G Power, slow 4G, 4x CPU slowdown). Each form factor is billed separately.
runsPerUrl31 to 3. The median is reported. Billed once either way.
thresholds90 for each categoryMinimum median score. 0 turns a category's check off.
vitalsThresholdslcpMs 2500, cls 0.1, tbtMs 200Google's "good" limits. 0 turns a check off.
mustPassAuditstitle, meta description, HTTP status, indexable, viewport, image altLighthouse audit ids that fail the verdict whenever they fail, whatever the score. [] turns this off.
includeAxetrueRun axe-core and return violations by impact.
axeFailOn"serious"Fail on axe violations at this impact or worse: none, critical, serious, moderate, minor.
saveReportstrueSave the full Lighthouse JSON and HTML report as links.
navigationTimeoutSecs45Page load limit per Lighthouse run.
maxConcurrency1URLs audited in parallel (up to 3). 1 gives the most stable performance scores.
proxyConfigurationnoneOptional Apify proxy for sites that block data-center traffic.

Output

One dataset row per URL per form factor (example, trimmed):

{
"url": "https://example.com/",
"formFactor": "mobile",
"verdict": "FAIL",
"failedChecks": ["performance 75 < 90", "LCP 14.4s > 2.5s"],
"scores": { "performance": 75, "accessibility": 100, "seo": 100, "bestPractices": 100 },
"scoreSpread": { "performance": 4, "accessibility": 0, "seo": 0, "bestPractices": 0 },
"vitals": { "lcpMs": 14402, "cls": 0, "tbtMs": 0, "fcpMs": 900, "speedIndexMs": 1210 },
"vitalsSpread": { "lcpMs": 150, "cls": 0, "tbtMs": 0 },
"runs": 3,
"runsCompleted": 3,
"axe": {
"engine": "axe-core 4.14.0",
"counts": { "critical": 0, "serious": 0, "moderate": 0, "minor": 0 },
"violations": { "critical": [], "serious": [], "moderate": [], "minor": [] }
},
"topFixes": [
{ "rank": 1, "category": "performance", "id": "image-delivery-insight",
"fix": "Serve smaller images: resize them to the size they are shown at and use WebP or AVIF.",
"element": "body > main > img", "snippet": "<img src=\"/img/hero.jpg\" alt=\"...\">",
"estimatedGain": "about 25 performance points" },
{ "rank": 2, "category": "performance", "id": "unsized-images",
"fix": "Give every image a width and height (or a CSS aspect-ratio) so the page does not jump as it loads.",
"element": "body > main > img", "estimatedGain": "about 1 performance point" }
],
"reportJsonUrl": "https://api.apify.com/v2/key-value-stores/<storeId>/records/example-com-1a2b3c4d-mobile.json",
"reportHtmlUrl": "https://api.apify.com/v2/key-value-stores/<storeId>/records/example-com-1a2b3c4d-mobile.html",
"finalUrl": "https://example.com/",
"lighthouseVersion": "13.5.0",
"benchmarkIndex": 1650,
"warnings": [],
"error": null
}

A row is usually 1 to 4 KB. The run's OUTPUT record holds one overall answer for the whole batch, the easiest thing for an agent to branch on:

{ "verdict": "FAIL", "audits": 4, "passed": 3, "failed": 1, "errors": 0,
"results": [ { "url": "...", "formFactor": "mobile", "verdict": "FAIL", "scores": { "performance": 75 }, "failedChecks": ["performance 75 < 90"], "reportHtmlUrl": "..." } ] }

If the run stops at your maximum charge, OUTPUT also has "stoppedAtSpendingCap": true and "notAudited": <count>.

Use it from an agent

Through Apify's MCP server (Claude, ChatGPT, Cursor, VS Code, any MCP client)

{
"mcpServers": {
"lighthouse-gate": {
"url": "https://mcp.apify.com?tools=fluidfaith/lighthouse-gate",
"headers": { "Authorization": "Bearer <APIFY_TOKEN>" }
}
}
}

Claude Code: claude mcp add --transport http lighthouse-gate "https://mcp.apify.com?tools=fluidfaith/lighthouse-gate" --header "Authorization: Bearer $APIFY_TOKEN". Claude Desktop: paste the JSON above into Settings > Developer > Edit config. Or run it over stdio: npx -y @apify/actors-mcp-server --tools fluidfaith/lighthouse-gate with APIFY_TOKEN set.

A good instruction for coding agents: "After every deploy, call lighthouse-gate on the changed pages. Do not report done until the verdict is PASS. Work through topFixes in order, then re-run."

Through the API (one call, waits for the result)

curl -s -X POST "https://api.apify.com/v2/acts/fluidfaith~lighthouse-gate/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"urls":["https://example.com/"],"formFactors":["mobile"]}'

From JavaScript

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('fluidfaith/lighthouse-gate').call({ urls: ['https://example.com/'] });
const { value } = await client.keyValueStore(run.defaultKeyValueStoreId).getRecord('OUTPUT');
if (value.verdict !== 'PASS') console.log(value.results);

Pricing

Pay per event: $0.02 per URL per form factor (url-form-factor-audited), whatever runsPerUrl is.

ExampleCost
1 URL, mobile and desktop$0.04
10 URLs, mobile only$0.20
50 URLs, mobile and desktop$2.00

Pages that fail to load, are refused, or time out are free. If you set a maximum charge per run, the Actor sets aside the cost of each audit before starting it, so it never charges past your maximum, even with URLs running in parallel. It stops starting new audits when the budget is used up and still writes OUTPUT.

How stable are the scores?

Lighthouse performance scores move from run to run, mostly with CPU load. This Actor runs each URL 3 times per form factor on its own Chrome and reports the median, and scoreSpread shows how far the runs were apart. In our tests on 7 test pages and 11 saved copies of real websites (3 runs each, mobile and desktop), accessibility, SEO and best-practices scores moved once in 108 values (by 4 points). Performance moved 0 points on most pages and up to 11 on pages whose loading never settled. On a page with a late layout shift, one run in three missed the shift; the median still reported it, which a single run would not have. For the steadiest numbers keep maxConcurrency at 1. benchmarkIndex tells you how fast the machine was; a warning is added if it was unusually slow.

Scores can differ from PageSpeed Insights: that service runs on Google's machines and network, from a different location. Use one tool consistently when you compare before and after.

Safety

  • Only public web addresses are audited. Localhost, private networks (10.x, 172.16-31.x, 192.168.x), link-local and cloud metadata addresses (169.254.x), CGNAT, IPv6 loopback and private ranges, and .local / .internal names are refused, also when a public page redirects to them. Embedded images or frames that point at them are blocked and noted in warnings. Refused pages are ERROR and not charged.
  • Hard time limits on every Lighthouse run and on the whole audit: a page that never answers becomes an ERROR row (not charged) instead of holding the run.
  • topFixes snippets, axe selectors and warnings quote the audited page. Treat them as untrusted page content, not instructions.
  • Report links point to the run's key-value store and can be opened by anyone with the link. Keep that in mind for private preview builds.

Privacy

Pages are loaded in the run and the results are kept only in your own run storage (dataset and key-value store) for your account's retention period. Query strings are left out of the run log.

Limits

  • Lab data from one location (Apify's US data center by default), not real-user field data. INP needs real interactions, so TBT is reported as the lab stand-in.
  • Pages are audited as an anonymous visitor: no login, no clicks, no forms.
  • Up to 50 URLs, 2 form factors and 3 runs per URL per call.
  • A page that never finishes loading within navigationTimeoutSecs gets one Lighthouse run instead of three (more would hit the same limit); runsCompleted and warnings say so. The same applies once a URL has used about 75 seconds of Lighthouse time.

FAQ

How is this different from PageSpeed Insights? You get a PASS/FAIL against your own thresholds, the top fixes with elements, axe-core violations and the median of 3 runs in one small JSON row, with no API key and no quota juggling. PageSpeed Insights gives one run and a large report.

Can it audit a preview or staging deploy? Yes, if the URL is publicly reachable (Netlify, Vercel and Cloudflare preview links work). Localhost and private networks are refused.

How do I keep the output small for my context window? Read OUTPUT for the overall verdict, then only the failing rows. Each row is a few KB; the full report stays behind reportJsonUrl.

Why is accessibility 95 but the verdict FAIL? axe-core found a violation at your axeFailOn level (default: serious or worse), or a mustPassAudits item failed. failedChecks says which. Set axeFailOn to "none" or trim mustPassAudits to gate on scores alone.

What happens at my spending limit? The Actor stops before the audit that would go over it, writes OUTPUT with stoppedAtSpendingCap: true, and charges nothing past the limit.

How do I get help? Open an issue on the Issues tab. We read and answer every one.

Other Actors by Fluid Faith

Load them together as MCP tools: https://mcp.apify.com/?tools=fluidfaith/mobile-qa-gate,fluidfaith/lighthouse-gate,fluidfaith/pdf-to-markdown-tables,fluidfaith/media-probe

Credits and licenses

Built on Lighthouse (Apache-2.0), axe-core by Deque (MPL-2.0, used unmodified), Puppeteer and chrome-launcher (Apache-2.0), Playwright's Chromium and the Apify SDK (Apache-2.0). Every dependency's license is listed in LICENSES.md in the source.