# Bulk Lighthouse & Core Web Vitals Audit (`rod_analytics/lighthouse-audit`) Actor

Run Google Lighthouse on hundreds of URLs. Get performance, accessibility, best practices and SEO scores, Core Web Vitals (LCP, CLS, TBT, INP), top fixes and full HTML reports. Mobile and desktop. Optional CrUX field data with your own PageSpeed Insights key.

- **URL**: https://apify.com/rod\_analytics/lighthouse-audit.md
- **Developed by:** [Rod Services](https://apify.com/rod_analytics) (community)
- **Categories:** SEO tools, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

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

### What does Bulk Lighthouse & Core Web Vitals Audit do?

**Bulk Lighthouse & Core Web Vitals Audit** runs **Google Lighthouse on hundreds or thousands of URLs** and returns one clean JSON row per page and device. You get the four **Lighthouse scores** (Performance, Accessibility, Best Practices, SEO), **Core Web Vitals** (LCP, CLS, TBT, INP), FCP, TTFB, Speed Index, the **top improvement opportunities** with estimated savings, and a link to the **full Lighthouse HTML report** for every URL.

It is a **bulk PageSpeed Insights tool** at **$1.50 per 1,000 audits**. By default it calls the official **Google PageSpeed Insights API with your own free key**, so you get Google's own Lighthouse numbers plus **real user CrUX field data** (p75 LCP, CLS, INP, FCP, TTFB). No browser runs, so it is fast and cheap. No key or no Google quota? Switch to the **local engine**, which runs Lighthouse in real Google Chrome inside the Actor.

Run it on the Apify platform with API access, scheduling, webhooks, integrations (Make, Zapier, n8n, Google Sheets, Slack) and monitoring. Press **Start** with the prefilled example to try it.

### Why use this Lighthouse bulk audit tool?

- **SEO agencies.** Audit every client page in one run. Send reports with scores, Core Web Vitals and fixes per URL.
- **Web performance monitoring.** Schedule daily or weekly runs. Track LCP, CLS and TBT over time and alert on regressions with webhooks.
- **Core Web Vitals checks before release.** Audit staging and production URLs, mobile and desktop, in one run.
- **Competitor benchmarking.** Compare page speed and SEO scores of your site against competitors.
- **Accessibility and SEO audits at scale.** Count failed audits per page and find the worst pages first.
- **AI agents and LLM tools.** One predictable JSON schema with numbers, not screenshots. Agents can call it through the Apify API or MCP and reason about the top fixes.

### How to get a free PageSpeed Insights API key (2 minutes)

1. Open the [PageSpeed Insights API page](https://console.cloud.google.com/apis/library/pagespeedonline.googleapis.com) in Google Cloud Console. Sign in and create a project if asked.
2. Click **Enable**.
3. Open [Credentials](https://console.cloud.google.com/apis/credentials), click **Create credentials** and pick **API key**.
4. Copy the key. Optional: click **Restrict key** and allow only the PageSpeed Insights API.

The key is free. Google's quota is 25,000 requests per day. The Actor stores it encrypted as a secret input.

If the key is wrong, or the API is not enabled for its project, the run stops after the first request. It ends with one error item and Google's error message in the status. Only the run start is charged.

### How to run a bulk Lighthouse audit

1. Open the **Input** tab.
2. Paste URLs into **URLs to audit**, one per line. `example.com` works, https is added.
3. Paste your **PageSpeed Insights API key**. Without a key the run stops right away with the setup guide above and nothing is charged for audits.
4. Pick **Device**: mobile, desktop or both.
5. Press **Start**. PSI audits take 10 to 60 seconds each and run 20 at a time.
6. Open the **Output** tab. Switch views: Overview, Core Web Vitals, Opportunities, CrUX field data. Click **Report** to open the full Lighthouse report.

#### Local engine, no key needed

Set **Engine** to `local` and set **Memory** to **8 GB** in Run options. Chrome needs about 2 CPU cores for credible scores. The Actor warns in the log when memory is under 4 GB.

### Input

Only `urls` is required.

| Field               | Default    | Description                                                                                    |
| ------------------- | ---------- | ---------------------------------------------------------------------------------------------- |
| `urls`              |            | Pages to audit. Duplicates are removed.                                                        |
| `strategy`          | `mobile`   | `mobile`, `desktop` or `both`. Both means two audits per URL.                                  |
| `categories`        | all four   | `performance`, `accessibility`, `best-practices`, `seo`.                                       |
| `throttling`        | `simulate` | `simulate` like PageSpeed Insights, `devtools` applied throttling, `none` raw speed.           |
| `cpuSlowdown`       | `auto`     | Mobile CPU slowdown. Auto calibrates to the cloud CPU. `4` is the plain Lighthouse default.    |
| `engine`            | `psi`      | `psi` calls the Google PageSpeed Insights API with your key. `local` runs Chrome in the Actor. |
| `psiApiKey`         |            | Your free Google API key. Secret, stored encrypted. Needed for `psi`, adds CrUX to `local`.    |
| `maxConcurrency`    | 20 or 1    | Parallel audits. 20 for PSI, 1 for local.                                                      |
| `includeFullReport` | `true`     | Save the full HTML report to the key-value store.                                              |
| `includeJsonReport` | `false`    | Also save the raw Lighthouse JSON, linked in `reportJsonUrl`.                                  |
| `maxOpportunities`  | `10`       | Top opportunities per audit.                                                                   |
| `timeoutSecs`       | `90`       | Hard limit per audit. Failed audits are retried once and never charged.                        |

```json
{
    "urls": ["https://apify.com", "https://web.dev"],
    "strategy": "both",
    "categories": ["performance", "seo"],
    "engine": "psi",
    "psiApiKey": "YOUR_GOOGLE_API_KEY"
}
```

### Output example

You can download the dataset in various formats such as JSON, HTML, CSV, or Excel.

```json
{
    "url": "https://web.dev/",
    "finalUrl": "https://web.dev/",
    "strategy": "mobile",
    "engine": "local",
    "performanceScore": 37,
    "accessibilityScore": 90,
    "bestPracticesScore": 100,
    "seoScore": 92,
    "lcpMs": 5427,
    "cls": 0.001,
    "tbtMs": 3584,
    "inpMs": null,
    "fcpMs": 5127,
    "ttfbMs": 230,
    "speedIndexMs": 5347,
    "opportunities": [
        {
            "id": "render-blocking-insight",
            "title": "Render-blocking requests",
            "savingsMs": 1600,
            "savingsBytes": null
        }
    ],
    "failedAuditsCount": 19,
    "fieldData": null,
    "reportUrl": "https://api.apify.com/v2/key-value-stores/<id>/records/lh-web-dev-da1284d15fd0-mobile.html?signature=...",
    "lighthouseVersion": "13.5.0",
    "cpuSlowdownMultiplier": 1.8,
    "durationSecs": 27.1,
    "error": null
}
```

With a PSI key, `fieldData` holds CrUX data, for example `{ "scope": "url", "overallCategory": "AVERAGE", "lcpMs": 2400, "lcpCategory": "FAST", "cls": 0.12, "inpMs": 180, "inpCategory": "FAST", ... }`, and `inpMs` is filled from it.

### Data fields

| Field                                            | Meaning                                                                 |
| ------------------------------------------------ | ----------------------------------------------------------------------- |
| `performanceScore` ... `seoScore`                | Lighthouse category scores, 0 to 100                                    |
| `lcpMs`, `cls`, `tbtMs`, `fcpMs`, `speedIndexMs` | Lab metrics from Lighthouse                                             |
| `ttfbMs`                                         | Server response time of the main document                               |
| `inpMs`                                          | Interaction to Next Paint, p75 from CrUX. Lab audits cannot measure INP |
| `opportunities`                                  | Top failing performance audits sorted by estimated time savings         |
| `failedAuditsCount`, `failedAudits`              | Audits scoring under 0.9 in the selected categories                     |
| `fieldData`                                      | CrUX real user data, URL level or origin fallback                       |
| `reportUrl`, `reportJsonUrl`                     | Full HTML report, and raw JSON when `includeJsonReport` is on           |
| `error`                                          | Why an audit failed, for example DNS error or HTTP 404                  |

### How much does a Lighthouse audit cost?

Pay per event. You pay only for **successful audits**. Failed and unreachable URLs are free.

- **PSI audit** with your own free key: **$0.0015** per URL and device ($1.50 per 1,000).
- **Local Lighthouse audit** in Chrome, premium, no key needed: $0.07 per URL and device ($70 per 1,000).
- **Run start:** $0.001 per run.

The Apify free plan's $5 monthly credit covers about 3,000 PSI audits.

### Tips for accurate and cheap audits

- **Use the PSI engine for large lists.** 512 MB memory is enough. It runs 20 audits in parallel by default. Lower it if Google answers with quota errors.
- **Local engine: 8 GB memory and concurrency 1.** Chrome needs about 2 CPU cores. Less CPU inflates TBT and lowers scores.
- **Local engine: keep `cpuSlowdown: auto`.** Cloud CPUs are slower than the machines Lighthouse assumes. Auto measures the CPU at start and scales the 4x mobile slowdown so numbers stay closer to PageSpeed Insights. Set `4` to match plain Lighthouse CLI.
- **Scores vary run to run.** This is normal for Lighthouse. For monitoring, compare medians of several runs.
- **Only need speed?** Select only `performance` to save a few seconds per audit.

### FAQ, limitations and support

**Is this the same as PageSpeed Insights?** The PSI engine returns exactly what the PageSpeed Insights API returns, normalized into one row. The local engine uses the same Lighthouse and simulated throttling on different hardware, so its lab numbers will not match PSI exactly.

**What happens without a key?** With the default PSI engine the run finishes right away with one dataset item that explains how to get a key. No audits are charged.

**Why is INP empty?** INP needs real user interactions. Lab tests cannot measure it. The PSI key adds INP from CrUX. TBT is the lab proxy for INP.

**Why did a page fail with HTTP\_ERROR\_STATUS?** The page answered with an HTTP error such as 403 or 404, often a bot blocker. Lighthouse would only score the error page, so the audit is reported as failed and not charged. HTTP 429 from PSI means Google throttles tests of that site for a while, or the site blocks Google. It is not charged. Retry later.

**Why is fieldData null with a key?** The page or origin has too little Chrome traffic to appear in the CrUX dataset.

**Can it audit pages behind a login?** No. Only public URLs.

**Is it legal?** You audit pages you choose, like running Lighthouse in your own browser. Lighthouse is open source under Apache 2.0. Audit only sites you are allowed to test and respect their terms.

Found a bug or need a custom version, for example budgets, sitemaps or Slack alerts? Open an issue in the **Issues** tab.

# Actor input Schema

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

Pages to audit with Lighthouse. One URL per line. Missing https:// is added automatically. Duplicates are removed.

## `engine` (type: `string`):

PSI (default) calls the Google PageSpeed Insights API with your own free key: no Chrome, 512 MB memory is enough, and you get real user CrUX field data. Without a key the run stops with a short setup guide and nothing is charged. Local runs Lighthouse in real Chrome inside the Actor with no key and no Google quota. Local needs 8 GB memory (set it in Run options) for credible scores.

## `psiApiKey` (type: `string`):

Free Google API key, takes 2 minutes. 1) Open the <a href='https://console.cloud.google.com/apis/library/pagespeedonline.googleapis.com'>PageSpeed Insights API page</a> in Google Cloud Console and click Enable (create a project if asked). 2) Open <a href='https://console.cloud.google.com/apis/credentials'>Credentials</a>, click Create credentials > API key. 3) Paste the key here. Free quota: 25,000 requests per day. Stored encrypted. Also adds CrUX field data when engine is Local.

