Bulk Lighthouse Audit: PageSpeed, SEO & CWV
Pricing
from $25.00 / 1,000 successful url audits
Bulk Lighthouse Audit: PageSpeed, SEO & CWV
Run Lighthouse on up to 50 public URLs in one batch: performance, accessibility, best-practices and SEO score plus Core Web Vitals (LCP, CLS, TBT, FCP). Our own Chrome, so no Google API key, PageSpeed quota or baseline. Monitor mode confirms regressions over two runs.
Pricing
from $25.00 / 1,000 successful url audits
Rating
0.0
(0)
Developer
Vadim Bezrukov
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
Paste up to 50 public URLs and get one Lighthouse row per page: performance, accessibility, best-practices and SEO scores, plus the Core Web Vitals lab metrics LCP, CLS, TBT and FCP. A batch audit needs no baseline, no Google API key and no PageSpeed Insights quota: every audit runs in our own Chrome with open-source Lighthouse.
Run it once for a site review, or switch to monitor mode and run it on a schedule. Monitor mode saves a last-good baseline per URL and confirms a performance regression only when two runs in a row breach it. A timeout or a blocked page never looks like a recovery.
Quick start: audit 10 pages in one run
{"urls": [{"url": "https://example.com", "externalId": "home"},{"url": "https://example.com/pricing", "externalId": "pricing"},{"url": "https://example.com/blog", "externalId": "blog"},{"url": "https://example.com/contact", "externalId": "contact"},{"url": "https://example.com/about", "externalId": "about"},{"url": "https://example.org", "externalId": "org-home"},{"url": "https://example.org/docs", "externalId": "org-docs"},{"url": "https://example.net", "externalId": "net-home"},{"url": "https://example.net/shop", "externalId": "net-shop"},{"url": "https://example.net/help", "externalId": "net-help"}],"mode": "snapshot","formFactor": "mobile"}
Replace the example URLs with your own pages. All four categories are on by default; pick fewer in Lighthouse categories if you only need some. Performance and Core Web Vitals always run, because the row status and the charge depend on them.
One row of the result (shortened; values differ per page and run):
{"external_id": "home","status": "SUCCESS","requested_url": "https://example.com","form_factor": "mobile","performance_score": 96,"accessibility_score": 88,"best_practices_score": 100,"seo_score": 90,"lcp_ms": 1250,"cls": 0.0,"tbt_ms": 30,"fcp_ms": 1100,"category_errors": []}
Scores use the 0-100 scale you know from Lighthouse reports. Open the Lighthouse scores Dataset view for the four scores side by side, or All URL audits for scores and Core Web Vitals together.
At $0.025 per successful audit, these 10 pages cost about $0.25. Set Maximum cost per run to at least $0.26 so every page fits in the budget.
Who uses this bulk Lighthouse audit?
- SEO teams checking the SEO and accessibility score of every landing page before and after a release;
- agencies reviewing a client portfolio in one run instead of one PageSpeed lookup per URL;
- engineering teams that want a lab Core Web Vitals baseline and two-run confirmation before paging on noise;
- webhook and MCP workflows that must tell
UNCHANGEDapart fromTIMEOUT.
Monitor Core Web Vitals on a schedule
{"urls": [{"url": "https://example.com", "externalId": "homepage"}],"mode": "monitor","formFactor": "mobile"}
The first successful monitor run creates a BASELINE. Run the same saved
Task again and keep URL and form factor stable. A later breach of the
performance thresholds is REGRESSION_PENDING until the next run confirms it
(REGRESSION_CONFIRMED) or the metrics recover. Timeouts, HTTP errors,
blocked pages and incomplete audits leave the last successful baseline
intact. Monitor mode uses the named key-value store
lighthouse-cwv-monitor-state.
Accessibility, best-practices and SEO scores are reported next to their
previous value (previous_accessibility_score, previous_best_practices_score,
previous_seo_score). They never raise an alert and never change the
performance baseline, so adding or removing them keeps an existing monitor
comparable.
Daily schedule
- Run a
monitorinput successfully once. - In Apify Console, choose Save as task.
- Open Schedules, create a daily schedule, and select that Task.
- Keep URL and form factor unchanged.
Webhook on confirmed regressions
Attach an ACTOR.RUN.SUCCEEDED webhook to the scheduled Task. In the
receiver, fetch the run dataset and act only on comparable successes:
const confirmed = datasetItems.filter((item) => item.status === 'SUCCESS' && item.monitor_event === 'REGRESSION_CONFIRMED',);
Never treat a missing monitor_event or a failed status as unchanged.
Ready-made example Tasks
- Snapshot Lighthouse Core Web Vitals for one page
- Monitor Lighthouse Core Web Vitals regressions
- Lighthouse Core Web Vitals Website Portfolio Audit
The default Actor input audits one public page, https://example.com.
More inputs
Desktop lab profile
{"urls": [{"url": "https://example.com"}],"mode": "monitor","formFactor": "desktop"}
Mobile and desktop keep separate last-good baselines. A Lighthouse or Chrome
major change rebases as PROFILE_CHANGED instead of a false regression.
Performance only
{"urls": [{"url": "https://example.com"}],"categories": ["performance"]}
Only the performance score and Core Web Vitals are filled; the other score
columns are null. The price per audit is the same.
Input reference
| Field | Default | Meaning |
|---|---|---|
urls | required | 1-50 public HTTP(S) pages, with optional externalId |
mode | snapshot | snapshot does not touch monitor state; monitor compares successful audits |
formFactor | mobile | Lighthouse mobile or desktop lab profile |
categories | all four | any of performance, accessibility, best-practices, seo; performance always runs |
Concurrency, Chrome flags and proxy settings are not inputs. The Actor runs one Chrome, one audit at a time.
Query strings, including UTM parameters, are part of identity. www vs bare
host is distinct. Trailing slashes are preserved. Fragments are dropped.
Credentials and private/loopback hosts are rejected before Chrome starts.
Output and failure semantics
Every row carries source, stable source_id, source_url, scraped_at,
schema_version and fingerprint, plus lab metrics, the four category
scores and an explicit status. One bad URL does not stop the others: ten
inputs always produce ten rows. Repeated normalized URLs share one audit:
alias rows retain each external_id, carry duplicate_of, and incur no
extra event charge.
If Lighthouse cannot score a requested category (for example because one of
its audits errored), that score is null and category_errors says which
category and why. The audit itself still counts as SUCCESS when performance
and Core Web Vitals are complete.
Statuses:
SUCCESS- comparable lab audit with performance score, LCP, CLS, TBT, FCP and Chrome major;INVALID_URL- rejected before Chrome access;UNREACHABLE- DNS/connection failure;HTTP_ERROR- document HTTP 4xx/5xx other than a block;TIMEOUT- navigation or hard audit timeout; Chrome is recycled;BLOCKED- HTTP 401/403/407/429 or a Chrome interstitial on a page that loaded. A refusal with an empty body shows Chrome's own error page and is reported asUNREACHABLE, because the page gives Lighthouse no status code;AUDIT_FAILED- Lighthouse ran but the row is not comparable, including off-host redirects and missing lab metrics;FAILED- spending-limit rejection, Chrome/worker start failure (WORKER_START_FAILED), corrupt monitor state, or an unexpected per-item error.
Monitor events on a classified row:
BASELINE- first comparable success for this URL and form factor;UNCHANGED- performance metrics stayed inside the noise thresholds;REGRESSION_PENDING- one breach; last-good is kept;REGRESSION_CONFIRMED- two consecutive breaches;RECOVERED- metrics returned after a confirmed regression;PROFILE_CHANGED- form factor, Lighthouse version, Chrome major or throttling changed, so the baseline is rebased;AUDIT_FAILED- the check is not comparable.
failed_audits lists the lowest-scoring performance audits and
opportunities the largest load-time savings. See
examples/sample_output.json for a complete
row.
API use
Use the standard Apify Actor API with your own token. Never place a token in source control.
import osfrom apify_client import ApifyClientclient = ApifyClient(os.environ["APIFY_TOKEN"])run = client.actor("automa-flow/lighthouse-cwv-monitor").call(run_input={"urls": [{"url": "https://example.com", "externalId": "homepage"}],"mode": "snapshot",},)items = list(client.dataset(run["defaultDatasetId"]).iterate_items())
Use with AI agents through Apify MCP
Expose the Actor as a typed MCP tool:
https://mcp.apify.com?tools=automa-flow/lighthouse-cwv-monitor
Example prompt:
Run automa-flow/lighthouse-cwv-monitor in snapshot mode for these publiclanding-page URLs on mobile. Report the performance, accessibility,best-practices and SEO score of each page, and keep TIMEOUT or AUDIT_FAILEDrows separate from successful audits.
Agent budget before a call (plus the platform apify-actor-start of about
$0.0002 at the 4 GiB default): 1 URL $0.025, 10 URLs $0.25,
maximum 50 URLs $1.25. Set maxTotalChargeUsd to that url-audit bill
plus start. A $0.25 cap is too low for 10 successful audits at 4 GiB
($0.2502). If the limit cannot cover every valid URL, Chrome never starts
and each URL gets a free BILLING_LIMIT_TOO_LOW row.
Authenticated MCP execution uses the caller's Apify account and pay-per-event.
Direct ?tools=automa-flow/lighthouse-cwv-monitor requires a token; anonymous
search-actors can discover the public listing. Discovery via MCP is not the
same as an autonomous paid run.
Related automa-flow tools
- On-page SEO for the same site: Website SEO Audit audits noindex, canonical, metadata and broken-link issues and reports which ones appear or recover between runs.
- Search traffic of the same sites: Website Traffic Checker returns monthly organic search traffic since 2015 and the Chrome popularity tier for up to 10,000 domains, to read next to your audit results.
- Build the URL list: Sitemap Extractor returns every URL in a sitemap tree. Choose the pages you want to measure and pass them as
urls.
Each Actor runs and charges separately. This Actor does not call them.
Pricing
The price is $0.025 per successful URL audit ($25 per 1,000), with all
four category scores included. In monitor mode it also includes the
comparison with last-good. Platform usage is included in this pay-per-event
price; the Apify Console price shown at run time is canonical.
The Actor does not define a custom start event. Console PPE still applies
the synthetic apify-actor-start at the platform default of $0.00005 per GB
of allocated memory ($0.0002 at the 4 GiB default) and covers the first
five seconds of compute. That is not url-audit.
| Successful URL audits | url-audit charge | Plus apify-actor-start at 4 GiB |
|---|---|---|
| 1 | $0.025 | ≈ $0.0252 |
| 10 | $0.25 | ≈ $0.2502 |
| 50 | $1.25 | ≈ $1.2502 |
| 1,000 | $25.00 | ≈ $25.0002 |
An unchanged monitor check is billable because the page was audited and
compared. Invalid URLs, blocked pages, HTTP errors, timeouts, unreachable
hosts, failed audits, retries and duplicate aliases are not charged. If a
run's maximum total charge cannot cover every potentially successful URL, the
Actor stops before launching Chrome, writes one free BILLING_LIMIT_TOO_LOW
result per otherwise valid URL and fails the run. No last-good is advanced
without a deliverable paid result.
A completed run is not replayed after resurrection. If output delivery was
interrupted, the Actor retains existing output and stops with
DELIVERY_UNCERTAIN; start a new run for a new observation. If every URL
fails because of the target pages, the run still succeeds with the status
message NO_SUCCESS and keeps the free error rows. It fails only when our own
runtime broke, for example when Chrome could not start.
Known limitations
- Lab Lighthouse is not field Core Web Vitals. Scores vary with Chrome, Lighthouse version, CPU and simulated throttling.
- Default memory is 4 GiB. A heavy page can take a minute and lab scores move with CPU. Keep 4 GiB unless you have measured the page.
- One Chrome, sequential audits, maximum 50 URLs per run. A slow page can take tens of seconds.
- No proxy, login, cookie jar or CAPTCHA solving. Pages that require those will fail explicitly.
- Off-host redirects are
AUDIT_FAILED, not success.wwwto bare host on the same registrable host is allowed. - This Actor does not crawl a site, does not list every accessibility or SEO issue, and does not call the PageSpeed Insights API or return field CrUX data.
FAQ and troubleshooting
Is this PageSpeed Insights? No. PageSpeed Insights is a Google service with its own quota and a mix of field and lab data. This Actor runs the same open-source Lighthouse engine in Chrome against the URLs you paste, so you need no API key and hit no PageSpeed quota. Scores can differ from a PageSpeed lab run, because CPU and network conditions differ.
Why is my SEO score null? Lighthouse could not score that category,
usually because one of its audits errored on the page. category_errors
names the category. The performance audit and its charge are unaffected.
Why was my successful-looking page AUDIT_FAILED? Missing performance
score, LCP, CLS, TBT, FCP or Chrome major, or an off-host finalUrl, cannot
be compared. The last-good baseline is kept.
Why did one slow run not alert? A single breach is REGRESSION_PENDING.
The next comparable run must also breach to become REGRESSION_CONFIRMED.
Can I audit localhost? No. Private, loopback and metadata hosts are rejected.
Security, legal use and retention
You control the URL list. The Actor fetches only those public HTTP(S) pages
in a headless Chrome lab audit. It does not log in, store cookies for later
reuse, or collect personal data beyond what the requested page already
exposes in a Lighthouse report extract (URL, lab metrics, category scores,
selected audit titles). Monitor state stores last-good metrics and the latest
category scores in the named KVS lighthouse-cwv-monitor-state until you
delete that store. Dataset rows follow your Apify storage retention.
Respect each site's terms and robots.txt. Do not use it to access accounts,
paywalled content or private networks.
Release history
See the Changelog for every update.