# Lighthouse Bulk Audit: Scores, Core Web Vitals, Top Fixes (`brasspage/lighthouse-bulk-audit`) Actor

Runs Google Lighthouse on a list of URLs, one at a time. Returns one row per URL: Performance, Accessibility, Best Practices and SEO scores, lab LCP, CLS, TBT, FCP, Speed Index and TTFB, and the top fixes. Mobile, desktop or both. $0.01 per URL; failed audits are free.

- **URL**: https://apify.com/brasspage/lighthouse-bulk-audit.md
- **Developed by:** [Brasspage](https://apify.com/brasspage) (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

from $10.00 / 1,000 url auditeds

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

### Lighthouse bulk audit: scores, Core Web Vitals and top fixes for a list of URLs

Paste a list of pages. For each one, the Actor runs **Google Lighthouse** in headless Chrome and returns one row with:

- **Four scores from 0 to 100:** Performance, Accessibility, Best Practices and SEO.
- **Lab metrics:** Largest Contentful Paint (LCP), Cumulative Layout Shift (CLS), Total Blocking Time (TBT), First Contentful Paint (FCP), Speed Index and Time to First Byte (TTFB).
- **Top fixes:** the changes Lighthouse says matter most, with the time each speed fix saves.

**$0.01 per URL.** Pages that do not load, that Lighthouse cannot score, or that robots.txt blocks are free.

### Quick start

1. Paste URLs or domains into **Pages to audit**, one per line.
2. Pick **Mobile**, **Desktop** or **Both**.
3. Click **Start**. Each page takes about 10 to 30 seconds, one page at a time.
4. Download the table as CSV, Excel or JSON, or read it through the API.

### What can you do with it?

- **Check a whole site after a release:** paste your key pages and compare the scores with last week's run.
- **Find the slowest pages:** sort by `performance` or `lcpMs` and fix those first.
- **Audit client or prospect sites:** an agency can show a list of sites with their scores and the top 3 fixes for each.
- **Schedule it:** run it every week with Apify Schedules and keep a history of your scores.
- **AI agents:** call the Actor as a tool (Apify API or Apify MCP server) to answer "Which of these 40 landing pages has the worst LCP on mobile?".

### Input example

```json
{
    "urls": ["https://www.spacejam.com/1996/", "https://example.com"],
    "device": "mobile",
    "topFixes": 3
}
```

| Field      | What it does                                                                                                         |
| ---------- | -------------------------------------------------------------------------------------------------------------------- |
| `urls`     | Required. Domains or http(s) URLs. A domain is tested over HTTPS. Duplicates are removed. Other schemes are ignored. |
| `device`   | `mobile` (default), `desktop`, or `both`. `both` makes 2 rows and 2 charges per URL.                                 |
| `topFixes` | How many fixes to list per page, 0 to 10. Default 3.                                                                 |

### Output example

One item per URL and device (from a real run):

```json
{
    "url": "https://www.spacejam.com/1996/",
    "finalUrl": "https://www.spacejam.com/1996/",
    "device": "mobile",
    "status": "ok",
    "performance": 99,
    "accessibility": 85,
    "bestPractices": 88,
    "seo": 91,
    "lcpMs": 2003,
    "cls": 0,
    "tbtMs": 3,
    "fcpMs": 945,
    "speedIndexMs": 1043,
    "ttfbMs": 600,
    "topFixes": [
        { "id": "modern-http-insight", "category": "performance", "title": "Modern HTTP", "savingsMs": 650 },
        { "id": "cache-insight", "category": "performance", "title": "Use efficient cache lifetimes", "savingsMs": 200 },
        {
            "id": "html-has-lang",
            "category": "accessibility",
            "title": "`<html>` element does not have a `[lang]` attribute",
            "savingsMs": null
        }
    ],
    "lighthouseVersion": "13.5.0",
    "benchmarkIndex": 3886,
    "error": null,
    "auditedAt": "2026-10-21T08:30:00.000Z"
}
```

| Field                                                  | Meaning                                                                                                                                                                                                                                                     |
| ------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `status`                                               | `ok` (scored and charged), `skipped` (robots.txt, free) or `error` (did not load or could not be scored, free).                                                                                                                                             |
| `performance`, `accessibility`, `bestPractices`, `seo` | Lighthouse category scores, 0 to 100.                                                                                                                                                                                                                       |
| `lcpMs`, `tbtMs`, `fcpMs`, `speedIndexMs`, `ttfbMs`    | Lab metrics in milliseconds. These are the values Lighthouse scores.                                                                                                                                                                                        |
| `cls`                                                  | Cumulative Layout Shift (no unit).                                                                                                                                                                                                                          |
| `topFixes`                                             | Speed fixes come first, largest time saved first. `savingsMs` is Lighthouse's estimate of the time saved on LCP, FCP or TBT, whichever is largest. Then failed checks from Accessibility, Best Practices and SEO, the ones that cost the most points first. |
| `finalUrl`                                             | The page Lighthouse ended on, after redirects.                                                                                                                                                                                                              |
| `benchmarkIndex`                                       | Lighthouse's measure of the test machine's CPU speed. Useful when you compare runs.                                                                                                                                                                         |
| `error`, `skipReason`                                  | Why a page has no scores.                                                                                                                                                                                                                                   |

### Lab data, not field data

Lighthouse measures one page load in a test browser. That is **lab data**. It is good for finding problems and for comparing runs over time.

- **INP is not measured.** Interaction to Next Paint needs real people clicking. TBT is the lab metric that tracks it best.
- **Scores move between runs.** A few points of difference between two runs of the same page is normal. Compare trends, not single numbers.
- **PageSpeed Insights can show different numbers.** It runs on Google's machines, and it also shows field data from real Chrome users (the Chrome UX Report). This Actor shows lab data only.

Mobile runs use Lighthouse's default mobile settings: a mid-range phone on a slow 4G connection, simulated. Desktop runs use Lighthouse's desktop settings.

### Pricing

- **$0.01 per URL audited** (per URL and device, so `both` costs $0.02 per URL).
- Pages that robots.txt blocks, that do not load, or that Lighthouse cannot score are **not charged**.
- A tiny Actor start event (Apify's standard start charge) applies once per run.
- Set a **maximum total charge** on the run and the Actor stops before it goes over.

**Apify free plan:** each run audits the first 10 URLs. Upgrade to a paid Apify plan to audit any number in one run.

### Polite and safe

- The Actor reads each site's **robots.txt** first. A page that robots.txt blocks for Lighthouse (`Chrome-Lighthouse`) or for all bots (`*`) is skipped.
- It audits **one page at a time**, so a site never gets more than one Lighthouse visit at once.
- It loads **public internet pages only**. Every request the browser makes (the page, each redirect, each image or script) goes through a check that refuses private and local network addresses.

### FAQ

**How long does a run take?** About 10 to 30 seconds per page, one page at a time. Heavy pages take longer. A page that takes over 2 minutes is stopped and not charged.

**Can I audit pages behind a login?** No. The Actor tests public pages only, with no cookies.

**Which Lighthouse version?** The version used is in `lighthouseVersion` on every row.

**Does it use PageSpeed Insights?** No. It runs Lighthouse itself, so there is no Google API key and no PageSpeed Insights quota.

# Actor input Schema

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

One page per line: a domain (example.com) or a full URL (https://www.example.com/pricing). A domain is tested over HTTPS. A URL that starts with http:// is tested as given. On the Apify free plan, a run audits the first 10 URLs.

## `device` (type: `string`):

Mobile uses Lighthouse's phone settings (a mid-range phone on a slow 4G connection, simulated), as PageSpeed Insights does. Desktop uses its desktop settings. Both makes two rows and two charges per URL.

## `topFixes` (type: `integer`):

How many fixes to list for each page (0 to 10).

## Actor input object example

```json
{
  "urls": [
    "https://www.spacejam.com/1996/",
    "https://example.com"
  ],
  "device": "mobile",
  "topFixes": 3
}
```

# Actor output Schema

## `audits` (type: `string`):

One item per URL and device: the four category scores (0 to 100), lab metrics in milliseconds (CLS has no unit), the top fixes, and the Lighthouse version. Skipped and failed pages say why.

# 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://www.spacejam.com/1996/",
        "https://example.com"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("brasspage/lighthouse-bulk-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://www.spacejam.com/1996/",
        "https://example.com",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("brasspage/lighthouse-bulk-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://www.spacejam.com/1996/",
    "https://example.com"
  ]
}' |
apify call brasspage/lighthouse-bulk-audit --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,brasspage/lighthouse-bulk-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/LGwGVg2SYrr6YGkZy/builds/3uERkbUvaeXiKygdW/openapi.json