## `strategy` (type: `string`):

Mobile uses a Moto G Power profile with slow 4G throttling, like PageSpeed Insights. Desktop uses a desktop profile. Both runs two audits per URL.

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

Lighthouse categories to run. Fewer categories make audits a bit faster.

## `throttling` (type: `string`):

Simulate (default) matches PageSpeed Insights and is the most stable. DevTools applies real network and CPU throttling and is slower. None measures raw speed from the Apify data center.

## `cpuSlowdown` (type: `string`):

Auto measures the CPU of the cloud machine and scales the Lighthouse 4x mobile CPU slowdown so Total Blocking Time is closer to PageSpeed Insights. Pick 4 to use the plain Lighthouse default.

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

How many audits run at the same time. Empty means 1 for the local engine and 20 for the PSI engine. Local engine: keep 1 for accurate scores, Chrome needs about 2 CPU cores (8 GB memory on Apify) per audit. Use 2 only with 16 GB. PSI engine: up to 20. Lower it if Google answers with quota errors.

## `includeFullReport` (type: `boolean`):

Save the full Lighthouse HTML report of every audit to the key-value store. The dataset item links to it in reportUrl.

## `includeJsonReport` (type: `boolean`):

Also save the raw Lighthouse JSON (LHR) of every audit, linked in reportJsonUrl. Only needed for your own tooling. The HTML report already contains the same data.

