# Bulk Lighthouse Site Audit: Speed, SEO & Accessibility (`jeremydonaldsonventure/bulk-lighthouse-site-audit`) Actor

Lighthouse scores, Core Web Vitals and a fix list for every page you list, or for a whole site read from its sitemap. Mobile and desktop. No API key, no PageSpeed quota. Pay only for pages audited.

- **URL**: https://apify.com/jeremydonaldsonventure/bulk-lighthouse-site-audit.md
- **Developed by:** [Jeremy DONALDSON](https://apify.com/jeremydonaldsonventure) (community)
- **Features:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $8.00 / 1,000 page audits

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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 Site Audit do?

**Bulk Lighthouse Site Audit** runs Google's open-source **Lighthouse** on every page you list, or on a **whole site read from its sitemap**, and returns **performance, accessibility, best-practice and SEO scores**, **Core Web Vitals with good / needs-improvement / poor ratings**, and a **ranked list of fixes** for each page. It runs mobile, desktop or both.

It runs Lighthouse in its own Chrome, so there is **no Google API key to set up and no PageSpeed Insights quota** to hit. You **only pay for pages that were audited**. Pages that are blocked, missing, broken or not HTML are listed free with the reason.

To try it, paste your home page into **Pages to audit**, tick **Read the sitemap**, and press **Start**.

### Why use it?

- 🌐 **Whole-site audits from one address.** Give a home page and it reads `robots.txt` and `sitemap.xml` (including sitemap indexes and `.gz` sitemaps) to find the pages.
- 📱 **Mobile and desktop in one run**, using the same device profiles Google's PageSpeed Insights uses.
- 🧭 **A site summary**, not just rows: average scores per device, the five slowest pages, and the checks that fail on the most pages.
- 🛠️ **Fixes, not just scores.** Each page lists its biggest speed wins (with estimated time and size savings) and every failed accessibility, best-practice and SEO check, with how many page elements fail it.
- 💸 **Failures are free.** 404s, DNS errors, non-HTML files and pages that `robots.txt` blocks cost nothing.
- 🤖 **Agent-ready.** Works as a tool in the Apify MCP server, so AI assistants such as Claude or ChatGPT can call it.
- ⏱️ Everything the Apify platform gives you: **schedules** (weekly site checks), **API** access, **webhooks**, and exports to **JSON, CSV, Excel** or **Google Sheets**.

### Who is it for?

- **SEO and web agencies** checking client sites before and after changes, or prospecting with a speed report.
- **Site owners and developers** tracking Core Web Vitals across every template, not just the home page.
- **Accessibility reviews**: Lighthouse's accessibility checks are built on the axe-core engine and catch common WCAG issues such as missing labels, low contrast and broken heading order.

### How to audit a website

1. Open the Actor and paste one or more page addresses into **Pages to audit**.
2. To audit the whole site, tick **Read the sitemap and audit the whole site** and set **Most pages to audit**.
3. Choose **Mobile**, **Desktop** or **Both**.
4. Press **Start**. Each audit takes about 10 to 30 seconds.
5. Open the **Output** tab: **Scores** for the overview, **Speed fixes** and **Failed checks** for the detail, and **Site summary** for the roll-up. Download as CSV or Excel, or send it to Google Sheets.

### How much does a Lighthouse audit cost?

You pay **per page audit**: one page on one device. A page on **Both** devices is two audits.

| | Price |
|---|---|
| Page audit | **$0.012** each ($12 per 1,000), lower on Apify's Silver and Gold plans |
| Run start | Apify's standard tiny start fee |
| Failed, blocked or skipped pages | **Free** |

Examples: a 50-page site on mobile is about **$0.60**. The same site on both devices is about **$1.20**. Apify's free plan includes monthly credit, enough for many test audits.

You can set a **maximum cost per run** when you start it. The Actor stops cleanly before it would go over, and you keep every result it finished.

### Input example

```json
{
    "startUrls": ["https://docs.apify.com", "https://www.python.org"],
    "crawlSitemap": true,
    "maxPages": 4,
    "device": "both",
    "maxOpportunities": 3
}
```

### Output example

One row per page per device (shortened):

```json
{
    "url": "https://www.python.org/",
    "device": "mobile",
    "status": "ok",
    "performanceScore": 88,
    "accessibilityScore": 75,
    "bestPracticesScore": 100,
    "seoScore": 92,
    "lcpMs": 3673,
    "lcpRating": "needs-improvement",
    "cls": 0.027,
    "clsRating": "good",
    "tbtMs": 0,
    "tbtRating": "good",
    "pageWeightKb": 464,
    "requestCount": 23,
    "opportunities": [
        { "id": "render-blocking-insight", "title": "Render-blocking requests", "displayValue": "Est savings of 1,390 ms", "savingsMs": 1400, "savingsKb": null }
    ],
    "failedChecks": [
        { "id": "color-contrast", "category": "accessibility", "title": "Background and foreground colors do not have a sufficient contrast ratio.", "itemCount": 10 }
    ],
    "failedCheckCount": 8,
    "lighthouseVersion": "13.5.0",
    "errorCode": null
}
```

A page that could not be audited comes back free, with the reason:

```json
{ "url": "https://example.com/this-page-does-not-exist", "device": "mobile", "status": "failed", "errorCode": "ERRORED_DOCUMENT_REQUEST", "errorMessage": "Lighthouse was unable to reliably load the page you requested. Make sure you are testing the correct URL and that the server is properly responding to all requests. (Status code: 404) Not charged." }
```

The **Site summary** (key-value store record `OUTPUT`) holds average scores per device, the five slowest pages, and the ten most common failed checks.

### Output fields

| Field | Meaning |
|---|---|
| `performanceScore`, `accessibilityScore`, `bestPracticesScore`, `seoScore` | Lighthouse scores, 0 to 100 |
| `lcpMs`, `cls`, `tbtMs`, `fcpMs` and their `...Rating` | Core Web Vitals and First Contentful Paint, rated against Google's published thresholds |
| `speedIndexMs`, `serverResponseMs`, `pageWeightKb`, `requestCount` | Load detail |
| `opportunities` | Speed fixes, biggest estimated saving first |
| `failedChecks` | Failed accessibility, best-practice and SEO checks, with element counts |
| `status`, `errorCode`, `errorMessage` | `ok` rows are charged; `failed` and `skipped` rows are not |
| `reportUrl` | Link to the full Lighthouse HTML report, if you turned that on |

### FAQ

**Why do my scores differ a little from PageSpeed Insights?**
Lighthouse scores move a few points between runs on any machine, PageSpeed Insights included. This Actor uses the same Lighthouse engine and device profiles. It reports **lab data**: it does not include the Chrome UX Report field data (real-visitor data) that PageSpeed Insights shows above its lab section.

**Where is INP?**
INP needs real visitors clicking. Lighthouse lab tests report **Total Blocking Time (TBT)** as the stand-in, as PageSpeed Insights does.

**Can it audit pages behind a login?**
No. It audits public pages only.

**Does it respect robots.txt?**
Yes. Pages a site's `robots.txt` asks bots not to load are skipped and not charged. Each site is loaded at most once every 2 seconds, one page at a time.

**Is it legal?**
The Actor loads each public page once, as a browser would, and measures it. Audit sites you own, manage, or have permission to test.

**Can I run it on a schedule?**
Yes. Save your input as a task and add an Apify schedule, for example every Monday. Add a webhook or the Google Sheets integration to get the results where you work.

**Something went wrong.**
Open an issue on the Actor's **Issues** tab with the run link. Rows with `status: "failed"` include Lighthouse's own error code, which usually explains it: the page timed out, returned an error, or isn't a web page.

# Actor input Schema

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

Full page addresses, one per line, for example https://example.com/pricing. https:// is added if you leave it off. With 'Read the sitemap' on, a home page is enough.

## `crawlSitemap` (type: `boolean`):

Finds more pages on the same site from its sitemap.xml (via robots.txt), up to 'Most pages to audit'. Pages the site's robots.txt blocks are skipped.

## `maxPages` (type: `integer`):

Cap on pages per run, including sitemap pages. Each page is audited once per device. Your run's spending limit also stops the run.

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

Mobile uses Lighthouse's slow-4G phone profile, the one Google uses for its mobile scores. 'Both' runs two audits per page.

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

Which Lighthouse categories to score. Fewer categories run a little faster; the price is the same.

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

How many performance fixes to list per page, biggest estimated saving first.

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

How long to wait for a slow page to finish loading before scoring what has loaded.

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

Saves the standard Lighthouse report page for each audit and adds its link to the results.

## Actor input object example

```json
{
  "startUrls": [
    "https://example.com"
  ],
  "crawlSitemap": false,
  "maxPages": 20,
  "device": "mobile",
  "categories": [
    "performance",
    "accessibility",
    "best-practices",
    "seo"
  ],
  "maxOpportunities": 5,
  "pageTimeoutSecs": 60,
  "saveHtmlReports": false
}
```

# Actor output Schema

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

One row per page per device: Lighthouse scores, Core Web Vitals with ratings, speed fixes and failed checks. Rows with status 'failed' or 'skipped' were not charged.

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

Average scores per device, the five slowest pages and the most common failed checks across the site.

# 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": [
        "https://example.com"
    ]
};

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

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

```

## MCP server setup

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