🦖 TinyRex Data Toolspractical guides for web data APIs

How to run Lighthouse on hundreds of URLs and get Core Web Vitals in one table

Updated 2026-10-28 · Tool used: Bulk Lighthouse Audit - Core Web Vitals, SEO, Accessibility on Apify · Price: $10 per 1,000 successful audits (1 URL on 1 device); unreachable pages are free

PageSpeed Insights is the usual way to check Core Web Vitals, but it tests one URL at a time and its keyless API quota is shared and often answers HTTP 429. Comparing a whole site section, a list of landing pages or a set of competitors quickly turns into a lot of copy and paste.

This guide shows how to run real Lighthouse audits (the open-source tool from Google Chrome) on a list of URLs inside an Apify actor, on mobile, desktop or both, and get one row per page with the four category scores, lab metrics such as LCP, CLS, TBT, FCP and Speed Index, page weight and the failing audits with the largest estimated savings.

Open Bulk Lighthouse Audit on Apify →

Steps

  1. Add pages to urls (bare domains work) and pick formFactor: mobile matches PageSpeed Insights, both counts as two audits.
  2. Optionally limit categories, set maxIssues for the topIssues list, and turn on saveHtmlReport to get a link to the full Lighthouse report.
  3. Export as CSV, sort by performance or largestContentfulPaintMs, and schedule weekly runs to track scores over time.

Example input

{
  "urls": [
    "https://example.com"
  ],
  "formFactor": "mobile"
}

Example output (one item, shortened)

{
  "input": "https://example.com",
  "url": "https://example.com/",
  "formFactor": "mobile",
  "finalUrl": "https://example.com/",
  "statusCode": 200,
  "performance": 100,
  "accessibility": 96,
  "bestPractices": 100,
  "seo": 80,
  "reportHtmlUrl": null,
  "reportJsonUrl": null,
  "durationMs": 7903,
  "charged": true,
  "error": null,
  "auditedAt": "2026-10-21T07:10:44.517Z",
  "firstContentfulPaintMs": 906,
  "largestContentfulPaintMs": 906,
  "totalBlockingTimeMs": 0,
  "cumulativeLayoutShift": 0,
  "speedIndexMs": 906,
  "timeToInteractiveMs": 906,
  "serverResponseTimeMs": 8,
  "totalByteWeight": 2143,
  "failedAuditCount": 6,
  "topIssues": [
    {
      "id": "render-blocking-insight",
      "category": "performance",
      "title": "Render-blocking requests",
      "score": 0,
      "displayValue": "Est savings of 140 ms",
      "savingsMs": 150,
      "savingsBytes": null
    },
    {
      "id": "landmark-one-main",
      "category": "accessibility",
      "title": "Document does not have a main landmark.",
      "score": 0,
      "displayValue": null,
      "savingsMs": null,
      "savingsBytes": null
    },
    {
      "id": "meta-description",
      "category": "seo",
      "title": "Document does not have a meta description",
      "score": 0,
      "displayValue": null,
      "savingsMs": null,
      "savingsBytes": null
    },
    "..."
  ],
  "lighthouseVersion": "13.5.0",
  "runWarnings": []
}

Every run's dataset can be downloaded as JSON, CSV, Excel, XML or HTML from the Apify Console, or via https://api.apify.com/v2/datasets/<datasetId>/items?format=csv.

Run it from code

Python

from apify_client import ApifyClient  # pip install apify-client

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run_input = {
  "urls": [
    "https://example.com"
  ],
  "formFactor": "mobile"
}
run = client.actor("tinyrex/lighthouse-audit").call(run_input=run_input)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

JavaScript / Node.js

import { ApifyClient } from 'apify-client'; // npm i apify-client

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('tinyrex/lighthouse-audit').call({
  "urls": [
    "https://example.com"
  ],
  "formFactor": "mobile"
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);

curl (no SDK)

# Runs the actor and returns the results directly (CSV here; use format=json for JSON)
curl -X POST "https://api.apify.com/v2/acts/tinyrex~lighthouse-audit/run-sync-get-dataset-items?format=csv" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"urls": ["https://example.com"], "formFactor": "mobile"}' > results.csv

Get your API token in Apify Console → Settings → API & Integrations. The free Apify plan includes monthly credit that is enough to try this.

Use it from an AI agent (MCP)

The Apify MCP server exposes this actor as a tool for Claude, Cursor, VS Code, n8n and other MCP clients. Add this to your client's MCP config (or use the OAuth flow at mcp.apify.com instead of a token):

{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=tinyrex/lighthouse-audit",
      "headers": {
        "Authorization": "Bearer <YOUR_APIFY_TOKEN>"
      }
    }
  }
}

Then ask in plain language, e.g. "Bulk lighthouse audit for this list and give me a table".

Use cases

Pricing

Pay per result: $10 per 1,000 successful audits (1 URL on 1 device); unreachable pages are free. You can cap the cost of every run in the run options.

FAQ

Is this the same as PageSpeed Insights?

It runs the same Lighthouse engine with the mobile preset that PageSpeed Insights uses for lab data, so scores are comparable. It does not include the field data (CrUX) section, which comes from real Chrome users.

Do I need a Google API key?

No. Lighthouse runs inside the actor in headless Chrome, so there is no key and no shared quota.

Why do scores differ between runs?

Lab scores vary a little with network and CPU conditions, as in Chrome DevTools. For tracking, compare trends over several runs rather than single numbers.

Can I get the full Lighthouse report?

Yes. saveHtmlReport stores the full HTML report with a public link, and saveJsonReport stores the raw JSON result.

Try it on Apify →

Related guides

More guides