Bulk PageSpeed Insights & Core Web Vitals Checker
Pricing
from $3.00 / 1,000 page checkeds
Bulk PageSpeed Insights & Core Web Vitals Checker
Bulk-test URLs with Google's official PageSpeed Insights API: Lighthouse scores (performance, accessibility, best practices, SEO), lab metrics, real-user CrUX Core Web Vitals (LCP, INP, CLS) and top fixes, mobile and desktop.
Pricing
from $3.00 / 1,000 page checkeds
Rating
0.0
(0)
Developer
Halos AI
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
Test hundreds of URLs at once with Google's official PageSpeed Insights API and get, for every page and device:
- π Lighthouse scores (0β100): Performance, Accessibility, Best Practices, SEO
- π§ͺ Lab metrics: LCP, CLS, TBT, FCP, Speed Index and TTI
- π₯ Real-user Core Web Vitals from the Chrome UX Report (CrUX): LCP, INP, CLS, FCP and TTFB at p75, each labeled good / needs-improvement / poor, plus the overall Core Web Vitals passed/failed assessment for the URL and the whole origin
- π οΈ Top fixes ranked by estimated savings (e.g. "Improve image delivery: LCP β1.2 s")
- π Final URL after redirects, Lighthouse version, fetch time and clear errors
π Bring your own Google API key (free, required in practice)
This Actor runs every check on your own Google API key. Google has closed the shared keyless PageSpeed quota (it's set to 0), so without a key every check comes back with a quota error. Those rows are free, but you get no data.
Get a key in about 2 minutes:
- Open the Google Cloud Console and create a project (or pick an existing one). No billing account is needed for these APIs.
- Go to APIs & Services β Library and enable PageSpeed Insights API. Also enable Chrome UX Report API, which this Actor uses to fill real-user data gaps.
- Go to APIs & Services β Credentials β Create credentials β API key.
- Optional but recommended: click the key, choose Restrict key β API restrictions, and select only those two APIs.
- Paste the key into the Google API key field. The field is secret, so Apify stores it encrypted.
Quota (Google's defaults per Cloud project, free):
- PageSpeed Insights API: 25,000 checks per day and about 400 per 100 seconds. That's roughly 12,500 URLs a day on "Both" devices. You can see your exact limits under APIs & Services β PageSpeed Insights API β Quotas. To go higher, request an increase from Google; don't spread one job across several keys.
- Chrome UX Report API: about 150 queries per minute. It's used only when PageSpeed returns no real-user data.
- The default concurrency of 4 stays well under the per-100-second limit. If Google returns HTTP 429, the Actor backs off and retries. If your daily quota runs out, it stops and marks the remaining rows
billable: false.
What happens to your key: it's sent only to Google's APIs, in the X-goog-api-key request header (never in a URL). It's never logged, never written to the dataset or key-value store, and never shared with Halos AI. Usage counts against your Google project, and you can revoke or rotate the key any time in Google Cloud.
Why this one:
- β Official data only. Every number comes straight from Google's PageSpeed Insights API v5 and the Chrome UX Report API. That's the same engine as pagespeed.web.dev, with no scraping.
- π΅ Fair billing. You pay only for successful page checks (one per URL per device). Invalid URLs, pages Lighthouse can't load and quota errors are still returned with an
errorandbillable: false, and they're never charged. - π Your key, your quota. It works with your own free Google API key (see above), so you get Google's full 25,000 checks a day instead of a shared limit.
- π§ CrUX that keeps working. Google has announced it will phase real-user data out of the PageSpeed API. When PageSpeed has no field data, this Actor asks the CrUX API directly.
- β»οΈ Resilient. Backoff on rate limits (HTTP 429) and Google 5xx errors. It also stops cleanly when a daily quota runs out instead of burning retries.
Use cases
- SEO and web agencies: audit a client's top 200 pages on mobile before a pitch or each month, then hand over the Overview tab as CSV
- Core Web Vitals monitoring: schedule weekly runs and alert when
cwvOriginflips frompassedtofailed - Lead generation for speed and dev services: run prospects' homepages and sort by
performanceScore - Pre- and post-release checks: compare scores for key templates (home, category, product, blog) before and after a deploy
How to use it
- Get a free Google API key (2 minutes, see Bring your own Google API key above) and paste it into Google API key.
- Paste your URLs, one per line, and pick Mobile, Desktop or Both.
- Click Start. Each check takes about 10β40 seconds on Google's side, and 4 run in parallel by default.
- Open Output β Overview, Lab metrics, Real-user Core Web Vitals or Top fixes, and export as CSV, Excel or JSON.
Agency recipe: a client speed audit in one run
Input the client's sitemap's top pages with "strategy": "both". In the Overview table, sort by performanceScore, filter cwvOrigin = failed and read topOpportunity. That gives you a prioritized fix list per template. Re-run monthly on a schedule and keep each dataset as the before/after record in your report.
Cost
Pay per event:
- $0.005 per run (start fee)
- $0.003 per successful page check ($3.00 per 1,000), one check = one URL on one device
Examples:
- 200 URLs on mobile = 200 checks = $0.005 + $0.60 = $0.61
- 200 URLs on both devices = 400 checks = $1.21
- 1,000 URLs, mobile, weekly = about $3.01 a week
Failed and invalid rows cost nothing. You can also cap spend with Apify's Maximum cost per run. The Actor stops cleanly when the cap is reached.
Input example
{"urls": ["https://www.example.com/", "https://www.example.com/pricing", "shop.example.com/category/shoes"],"strategy": "both","categories": ["performance", "accessibility", "best-practices", "seo"],"googleApiKey": "YOUR_GOOGLE_API_KEY","includeCruxApi": true,"maxOpportunities": 5,"concurrency": 4,"maxRetries": 3}
Output example (one item)
{"url": "https://www.example.com/","strategy": "mobile","performanceScore": 62,"accessibilityScore": 91,"bestPracticesScore": 100,"seoScore": 92,"lcpMs": 4870,"cls": 0.04,"tbtMs": 410,"fcpMs": 2120,"speedIndexMs": 3980,"ttiMs": 6900,"fieldDataUrl": {"lcp": {"p75": 2900, "category": "needs-improvement"},"inp": {"p75": 180, "category": "good"},"cls": {"p75": 0.03, "category": "good"},"fcp": {"p75": 1700, "category": "good"},"ttfb": {"p75": 900, "category": "needs-improvement"},"coreWebVitals": "failed","source": "pagespeed-api"},"fieldDataOrigin": {"coreWebVitals": "passed", "source": "crux-api", "collectionPeriod": "2026-09-19/2026-10-16", "...": "..."},"cwvUrl": "failed","cwvOrigin": "passed","fieldLevel": "url","opportunities": [{"id": "image-delivery-insight", "title": "Improve image delivery", "displayValue": "Est savings of 955 KiB", "metricSavings": {"LCP": 1200}}],"topOpportunity": "Improve image delivery","finalUrl": "https://www.example.com/","fetchTime": "2026-10-18T18:07:10.635Z","lighthouseVersion": "13.5.0","durationSecs": 18.4,"error": null,"billable": true}
The values above are illustrative. Failed rows look like {"url": "...", "strategy": "mobile", "error": "Lighthouse could not test the page (FAILED_DOCUMENT_REQUEST) ...", "errorType": "check-failed", "billable": false}.
API example
Run it and get results in one call (replace YOUR_APIFY_TOKEN):
curl -X POST "https://api.apify.com/v2/acts/halos_ai_main~bulk-pagespeed-core-web-vitals-checker/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN&view=overview&format=csv" \-H "Content-Type: application/json" \-d '{"urls": ["https://www.example.com/", "https://www.example.com/blog/"], "strategy": "mobile", "googleApiKey": "YOUR_GOOGLE_API_KEY"}'
Python:
from apify_client import ApifyClientclient = ApifyClient("YOUR_APIFY_TOKEN")run = client.actor("halos_ai_main/bulk-pagespeed-core-web-vitals-checker").call(run_input={"urls": ["https://www.example.com/"], "strategy": "both", "googleApiKey": "YOUR_GOOGLE_API_KEY"})for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(item["url"], item["strategy"], item.get("performanceScore"), item.get("cwvOrigin"))
It also works from Make, Zapier, n8n, Google Sheets (via Apify integrations) and AI agents through the Apify MCP server.
FAQ
Do I need a Google API key? Yes, in practice. Google's shared keyless quota is set to 0, so runs without a key return only free quota-error rows. See Bring your own Google API key above for the 2-minute setup. The key is free, and Google doesn't bill for these APIs within the default quotas.
Why is real-user data missing even though I have a key?
Either the page or site doesn't have enough Chrome traffic (fieldDataNote explains which), or the Chrome UX Report API isn't enabled for your key's project. The run log and status message warn you about the second case.
Why do my scores differ from run to run?
Lighthouse lab tests vary by a few points between runs (network, server load, ads). Use real-user CrUX data (fieldData*, cwv*) for decisions, and lab scores for debugging and before/after comparisons.
Why is real-user data empty for some pages?
CrUX only covers pages and origins with enough Chrome traffic. Small sites often have origin-level data but no URL-level data. fieldLevel tells you which one was used.
What counts as a billable check? One URL tested on one device with a successful Lighthouse result. "Both" devices = 2 checks. Errors are free.
Is TTI always present?
Newer Lighthouse versions may stop reporting Time to Interactive. When Google doesn't return a value, the field is null.
Is this affiliated with Google? No. It's an independent tool by Halos AI that calls Google's public APIs on your behalf. Google, PageSpeed Insights, Lighthouse and Chrome are trademarks of Google LLC. CrUX data is Β© Google, licensed CC BY 4.0.
Support
Found a bug or need a field? Open an issue on the Actor's Issues tab.