# Lighthouse Bulk Auditor: Core Web Vitals and SEO for many URLs (`reflexdev/lighthouse-bulk-auditor`) Actor

Bulk Lighthouse audits for a URL list or an entire XML sitemap. One row per page with performance, accessibility, best-practices and SEO scores, Core Web Vitals (LCP, CLS, TBT) and the top fixes. No Google API key, no PageSpeed quota.

- **URL**: https://apify.com/reflexdev/lighthouse-bulk-auditor.md
- **Developed by:** [Rishad M](https://apify.com/reflexdev) (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 $15.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 Auditor: Core Web Vitals, SEO and accessibility for many URLs

Run **Google Lighthouse** on a list of URLs or a whole **XML sitemap** and get one clean row per page: performance, accessibility, best-practices and SEO scores, **Core Web Vitals** (LCP, CLS, TBT), and the **top fixes** ranked by estimated time saved.

- **No API key and no PageSpeed Insights quota.** Lighthouse runs inside the Actor in real headless Chrome, so you never hit "Quota exceeded" errors.
- **Mobile and desktop**, using the same emulation settings as PageSpeed Insights.
- **Whole-site audits from a sitemap**, including sitemap indexes and `.gz` sitemaps.
- **Pass/fail performance budget** so you can filter failing pages or alert on them.
- **Pay only for successful audits.** Pages that can't be loaded are listed with the reason and aren't charged as audits.

### What can this Lighthouse auditor do?

| Use case | How |
| --- | --- |
| SEO agency monthly client reports | Paste client URLs, export to Excel/Google Sheets |
| Find the slowest pages on a site | Give the sitemap, sort by `largestContentfulPaintMs` |
| Catch regressions after a release | Schedule a daily run with a performance budget and a webhook / Slack integration |
| Prospecting: find businesses with slow sites | Audit their homepages and pitch the top fixes |
| Accessibility and SEO checks | `failedSeoOrA11yAudits` lists failing checks per page (missing alt text, missing meta description, low contrast...) |

### How much does it cost to run Lighthouse audits?

This Actor uses **pay-per-event** pricing: you pay a fixed price for each successful audit (one URL on one device). See the **Pricing** tab for the current price. Auditing 100 pages on mobile is 100 audits; mobile + desktop is 200 audits. Failed pages aren't charged as audits. Apify also adds a tiny run-start event (a fraction of a cent per run), so a run where every page fails still costs almost nothing, but not exactly zero.

Set **Maximum cost per run** in the run options to cap your spend; the Actor stops cleanly when it reaches the limit.

### How to use it

1. Click **Try for free**.
2. Add your URLs, or paste a sitemap URL such as `https://www.example.com/sitemap.xml`.
3. Pick **Mobile**, **Desktop**, or both.
4. Optional: set a **Performance budget** (for example 70).
5. Click **Start** and download results as JSON, CSV, Excel or HTML, or use the API.

### Ready-made setups

Not sure where to start? These saved inputs run as-is, and you can swap in your own URLs:

- [**Sitemap audit (desktop)**](https://apify.com/reflexdev/lighthouse-bulk-auditor/examples/sitemap-lighthouse-audit-desktop): read a sitemap and audit the first pages on desktop.
- [**Mobile Core Web Vitals check**](https://apify.com/reflexdev/lighthouse-bulk-auditor/examples/mobile-core-web-vitals-check): performance only, with a pass/fail budget.
- [**Accessibility-only pass**](https://apify.com/reflexdev/lighthouse-bulk-auditor/examples/accessibility-audit-bulk): accessibility score plus the failing checks per page.
- [**SEO-only pass**](https://apify.com/reflexdev/lighthouse-bulk-auditor/examples/seo-audit-bulk): SEO score plus failing checks such as missing meta descriptions.

### Input

| Field | Description | Default |
| --- | --- | --- |
| `startUrls` | URLs to audit | – |
| `sitemapUrl` | XML sitemap or sitemap index to read URLs from | – |
| `maxSitemapUrls` | Cap on pages taken from the sitemap | 50 |
| `strategies` | `mobile`, `desktop` or both | `["mobile"]` |
| `categories` | `performance`, `accessibility`, `best-practices`, `seo` | all four |
| `minPerformanceScore` | Budget; adds `passedPerformanceBudget` true/false | 0 (off) |
| `maxOpportunities` | Number of top fixes per page | 5 |
| `saveHtmlReports` | Store the full Lighthouse HTML report per page | false |
| `pageTimeoutSecs` | Max seconds per page | 60 |

Example input:

```json
{
  "startUrls": [{ "url": "https://www.example.com" }],
  "sitemapUrl": "https://www.example.com/sitemap.xml",
  "maxSitemapUrls": 100,
  "strategies": ["mobile", "desktop"],
  "minPerformanceScore": 70
}
```

### Output

One row per URL and device. Example (real output from a test run):

```json
{
  "url": "https://www.govt.nz/",
  "finalUrl": "https://www.govt.nz/",
  "strategy": "mobile",
  "status": "ok",
  "errorMessage": null,
  "scores": { "performance": 97, "accessibility": 100, "bestPractices": 100, "seo": 100 },
  "firstContentfulPaintMs": 934,
  "largestContentfulPaintMs": 1834,
  "totalBlockingTimeMs": 152,
  "cumulativeLayoutShift": 0,
  "speedIndexMs": 3094,
  "timeToInteractiveMs": 5280,
  "serverResponseTimeMs": 1371,
  "passedPerformanceBudget": true,
  "topOpportunities": [
    { "id": "server-response-time", "title": "Reduce initial server response time", "estimatedSavingsMs": 1271, "estimatedSavingsBytes": 0, "displayValue": "Root document took 1,370 ms" }
  ],
  "failedSeoOrA11yAudits": [],
  "lighthouseVersion": "13.6.0",
  "auditedAt": "2026-11-01T01:07:05.765Z",
  "auditDurationSecs": 11.8
}
```

Columns for categories you didn't select are `null`. For example, an accessibility-only run has no Core Web Vitals.

The **Scores and Core Web Vitals** view gives a flat table that's ready for spreadsheets. The **Top fixes** view lists the biggest opportunities per page.

### Run it from the API

Start a run and get the results in one call (replace `YOUR_TOKEN`):

```bash
curl -X POST "https://api.apify.com/v2/acts/reflexdev~lighthouse-bulk-auditor/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"sitemapUrl": "https://www.example.com/sitemap.xml", "maxSitemapUrls": 20, "strategies": ["mobile"]}'
```

Synchronous calls time out after 5 minutes, so use the normal asynchronous run endpoint for large sitemaps.

### Tips

- Lighthouse scores naturally vary by a few points between runs (network, ads and third-party scripts). For trend tracking, compare averages over several runs, not single numbers.
- Audits run from Apify's cloud (US data centres). Server response time for sites hosted far away, such as in New Zealand or Australia, will be higher than from a local machine.
- Pages are audited **one at a time** on purpose. Running audits in parallel in one browser distorts performance scores.
- A single audit usually takes 10–40 seconds, depending on the page and which categories you pick. Performance-only and SEO-only runs are the quickest.
- If you turn on **Save full HTML Lighthouse reports**, each report includes a screenshot of the page. Keep that in mind for pages that show personal data.
- Lab data (this Actor) is not the same as Chrome UX Report field data shown at the top of PageSpeed Insights. Lab data is reproducible and works for any page, including pages with little traffic.

**Further reading:** [How to run Lighthouse on every page in your sitemap (without a PageSpeed API key)](https://dev.to/reflexdev/how-to-run-lighthouse-on-every-page-in-your-sitemap-without-a-pagespeed-api-key-43cn), a step-by-step walkthrough on dev.to.

### FAQ

**Do I need a Google API key?** No.

**Can it audit pages behind a login?** Not in this version.

**Is it legal?** The Actor loads public pages once, like a normal browser visit, and measures them with Google's open-source Lighthouse (Apache-2.0). It doesn't collect personal data. Only audit sites you own or have permission to test, and keep volumes reasonable.

**Something broke or you need a feature?** Open an issue on the **Issues** tab. Every issue gets read.

### Did this help?

If this Actor saved you time, a short review on the Store page is much appreciated. It's the main way other people find it, and it tells me what to improve next.

# Actor input Schema

## `startUrls` (type: `array`):

Pages to audit with Lighthouse. Add one URL per line. You can also give a sitemap below, or both.

## `sitemapUrl` (type: `string`):

Audit pages listed in an XML sitemap (sitemap index and .gz files are supported). Example: https://www.example.com/sitemap.xml

## `maxSitemapUrls` (type: `integer`):

Upper limit on the number of sitemap pages to audit. Each page and device counts as one audit.

## `strategies` (type: `array`):

Run the audit as mobile (Moto G Power, slow 4G, like PageSpeed Insights) and/or desktop. Choosing both doubles the number of audits.

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

Which Lighthouse category scores to calculate.

## `minPerformanceScore` (type: `integer`):

If set above 0, each row gets passedPerformanceBudget = true/false, so you can filter failing pages or alert on them. Leave 0 to skip.

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

How many of the biggest improvement opportunities (estimated time and byte savings) to include for each page.

## `saveHtmlReports` (type: `boolean`):

Also store the full, shareable Lighthouse HTML report for each audit in the key-value store and add its link to the row.

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

Maximum time for a single page to load and be audited before it is reported as an error.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://apify.com"
    }
  ],
  "sitemapUrl": "",
  "maxSitemapUrls": 50,
  "strategies": [
    "mobile"
  ],
  "categories": [
    "performance",
    "accessibility",
    "best-practices",
    "seo"
  ],
  "minPerformanceScore": 0,
  "maxOpportunities": 5,
  "saveHtmlReports": false,
  "pageTimeoutSecs": 60
}
```

# Actor output Schema

## `overview` (type: `string`):

No description

## `fixes` (type: `string`):

No description

## `results` (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 = {
    "startUrls": [
        {
            "url": "https://apify.com"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("reflexdev/lighthouse-bulk-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 = { "startUrls": [{ "url": "https://apify.com" }] }

# Run the Actor and wait for it to finish
run = client.actor("reflexdev/lighthouse-bulk-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 '{
  "startUrls": [
    {
      "url": "https://apify.com"
    }
  ]
}' |
apify call reflexdev/lighthouse-bulk-auditor --silent --output-dataset

```

## MCP server setup

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