## `maxOpportunities` (type: `integer`):

How many top improvement opportunities to include, sorted by estimated time savings.

## `timeoutSecs` (type: `integer`):

Hard limit for one Lighthouse audit. Failed or timed out audits are retried once and are not charged.

## Actor input object example

```json
{
  "urls": [
    "https://apify.com"
  ],
  "engine": "psi",
  "strategy": "mobile",
  "categories": [
    "performance",
    "accessibility",
    "best-practices",
    "seo"
  ],
  "throttling": "simulate",
  "cpuSlowdown": "auto",
  "includeFullReport": true,
  "includeJsonReport": false,
  "maxOpportunities": 10,
  "timeoutSecs": 90
}
```

# Actor output Schema

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

No description

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

No description

# 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": [
        "https://apify.com"
    ],
    "engine": "psi"
};

// Run the Actor and wait for it to finish
const run = await client.actor("rod_analytics/lighthouse-audit").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": ["https://apify.com"],
    "engine": "psi",
}

# Run the Actor and wait for it to finish
run = client.actor("rod_analytics/lighthouse-audit").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": [
    "https://apify.com"
  ],
  "engine": "psi"
}' |
apify call rod_analytics/lighthouse-audit --silent --output-dataset

```

## MCP server setup

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

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/RatuAaIWL9RQ3xnfA/builds/4L9DB115Xv4RFwfn9/openapi.json
