# Bulk PageSpeed Insights Checker: Lighthouse & Core Web Vitals (`michael80/pagespeed-core-web-vitals-bulk-monitor`) Actor

Bulk-audit URLs or a whole sitemap with Google PageSpeed Insights: Lighthouse scores, lab metrics, real-user Core Web Vitals (CrUX) with pass/fail, and the top 3 fixes, mobile and desktop in one CSV-ready row. Optional monitoring flags real changes. Failed pages are free.

- **URL**: https://apify.com/michael80/pagespeed-core-web-vitals-bulk-monitor.md
- **Developed by:** [Michael Schönherr](https://apify.com/michael80) (community)
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 page 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

## Bulk PageSpeed Insights Checker: Lighthouse & Core Web Vitals

Audit a list of URLs or a whole **sitemap** with Google's official **PageSpeed Insights** and get **one CSV-ready row per URL**, mobile and desktop side by side:

- **Lighthouse scores:** Performance, Accessibility, Best Practices, SEO (0–100)
- **Lab metrics:** LCP, FCP, TBT, CLS, Speed Index
- **Real-user Core Web Vitals (CrUX):** LCP, INP, CLS, FCP, TTFB at the 75th percentile, with a clear **passed / failed** result and whether the data is for the page or the whole site
- **Top 3 fixes** with the estimated time saved, e.g. *"Render-blocking requests (~1.5 s)"*
- **A link to the full Google report** for every URL

**Monitoring built in:** give the run a name and schedule it. Every run is compared with the previous one, and `significantChange` tells you when something really moved (10+ points or a changed Core Web Vitals result), instead of alerting on Lighthouse's normal noise.

**No setup:** an API key is built in. Pages that cannot be audited are **free**.

### Who uses it

| You are | You use it to |
| --- | --- |
| SEO / web agency | Monthly speed reports for all clients, sitemap-wide audits, proof of improvements |
| Shop or site owner | Find the slowest templates and the fixes with the biggest impact |
| Developer team | Catch performance regressions after releases with scheduled monitoring |
| AI agents | Call it as an MCP tool: *"Which of my 200 pages fail Core Web Vitals on mobile?"* |

### Output (one row per URL)

Columns are prefixed with `mobile_` and `desktop_`:

| Field | Example | Meaning |
| --- | --- | --- |
| `url`, `finalUrl` | `https://www.example.com/` | input and URL after redirects |
| `status` | `ok` | `ok`, `partial` (one device failed), `error`, `invalid` |
| `mobile_performance` … `mobile_seo` | `62`, `91`, `96`, `100` | Lighthouse category scores |
| `mobile_lcpMs`, `mobile_fcpMs`, `mobile_tbtMs`, `mobile_cls`, `mobile_speedIndexMs` | `4322`, `1840`, `350`, `0.045`, `3901` | lab metrics |
| `mobile_fieldLcpMs`, `mobile_fieldInpMs`, `mobile_fieldCls`, `mobile_fieldFcpMs`, `mobile_fieldTtfbMs` | `3100`, `180`, `0.08` | real users, p75 (CrUX) |
| `mobile_fieldScope` | `url` / `origin` | page-level data or whole-site fallback |
| `mobile_cwvAssessment` | `failed` | `passed`, `failed`, `no-field-data` |
| `mobile_topIssues` | `["Render-blocking requests (~1.5 s)", …]` | biggest savings first |
| `mobile_performanceChange`, `significantChange` | `-18`, `true` | only with monitoring |
| `reportUrl` | `https://pagespeed.web.dev/analysis?url=…` | full Google report |
| `lighthouseVersion`, `fetchedAt`, `errors` | | transparency |

The **Overview** table shows the most important columns; export everything as CSV, Excel, JSON or via API.

**Core Web Vitals thresholds used (p75, "good"):** LCP ≤ 2.5 s, INP ≤ 200 ms, CLS ≤ 0.1, as defined by Google on web.dev. Sites with too little traffic have no real-user data; you then still get all lab metrics and `no-field-data`.

### Pricing

Pay per audit, no subscription. **One audit = one URL on one device.**

| Event | Price |
| --- | --- |
| `page-audited` | $5.00 per 1,000 audits (a URL on mobile + desktop = 2 audits = $0.010) |
| Page could not be loaded, API error, invalid input | free |

Set a maximum cost per run in Apify; the Actor stops cleanly when it is reached.

### Input example

```json
{
  "urls": ["https://www.example.com", "apify.com"],
  "sitemapUrl": "https://www.example.com/sitemap.xml",
  "maxSitemapUrls": 100,
  "strategies": ["mobile", "desktop"],
  "monitorName": "client-a",
  "locale": "en"
}
```

### Tips

- **Weekly monitoring:** schedule the Actor with a `monitorName` and connect a Slack or email integration that triggers when `significantChange` is `true`.
- **Scores vary** a few points between runs because Lighthouse simulates a real device. Compare trends and use `significantChange`, not single points.
- **Audit titles in your language:** set `locale`, e.g. `de` for German.

### FAQ

**Do I need a Google API key?** No. You can add your own key for very large volumes; it is stored encrypted.

**Why is a page marked `error`?** Google's Lighthouse could not load it (for example: blocked for bots, 404, timeout). The reason is in `errors`, and you are not charged.

**Something wrong or missing?** Open an issue on the Actor page. We usually answer within one business day.

***

### Kurz auf Deutsch

Prüft beliebig viele URLs oder eine ganze Sitemap mit Google PageSpeed Insights: Lighthouse-Werte, Labormesswerte, echte Core Web Vitals (CrUX) mit Bestanden/Nicht bestanden und die 3 wichtigsten Verbesserungen, mobil und Desktop in einer Zeile. Mit Monitoring-Funktion für echte Veränderungen. Nicht prüfbare Seiten sind kostenlos. Tipp: `locale: "de"` für deutsche Audit-Titel.

***

**Anbieter / Impressum (Angaben gemäß § 5 DDG):** Michael Schönherr · Am Spiegelwald 1 · 08344 Grünhain-Beierfeld · Deutschland · E-Mail: m.schoenherr80@gmail.com

# Changelog

This Actor's version history is a separate document: https://apify.com/michael80/pagespeed-core-web-vitals-bulk-monitor/changelog.md

# Actor input Schema

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

One URL per line. 'example.com' is treated as 'https://example.com'. Duplicates are removed.

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

Audit the pages listed in a sitemap.xml (sitemap indexes and .xml.gz supported). Combined with the URLs above.

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

Upper limit of pages taken from the sitemap, so costs stay predictable.

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

Each device is one audit. Mobile is what Google uses for ranking.

## `monitorName` (type: `string`):

Set a name (e.g. 'client-a') and schedule the Actor. Each run is compared with the previous run of the same name: you get the score change and 'significantChange' = true for moves of 10+ points or a changed Core Web Vitals result.

## `apiKey` (type: `string`):

Not required: a key is built in. Use your own Google key if you run very large volumes and want your own quota.

## `locale` (type: `string`):

Language for audit titles in 'topIssues' (scores and metrics are identical in every language).

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

Each audit takes 10-40 seconds on Google's side. 4 is a good balance between speed and API quota.

## `selfTest` (type: `boolean`):

Audits one known page. Used for daily health monitoring.

## Actor input object example

```json
{
  "urls": [
    "https://www.example.com",
    "https://apify.com"
  ],
  "maxSitemapUrls": 50,
  "strategies": [
    "mobile",
    "desktop"
  ],
  "locale": "en",
  "maxConcurrency": 4,
  "selfTest": false
}
```

# Actor output Schema

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

One row per URL with Lighthouse scores, lab metrics, real-user Core Web Vitals and top fixes for mobile and desktop.

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

Complete rows with every field, CSV-ready.

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

// Run the Actor and wait for it to finish
const run = await client.actor("michael80/pagespeed-core-web-vitals-bulk-monitor").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.example.com",
        "https://apify.com",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("michael80/pagespeed-core-web-vitals-bulk-monitor").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.example.com",
    "https://apify.com"
  ]
}' |
apify call michael80/pagespeed-core-web-vitals-bulk-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,michael80/pagespeed-core-web-vitals-bulk-monitor"
        }
    }
}
```

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/DRm1mVmJ2qE0ygj5i/builds/UH5R44moiUn7uxRZV/openapi.json
