# Bulk PageSpeed Insights, Lighthouse & Core Web Vitals (`forevertools/pagespeed-core-web-vitals`) Actor

Bulk PageSpeed Insights & Lighthouse performance audit / website speed test & page load time check for a list of URLs (mobile, desktop or both): scores, LCP, CLS, TBT, FCP, SI, TTI and top fix opportunities. Add a free Google API key for real-user CrUX Core Web Vitals.

- **URL**: https://apify.com/forevertools/pagespeed-core-web-vitals.md
- **Developed by:** [Forever Tools](https://apify.com/forevertools) (community)
- **Categories:** Developer tools, SEO tools
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$20.00 / 1,000 page testeds

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 & Core Web Vitals Checker

Paste a list of URLs and get **Lighthouse / PageSpeed** results for every page, on **mobile, desktop or both**,
in one table: **Lighthouse scores** (performance, plus optional SEO / accessibility / best-practices),
**lab metrics** (LCP, CLS, TBT, FCP, Speed Index, TTI), **real-user Core Web Vitals from the Chrome UX Report** when you add a free Google API key
(LCP, INP, CLS at p75 with FAST / AVERAGE / SLOW ratings) and the **top 5 opportunities** ranked by estimated savings.

**Two modes, picked automatically:**

- **No API key (default):** the actor runs Lighthouse 12 itself in its own headless Chrome. You get Lighthouse
  scores, lab metrics and opportunities with zero setup, but **no real-user field data** (all `field*` values are `null`)
  and pages are tested one at a time. Rows have `"source": "lighthouse-local"`.
- **With your free Google API key:** it calls the official PageSpeed Insights v5 API (the same data as pagespeed.web.dev),
  which adds CrUX real-user Core Web Vitals and runs up to 3 tests in parallel. Rows have `"source": "psi"`.

Local lab numbers come from a different machine and network than Google's, so they will not exactly match
pagespeed.web.dev; compare runs made in the same mode.

Use it to: audit every template of a site before and after a release, track Core Web Vitals across client
sites on a schedule, find which pages fail CWV (and why), or feed performance data into a spreadsheet, BI tool or LLM report.

### Output (one row per URL × strategy)

```json
{
  "url": "https://example.com/",
  "strategy": "mobile",
  "finalUrl": "https://example.com/",
  "performanceScore": 67,
  "seoScore": 92,
  "accessibilityScore": null,
  "bestPracticesScore": null,
  "lcpMs": 4124, "cls": 0.104, "tbtMs": 412, "fcpMs": 1890, "speedIndexMs": 3890, "ttiMs": 6013,
  "fieldDataSource": "url",
  "fieldLcpP75Ms": 2890, "fieldLcpCategory": "AVERAGE",
  "fieldInpP75Ms": 180,  "fieldInpCategory": "FAST",
  "fieldClsP75": 0.12,   "fieldClsCategory": "AVERAGE",
  "fieldFcpP75Ms": 1700, "fieldTtfbP75Ms": 820,
  "fieldOverallCategory": "AVERAGE",
  "originField": { "lcpP75Ms": 2500, "clsP75": 0.05, "overallCategory": "FAST", "...": "..." },
  "opportunities": [
    { "id": "unused-javascript", "title": "Reduce unused JavaScript", "displayValue": "Potential savings of 212 KiB", "savingsMs": 1200, "savingsBytes": 217000 },
    { "id": "render-blocking-resources", "title": "Eliminate render-blocking resources", "savingsMs": 780, "savingsBytes": 0 }
  ],
  "lighthouseVersion": "12.8.2",
  "fetchTime": "2026-09-29T10:00:00.000Z",
  "source": "psi",
  "error": null
}
```

- **Scores** are 0–100 (`null` for categories you didn't request).
- **Lab metrics** come from a single Lighthouse run (on Google's servers with a key, inside the actor without one); they vary a little between runs.
- **`source`** is `psi` (PageSpeed Insights API) or `lighthouse-local` (no key; field data always `null`).
- **Field data** (`field*`) is real Chrome user data over the last 28 days. `fieldDataSource` is `url` when the page
  itself has enough traffic, `origin` when Google falls back to whole-site data, and `null` when the site has too
  little traffic to be in CrUX (common for small sites; lab data is still returned).
- **Opportunities** are the 5 failing audits with the largest estimated time (then byte) savings.
- **Errors never stop the run.** A page that can't be loaded, an invalid URL or an exhausted quota produces a row
  with `error` set and the actor moves on. A `SUMMARY` record in the key-value store counts successes and errors.

### Google API key (optional: adds real-user field data)

No key is needed: without one the actor runs Lighthouse locally (lab data only). Add a key if you want CrUX
real-user Core Web Vitals and faster parallel runs. A key is **free** and gives about 25,000 requests/day:

1. Open [Google Cloud console → Credentials](https://console.cloud.google.com/apis/credentials) and create an API key.
2. Enable the [PageSpeed Insights API](https://console.cloud.google.com/apis/library/pagespeedonline.googleapis.com) for that project.
3. Paste the key into the **Google API key** input. It is stored as a secret input and only sent to Google.

### Input

```json
{
  "urls": ["https://example.com", "https://example.com/pricing"],
  "strategy": "both",
  "categories": ["performance", "seo"],
  "apiKey": "YOUR_GOOGLE_API_KEY"
}
```

| Field | Default | Notes |
|---|---|---|
| `urls` | – | Public URLs; `https://` is added if missing. |
| `strategy` | `mobile` | `mobile`, `desktop` or `both` (two rows per URL). |
| `categories` | `["performance"]` | Add `seo`, `accessibility`, `best-practices` as needed. |
| `apiKey` | – | Optional. Omit to run Lighthouse locally (lab only, no field data, concurrency 1); set to use the PSI API (adds field data). |
| `locale` | `en` | Language for audit titles. |
| `maxConcurrency` | 3 | Parallel PSI API requests, max 3 (each test takes 10–40 s). Local mode always runs 1 at a time. |
| `maxRetries` | 4 | PSI API mode only: retries on 429 rate limits and Google 5xx errors, with exponential backoff. Daily-quota errors are not retried. |

### Pricing

Pay per result: **$0.02 per successfully tested URL × strategy** (so one URL on mobile + desktop = $0.04). Rows that end in an error are not charged.
Set a max charge on the run to cap spend; the actor stops cleanly when it is reached.

### Use cases

- **Pre/post-release checks:** run your key templates (home, category, product, article) on both devices and compare.
- **Performance monitoring & speed regression checks:** re-run after each deploy to catch slow pages and page-weight regressions before users notice.
- **Agency reporting:** schedule weekly runs across client sites and export to Google Sheets / CSV.
- **Find CWV failures:** filter rows by `fieldOverallCategory = SLOW` or `fieldInpCategory != FAST`, then read `opportunities`.
- **SEO audits:** add the `seo` category for a quick score alongside performance.

### FAQ

**Why do my lab numbers differ from pagespeed.web.dev?** Lighthouse runs vary by a few points between runs. In API-key mode the data source is the same API; in the default local mode the test runs on a different machine and network, so compare runs made in the same mode.
**Why is field data empty?** Without an API key the actor runs Lighthouse locally, which has no field data. With a key: the page/site doesn't have enough Chrome traffic to appear in the Chrome UX Report.
**Can it test pages behind a login or on localhost?** No. The page must be publicly reachable.
**How long does it take?** Roughly 20–40 seconds per test: one at a time in local mode, 3 in parallel with an API key.

### Notes

- Default mode runs the open-source Lighthouse engine locally. API-key mode uses the official Google PageSpeed Insights API, subject to Google's API terms.
- Not affiliated with Google. Built and maintained with AI assistance. Problems or requests: use the Issues tab.

### Related tools

Other actors by the same developer (same flat pay-per-result pricing, no subscription):

- [Apple App Store Reviews Scraper (Multi-Country)](https://apify.com/forevertools/apple-app-store-reviews)
- [Article Extractor – Clean Text & Markdown for LLM/RAG](https://apify.com/forevertools/article-extractor)
- [Company Jobs Scraper: Workday, Greenhouse, Lever, Ashby](https://apify.com/forevertools/ats-company-jobs)
- [Bulk Domain Checker — WHOIS/RDAP, DNS, SPF/DMARC, SSL Expiry](https://apify.com/forevertools/domain-whois-dns-ssl)
- [PDF to Text Extractor (Bulk, with Metadata)](https://apify.com/forevertools/pdf-to-text-extractor)
- [Website SEO Audit Crawler](https://apify.com/forevertools/website-seo-audit)
- [Sitemap Extractor & Bulk URL Status Checker](https://apify.com/forevertools/sitemap-url-status-checker)
- [Website Tech Stack Detector (CMS, Framework, Analytics)](https://apify.com/forevertools/website-tech-stack-detector)
- [Website Screenshot – Bulk Full Page PNG, JPEG & PDF](https://apify.com/forevertools/website-screenshot)

### Integrations

Run it from the Apify API, a schedule, or no-code tools: the Apify apps for **Zapier**, **Make** and **n8n** can start any public actor ("Run Actor") and read its dataset. AI agents can call it through the **Apify MCP server**.

# Actor input Schema

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

Public page URLs to test (https:// is added if missing). One result row per URL per strategy.

## `strategy` (type: `string`):

Test as a mobile device, desktop, or both (both = two rows per URL).

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

Which Lighthouse categories to score. Performance is always the core; add SEO, accessibility or best-practices if you need those scores too.

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

Optional. Without a key the actor runs Lighthouse itself in the actor's own headless Chrome: lab scores and metrics only, no CrUX real-user field data, one page at a time. With your own free PageSpeed Insights API key (Google Cloud console > APIs & Services > Credentials, enable 'PageSpeed Insights API') it calls Google's PSI API instead: same Lighthouse data plus CrUX field data, up to 3 in parallel, ~25,000 requests/day free.

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

Language for audit titles (e.g. en, de, fr).

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

Parallel PageSpeed API requests (max 3). Ignored without an API key: local Lighthouse runs one page at a time.

## `maxRetries` (type: `integer`):

Retries per request on rate limits (429) and Google server errors (5xx), with exponential backoff.

## Actor input object example

```json
{
  "urls": [
    "https://crawlee.dev"
  ],
  "strategy": "mobile",
  "categories": [
    "performance"
  ],
  "locale": "en",
  "maxConcurrency": 3,
  "maxRetries": 4
}
```

# Actor output Schema

## `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 = {
    "urls": [
        "https://crawlee.dev"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("forevertools/pagespeed-core-web-vitals").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://crawlee.dev"] }

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

```

## MCP server setup

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

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/u0CGVQRbqcUg4vriO/builds/2W4T8JEESuFjjhEUA/openapi.json
