# Bulk Lighthouse & Core Web Vitals Auditor (`thriving_adder/bulk-lighthouse-auditor`) Actor

Bulk Google Lighthouse audits of public URLs, mobile and/or desktop: Performance, Accessibility, Best Practices and SEO scores, lab Core Web Vitals (LCP, CLS, TBT), top opportunities and an HTML report per audit. One JSON row per URL and device. Failed audits free.

- **URL**: https://apify.com/thriving_adder/bulk-lighthouse-auditor.md
- **Developed by:** [Adrian LHH](https://apify.com/thriving_adder) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $12.00 / 1,000 lighthouse audits

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Bulk Lighthouse & Core Web Vitals Auditor

**Run Google Lighthouse on hundreds of URLs at once and get one clean table.** For every URL, on **mobile and/or desktop**: the **Performance, Accessibility, Best Practices and SEO scores**, lab **Core Web Vitals** (LCP, CLS, TBT) plus FCP, Speed Index and TTFB, the top fix-it opportunities, failed audits, and a link to the **full interactive Lighthouse HTML report**. No API key, no quotas, no one-URL-at-a-time copy-pasting. **Pay per audit; failed audits are free.**

### What does Bulk Lighthouse Auditor do?

- Audits every URL with the official open-source **Lighthouse 13** engine (the same engine behind Chrome DevTools and PageSpeed Insights) in a fresh headless Chrome.
- **Mobile** (emulated Moto G Power on slow 4G, simulated throttling, like PageSpeed Insights mobile) and/or **desktop** presets.
- Choose the categories you need; fewer categories run faster.
- Flags whether each page passes the lab Core Web Vitals thresholds (LCP ≤ 2.5 s, CLS ≤ 0.1, TBT ≤ 200 ms).
- Lists the biggest opportunities (for example "Reduce unused JavaScript", with estimated savings) and every failed pass/fail audit (for example `image-alt`, `meta-description`).
- Saves the full HTML report (and optionally the raw Lighthouse JSON) for every audit and links it from the row.
- Two ready-made views: **Scores & Core Web Vitals** and **Top opportunities**. Export to JSON, CSV, Excel or HTML.

### Why use it instead of PageSpeed Insights?

- **Bulk:** paste 10 or 2,000 URLs and run them in one go, on a schedule if you like.
- **No Google API key or quota** to manage, and the results land in a dataset you can export or connect to Google Sheets, Slack or webhooks.
- **Full reports kept** for every audit, so you can share or compare them later.
- **Much cheaper** than other bulk Lighthouse tools on the Apify Store.

### How to use it

1. Click **Try for free** (or **Start**) and paste your URLs into **URLs** (one per line, or upload a text/CSV file).
2. Pick **Devices** (mobile, desktop or both) and **Categories**.
3. Click **Start**. Each audit takes about 10–40 seconds. Open the **Scores & Core Web Vitals** view, or click a **Report** link for the full Lighthouse report.

Tip: audit a whole site by listing its pages first with our **Sitemap URL Extractor & SEO Health Checker**.

### Input

| Field | Default | What it does |
|---|---|---|
| `urls` | required | Up to 2,000 public URLs per run (`[{ "url": "https://..." }]`, plain strings also work). |
| `devices` | `["mobile"]` | `mobile` and/or `desktop`. Each device is one audit and one row. |
| `categories` | all four | `performance`, `accessibility`, `best-practices`, `seo`. |
| `throttlingMethod` | `simulate` | `simulate` matches PageSpeed Insights; `provided` = raw speed, no throttling. |
| `saveHtmlReport` | `true` | Full HTML report per audit, linked in `reportUrl`. |
| `saveJsonReport` | `false` | Full Lighthouse JSON per audit, linked in `jsonReportUrl`. |
| `respectRobotsTxt` | `true` | Skip (free) URLs that robots.txt disallows. |
| `maxConcurrency` | `1` | 1 or 2 parallel audits (2 needs 8 GB run memory). |
| `pageTimeoutSecs` | `60` | Max page-load wait per audit. |

```json
{
  "urls": [{ "url": "https://www.python.org" }, { "url": "https://www.gov.uk" }],
  "devices": ["mobile", "desktop"],
  "categories": ["performance", "accessibility", "best-practices", "seo"],
  "saveHtmlReport": true
}
```

### Output

One row per URL and device. Example (shortened, from a real run):

```json
{
  "url": "https://www.python.org/",
  "device": "mobile",
  "finalUrl": "https://www.python.org/",
  "scores": { "performance": 74, "accessibility": 75, "bestPractices": 100, "seo": 92 },
  "fcpMs": 2462, "lcpMs": 4067, "tbtMs": 420, "cls": 0.003, "speedIndexMs": 2462, "ttiMs": 4149, "ttfbMs": 3,
  "coreWebVitalsPass": false,
  "opportunities": [
    { "id": "render-blocking-insight", "title": "Render-blocking requests", "savingsMs": 1400, "displayValue": "Est savings of 1,420 ms" },
    { "id": "unused-css-rules", "title": "Reduce unused CSS", "savingsMs": 600, "savingsBytes": 131589, "displayValue": "Est savings of 129 KiB" }
  ],
  "failedAudits": ["aria-hidden-focus", "color-contrast", "link-text"],
  "reportUrl": "https://api.apify.com/v2/key-value-stores/<id>/records/lh_5d5c..._mobile_html",
  "lighthouseVersion": "13.5.0",
  "benchmarkIndex": 1437,
  "auditedAt": "2026-10-26T10:49:10.000Z"
}
```

Audits that fail are still listed, with `error` and a machine-readable `errorCode` (for example `ERRORED_DOCUMENT_REQUEST` for a 404/500 page, `NO_FCP`, `AUDIT_TIMEOUT`, `ROBOTS_DISALLOWED`, `BLOCKED_NON_PUBLIC`, `INVALID_URL`). These rows are **not charged**. If a page fails on the first device for a page-level reason (for example a 404), the second device is skipped for free. A `SUMMARY` record in the key-value store has the run totals.

### How much does it cost?

Pay per event: you pay only for audits that finished and were saved.

| Event | Price |
|---|---|
| Lighthouse audit (one URL, one device) | $0.012 |
| Second device for the same URL (mobile + desktop) | $0.010 |

- 100 URLs on mobile ≈ **$1.20**; 100 URLs on mobile **and** desktop ≈ **$2.20**. That is $12 per 1,000 audits, far below typical bulk PageSpeed tools.
- Apify adds its standard tiny run-start fee (about $0.00005 per GB of memory; the default run uses 4 GB).
- Failed audits (timeouts, 404s, pages that never paint, blocked or robots.txt-disallowed URLs) are **free**.
- Set **Maximum cost per run** and the Actor never starts an audit it cannot bill within your limit; everything finished so far is kept.

### Use it from code or an AI agent

Every Apify Actor is an API. Call it with the [Apify API](https://docs.apify.com/api/v2), the JavaScript or Python client, or as a tool in **Apify's MCP server** for Claude, ChatGPT, Cursor and other AI agents. The input is a plain JSON object with a `urls` array; each output row has stable numeric fields (scores 0–100, metrics in ms) and an `errorCode` on failures, so an agent can compare pages or flag regressions without parsing text.

```bash
curl -X POST "https://api.apify.com/v2/acts/thriving_adder~bulk-lighthouse-auditor/run-sync-get-dataset-items" \
  -H "Authorization: Bearer YOUR_APIFY_TOKEN" -H 'Content-Type: application/json' \
  -d '{"urls":[{"url":"https://example.com"}],"devices":["mobile"]}'
```

### What data does it collect?

Only technical performance and quality measurements of the pages you list. It does not collect personal data, does not log in or use cookies, and cannot reach private networks: every request the browser makes, including redirects and embedded resources, goes through a filter that blocks `localhost`, private-network and cloud-metadata addresses. By default it **respects robots.txt** (user-agent token `LighthouseAuditBot`). Only audit pages you are allowed to access.

### Use cases

- **Weekly performance and SEO monitoring** of your own site or a client portfolio (schedule it and connect a webhook, Slack or Google Sheets).
- **Before/after checks** for releases, redesigns and migrations.
- **Competitor benchmarking** of landing pages.
- **Agency reporting:** one table with scores and report links for every client page.
- **AI agents** that need a reliable performance check as a tool.

### Tips

- Keep **Parallel audits** at 1 for the most stable scores. Lab scores always vary a little from run to run; for important pages, audit 3 times and use the median.
- Lab metrics are not field data. Google's ranking uses real-user (CrUX) data, which this Actor does not query.
- **Large lists:** one audit takes about 10–40 s, so the default 1-hour run timeout fits roughly 150–250 audits. For bigger lists, raise **Timeout** in the run options (or split the list); audits finished before a timeout are kept.
- `benchmarkIndex` shows the CPU speed Lighthouse measured; at the default 4 GB memory it is comparable to PageSpeed Insights hardware.

### FAQ

**Why do my scores differ from PageSpeed Insights?** PSI runs on Google's hardware from a US location. Simulated throttling makes numbers comparable, but not identical; performance scores typically land within about 10 points.

**Why 4 GB of memory?** Lighthouse scores depend on CPU speed. On Apify, 4 GB comes with one full CPU core, which gives stable, PSI-like scores and avoids browser crashes on very long pages.

**Problems or ideas?** Open an issue in the Issues tab with the URL and input. We answer within 2 business days.

# Actor input Schema

## `urls` (type: `array`):

Public http(s) pages to audit, max 2,000 per run. Each item is {"url": "https://..."}; plain strings and URLs without a scheme (example.com) are also accepted. Duplicates are removed. Login-protected, localhost and private-network URLs are rejected and not charged.

## `devices` (type: `array`):

Which Lighthouse presets to run for every URL: "mobile" (Moto G Power, slow 4G, simulated throttling, like PageSpeed Insights mobile) and/or "desktop". Each device is a separate audit and row; the second device for the same URL is billed at the cheaper second-device price.

## `categories` (type: `array`):

Lighthouse categories to score: performance, accessibility, best-practices, seo. Fewer categories run faster. Unknown values are ignored; an empty list runs all four.

## `throttlingMethod` (type: `string`):

"simulate" (default) gives numbers comparable with PageSpeed Insights. "provided" applies no throttling and reports raw speed from Apify's servers.

## `saveHtmlReport` (type: `boolean`):

Save the full interactive Lighthouse HTML report for every audit to the run's key-value store and link it in the reportUrl field.

## `saveJsonReport` (type: `boolean`):

Also save the complete Lighthouse JSON result (LHR, about 0.5-2 MB each) and link it in jsonReportUrl. Useful for custom analysis.

## `respectRobotsTxt` (type: `boolean`):

Skip URLs whose robots.txt disallows automated agents (our token: LighthouseAuditBot). Skipped URLs are free and returned with errorCode ROBOTS_DISALLOWED.

## `maxConcurrency` (type: `integer`):

Audits run in parallel (1 or 2). 1 gives the most stable performance scores. For 2, set the run memory to 8 GB (each audit needs about 4 GB / 1 vCPU).

## `pageTimeoutSecs` (type: `integer`):

Maximum wait for the page to load in each audit (Lighthouse maxWaitForLoad). Pages that never finish loading fail with a free error row.

## Actor input object example

```json
{
  "urls": [
    {
      "url": "https://www.python.org"
    }
  ],
  "devices": [
    "mobile"
  ],
  "categories": [
    "performance",
    "accessibility",
    "best-practices",
    "seo"
  ],
  "throttlingMethod": "simulate",
  "saveHtmlReport": true,
  "saveJsonReport": false,
  "respectRobotsTxt": true,
  "maxConcurrency": 1,
  "pageTimeoutSecs": 60
}
```

# Actor output Schema

## `results` (type: `string`):

One row per URL and device with Lighthouse scores, metrics and report links.

## `reports` (type: `string`):

Full Lighthouse HTML reports (keys lh\_\*\_html).

## `summary` (type: `string`):

Counts of delivered, failed and skipped audits, and any hosts blocked by the SSRF guard.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "urls": [
        {
            "url": "https://www.python.org"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("thriving_adder/bulk-lighthouse-auditor").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "urls": [{ "url": "https://www.python.org" }] }

# Run the Actor and wait for it to finish
run = client.actor("thriving_adder/bulk-lighthouse-auditor").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "urls": [
    {
      "url": "https://www.python.org"
    }
  ]
}' |
apify call thriving_adder/bulk-lighthouse-auditor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,thriving_adder/bulk-lighthouse-auditor"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/tfuAawld7K7pTq7U8/builds/mqiWT79Rbsl5qAC52/openapi.json
