# Bulk Lighthouse Audit – No API Key Needed (`refillflows/bulk-lighthouse-audit`) Actor

Run real Google Lighthouse on a list of URLs or a whole sitemap: Performance, Accessibility, Best Practices and SEO scores, LCP/CLS/TBT, top fixes with savings, failed audits and HTML reports. No PageSpeed API key or quota required. Export CSV or use in CI.

- **URL**: https://apify.com/refillflows/bulk-lighthouse-audit.md
- **Developed by:** [Refill Flows](https://apify.com/refillflows) (community)
- **Categories:** SEO tools, Developer tools, Automation
- **Features:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $10.00 / 1,000 lighthouse audit (local engine)s

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

Run **real Google Lighthouse** on a list of URLs or a **whole sitemap**, on mobile and desktop, with this **Bulk Lighthouse Audit**. No PageSpeed Insights API key and no shared quota. For every page you get:

- **Performance, Accessibility, Best Practices and SEO scores** (0–100)
- **Core Web Vitals lab metrics**: LCP, CLS and TBT, plus FCP, Speed Index, TTI, TTFB, page weight, DOM size and request count, each rated good, needs improvement or poor
- **The top fixes**, ranked by estimated time and bytes saved
- **Failing accessibility, SEO and best-practice checks**, listed by name
- The **LCP element** and LCP breakdown (TTFB vs render delay)
- An optional **shareable HTML Lighthouse report** for each page
- Optional **real-user CrUX field data** (p75 LCP, INP, CLS, FCP and TTFB, with pass or fail) when you add a free Google API key
- A **site summary** (`SUMMARY`): average scores, the slowest pages and the Core Web Vitals pass rate

Try it with the prefilled `https://example.com` input, or point it at your sitemap.

### Why this Lighthouse checker?

- **No API key and no quota.** Most bulk PageSpeed tools call Google's PageSpeed Insights API and break when its shared quota runs out. This Actor runs Lighthouse 13 inside its own Chrome, so it works on day one. If you have a key, you can switch to the PSI engine, which is cheaper, and add real-user CrUX data.
- **Sitemap in, audit out.** Paste `https://yoursite.com/sitemap.xml`. Sitemap indexes and `.gz` files are handled for you.
- **Stable numbers.** Set `runsPerUrl: 3` and the Actor keeps the median run, as Google recommends.
- **Made for monitoring and CI.** Set a `performanceThreshold` budget, get `passedThreshold` per page, schedule daily runs and send results to Slack, Sheets or a webhook.
- **Easy for AI agents.** A flat JSON schema and clear field names make it a simple [MCP](https://docs.apify.com/platform/integrations/mcp) tool for "audit this site's speed".

### Who is it for?

- SEO and web agencies running monthly client speed and SEO reports across hundreds of URLs.
- Ecommerce teams checking that every product template passes Core Web Vitals after a release.
- Developers who want a deploy pipeline to fail when performance drops below budget.
- Sales teams prospecting agencies who want to find slow sites to pitch speed work to.

### How to run a bulk Lighthouse audit

1. Open the [Bulk Lighthouse Audit](https://apify.com/refillflows/bulk-lighthouse-audit) and click **Try for free**.
2. Paste one or more URLs, or a sitemap URL. The form is prefilled with `https://example.com`.
3. Keep **Devices** on `mobile` for a first run, or add `desktop`. Leave **Save full HTML Lighthouse reports** off unless you need the shareable report.
4. Click **Start**. When the run finishes, open the dataset for scores and Core Web Vitals, and the key-value store for the `SUMMARY` record. Export **CSV** or JSON, or pull results through the API.

A single mobile audit usually finishes in well under a minute.

### How much does a Lighthouse audit cost?

| Event | Price |
|---|---|
| Actor start | $0.005 per run (charged per GB of memory; this Actor defaults to 2 GB, so $0.01) |
| Lighthouse audit (local engine, no key) | **$0.01 per page per device** |
| Audit with your PageSpeed API key | **$0.003 per page per device** |

So a 100-page site on mobile costs about $1.00, or $2.00 for mobile plus desktop. With your own Google key it is $0.30 per 100 pages. Platform usage is included. Pages that cannot load are reported with an `error` field and are not charged.

### Input

```json
{
  "sitemapUrls": ["https://crawlee.dev/sitemap.xml"],
  "urls": ["https://apify.com", "https://example.com"],
  "maxUrls": 50,
  "strategies": ["mobile", "desktop"],
  "performanceThreshold": 80,
  "runsPerUrl": 1,
  "saveHtmlReports": true
}
```

### Output

One page, mobile, shortened:

```json
{
  "url": "https://www.python.org/",
  "strategy": "mobile",
  "engine": "local",
  "finalUrl": "https://www.python.org/",
  "lighthouseVersion": "13.6.0",
  "scores": {
    "performance": 86,
    "accessibility": 75,
    "bestPractices": 100,
    "seo": 92
  },
  "metrics": {
    "firstContentfulPaintMs": 2189,
    "largestContentfulPaintMs": 3786,
    "totalBlockingTimeMs": 13,
    "cumulativeLayoutShift": 0.003,
    "speedIndexMs": 2189,
    "timeToInteractiveMs": 3786,
    "serverResponseTimeMs": 71,
    "totalByteWeight": 474666,
    "domSize": 913,
    "networkRequests": 23
  },
  "labCwv": {
    "lcp": "needs-improvement",
    "cls": "good",
    "tbt": "good"
  },
  "labCwvAssessment": "needs-improvement",
  "opportunities": [
    {
      "id": "unused-css-rules",
      "title": "Reduce unused CSS",
      "displayValue": "Est savings of 129 KiB",
      "savingsMs": 710,
      "savingsBytes": 131609
    }
  ],
  "failedAudits": {
    "accessibility": ["Background and foreground colors do not have a sufficient contrast ratio."],
    "seo": ["Links do not have descriptive text"],
    "bestPractices": []
  },
  "passedThreshold": true,
  "fieldData": null,
  "runs": 1,
  "error": null,
  "auditedAt": "2026-11-10T20:23:47.897Z"
}
```

The dataset has two views: **Scores & Core Web Vitals**, and **Top fixes** with one row per recommendation. The `SUMMARY` record in the key-value store holds the site-level averages.

### How to run Lighthouse in bulk with Python

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("refillflows/bulk-lighthouse-audit").call(run_input={
    "urls": ["https://example.com"],
    "strategies": ["mobile"],
    "saveHtmlReports": False,
})
for row in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(row["url"], row["scores"], row["labCwv"])
```

Schedule it daily, set a `performanceThreshold`, and post `passedThreshold: false` rows to Slack or a webhook from a CI pipeline.

### Notes and tips

- Lab scores come from a simulated mid-range phone on slow 4G, the same method PageSpeed Insights uses. They differ slightly between machines, so use `runsPerUrl` of 3 or more when you need precise numbers. Real-user (CrUX) data needs a Google API key.
- To get a free Google API key, open Google Cloud Console, go to APIs & Services, enable the **PageSpeed Insights API** and the **Chrome UX Report API**, and create an API key.
- Keep `maxConcurrency` at 1 for the most accurate local scores. Use 2–4 with 4 GB or more of memory when you need speed.
- Pages that can't load (DNS errors, interstitials, no content painted) are reported with an `error` field and aren't charged.

### FAQ

#### Do I need a PageSpeed Insights API key?

No. The default local engine runs Lighthouse 13 in Chrome inside the Actor, so there is no Google quota to run out of. Add a key only if you want cheaper PSI-backed audits and real-user CrUX field data.

#### Can I audit a whole sitemap?

Yes. Paste your `sitemap.xml` (indexes and `.gz` files are fine) and set **Max URLs**. The Actor collects the loc entries, de-duplicates them, and audits each page.

#### How is this different from pagespeed.web.dev?

pagespeed.web.dev tests one URL at a time in your browser. This Actor does the same style of Lighthouse audit in bulk, on a schedule, and returns a dataset you can export to CSV, send to Sheets, or assert on in CI.

#### May I audit any website?

The Actor loads only the pages you give it, the same way a normal browser visit does. Only audit sites you own or are allowed to test.

### Other tools by Refill Flows

- [Luma Events Scraper](https://apify.com/refillflows/luma-events-scraper) — public Luma (lu.ma) events by city, category or calendar.
- [Shopify App Store Scraper](https://apify.com/refillflows/shopify-app-store-scraper) — app rankings, pricing plans and merchant reviews.

### Support

Open an issue on the **Issues** tab. Maintained by [Refill Flows](https://apify.com/refillflows).

# Actor input Schema

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

Pages to audit. Domains without https:// are fine.

## `sitemapUrls` (type: `array`):

Audit pages from XML sitemaps (sitemap indexes and .gz supported), up to Max URLs.

## `maxUrls` (type: `integer`):

Cap on the number of pages audited (per strategy).

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

Mobile (Moto G Power, slow 4G throttling — Google's default) and/or desktop.

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

Which scores to compute. Fewer categories = faster.

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

auto = PageSpeed Insights API when a Google API key is provided, otherwise real Lighthouse runs inside the Actor (no key or quota needed).

## `googleApiKey` (type: `string`):

Free key from Google Cloud with PageSpeed Insights API and Chrome UX Report API enabled. Unlocks real-user Core Web Vitals (CrUX field data: LCP, INP, CLS p75) and the cheaper PSI engine.

## `includeFieldData` (type: `boolean`):

Requires a Google API key. Falls back from URL-level to origin-level data.

## `runsPerUrl` (type: `integer`):

Run Lighthouse several times and keep the median performance run (Google recommends 3-5 for stable numbers). Each run is billed.

## `performanceThreshold` (type: `integer`):

Optional. Adds passedThreshold = true/false per page; useful for CI/monitoring alerts.

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

How many 'fix this first' recommendations (with estimated savings) to include.

## `includeFailedAudits` (type: `boolean`):

Adds the titles of failing audits per category.

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

Stores the shareable Lighthouse HTML report for each page in the key-value store and adds reportUrl (local engine only).

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

Local engine: 1 gives the most stable scores (CPU contention skews metrics). Use 2-4 with 4+ GB memory for speed. PSI engine: up to 10.

## `auditTimeoutSecs` (type: `integer`):

Abort a single page audit after this time.

## Actor input object example

```json
{
  "urls": [
    "https://example.com"
  ],
  "sitemapUrls": [],
  "maxUrls": 50,
  "strategies": [
    "mobile"
  ],
  "categories": [
    "performance",
    "accessibility",
    "best-practices",
    "seo"
  ],
  "engine": "auto",
  "includeFieldData": true,
  "runsPerUrl": 1,
  "maxOpportunities": 5,
  "includeFailedAudits": true,
  "saveHtmlReports": false,
  "maxConcurrency": 1,
  "auditTimeoutSecs": 120
}
```

# Actor output Schema

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

No description

## `summary` (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://example.com"
    ]
};

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

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

```

## MCP server setup

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