# Bulk PageSpeed Insights & Core Web Vitals Checker (`datawright-labs/pagespeed-auditor`) Actor

Audit hundreds of URLs with Google PageSpeed Insights / Lighthouse in one run. Get performance, accessibility, SEO and best-practices scores, LCP, CLS, TBT, FCP, INP field data and the top fix-it opportunities for mobile and desktop.

- **URL**: https://apify.com/datawright-labs/pagespeed-auditor.md
- **Developed by:** [Datawright Labs](https://apify.com/datawright-labs) (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 $12.00 / 1,000 audit (built-in lighthouse)s

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

Run **Google Lighthouse / PageSpeed Insights audits on hundreds of URLs in one run** and get a clean table of **performance, accessibility, SEO and best-practices scores**, the **Core Web Vitals** (LCP, CLS, TBT, FCP, Speed Index, plus real-user **INP** field data when available) and the **top opportunities** to make each page faster, for **mobile, desktop or both**.

No more pasting URLs into pagespeed.web.dev one by one.

### What does the Bulk PageSpeed Auditor do?

- Audits a list of URLs (one per line) with Lighthouse, for **mobile and/or desktop**.
- Returns **0–100 category scores**: Performance, Accessibility, Best Practices, SEO.
- Returns **lab metrics**: Largest Contentful Paint (LCP), Cumulative Layout Shift (CLS), Total Blocking Time (TBT, the lab stand-in for INP), First Contentful Paint (FCP), Speed Index, server response time and total page weight.
- With your own free Google API key, adds **Chrome UX Report (CrUX) field data**: real-user p75 LCP, **INP**, CLS, FCP and TTFB for the page (or the whole origin if the page has too little traffic).
- Lists the **top improvement opportunities** for each page (e.g. "Reduce unused JavaScript", "Eliminate render-blocking resources") with estimated savings.
- Runs audits **in parallel**, **retries** transient failures and gives a **clear error per URL** (invalid URL, DNS failure, page didn't load, quota exceeded...) instead of failing the whole run.

### Two engines: PageSpeed Insights API or local Lighthouse

| | PageSpeed Insights API (with your API key) | Local Lighthouse (no key) |
|---|---|---|
| Where the test runs | Google's servers | Inside this Actor (headless Chrome on Apify) |
| Lab scores & metrics | ✅ | ✅ |
| CrUX real-user field data (INP etc.) | ✅ | ❌ |
| Needs a Google API key | Yes (free) | No |
| Speed | Faster, up to 20 parallel audits | ~10–40 s per audit, one audit per CPU core (Apify gives 1 core per 4 GB of run memory) |

In the default **auto** mode the Actor uses the PSI API when you supply an API key. Without a key it first checks Google's shared *keyless* quota; that quota is shared by everyone on the internet and is usually exhausted, in which case the Actor automatically **runs Lighthouse itself**, so your run still succeeds.

The local engine is CPU-bound, so run it with at least 4 GB of memory (the default). Scores from the two engines are produced by the same Lighthouse audits but on different hardware and networks, so expect them to differ by a few points, just as two runs on pagespeed.web.dev do.

#### How to get a free Google API key (2 minutes)

1. Open the [Google Cloud Console](https://console.cloud.google.com/apis/library/pagespeedonline.googleapis.com) and enable the **PageSpeed Insights API** for any project.
2. Go to **APIs & Services → Credentials → Create credentials → API key**.
3. Paste the key into the **Google API key** input. It is stored as a secret input and never written to the dataset or logs.

Google's free PSI quota is generous for most audit volumes; you can check your project's limits on the Quotas page of the Google Cloud Console.

### Use cases

- **SEO audits** of a whole site or of every landing page before and after a release.
- **Agency reporting**: score all client sites monthly and export to Google Sheets or Looker Studio.
- **Competitor benchmarking**: compare your Core Web Vitals with competitors' pages.
- **Regression monitoring**: schedule the Actor daily and alert when performance drops.
- **Accessibility triage**: find the pages with the lowest accessibility scores first.

### Input

| Field | Description | Default |
|---|---|---|
| `urls` | URLs to audit, one per line | `["https://example.com"]` |
| `strategies` | `mobile`, `desktop` or both | `["mobile"]` |
| `categories` | Lighthouse categories to score | all four |
| `apiKey` | Optional Google API key (secret) | – |
| `engine` | `auto`, `psi` or `local` | `auto` |
| `includeFieldData` | Add CrUX real-user data (PSI engine only) | `true` |
| `maxOpportunities` | Opportunities per result | `5` |
| `maxConcurrency` | Parallel audits | auto (10 for PSI API, 1 per CPU core locally) |
| `maxRetries` | Retries for transient errors | `2` |
| `locale` | Language of audit titles | `en` |

Example input:

```json
{
  "urls": ["https://example.com", "https://web.dev"],
  "strategies": ["mobile", "desktop"],
  "apiKey": "YOUR_OPTIONAL_GOOGLE_API_KEY"
}
```

### Output

One dataset row per URL × strategy. Download it as JSON, CSV, Excel or HTML, or read it via the Apify API.

```json
{
  "url": "https://web.dev/",
  "strategy": "mobile",
  "engine": "local-lighthouse",
  "status": "ok",
  "finalUrl": "https://web.dev/",
  "performanceScore": 83,
  "accessibilityScore": 90,
  "bestPracticesScore": 100,
  "seoScore": 92,
  "lcpMs": 2831,
  "fcpMs": 2831,
  "cls": 0.002,
  "tbtMs": 301,
  "speedIndexMs": 3773,
  "ttfbMs": 420,
  "totalByteWeightKb": 2602.9,
  "topOpportunities": [
    { "id": "render-blocking-resources", "title": "Eliminate render-blocking resources", "displayValue": "Est savings of 620 ms", "savingsMs": 622, "savingsKb": 0, "score": 0 },
    { "id": "unused-css-rules", "title": "Reduce unused CSS", "displayValue": "Est savings of 130 KiB", "savingsMs": 600, "savingsKb": 129.9, "score": 0 }
  ],
  "lighthouseVersion": "12.8.2",
  "attempts": 1,
  "checkedAt": "2026-10-19T03:50:12.000Z"
}
```

With the PSI engine and field data the row also contains `fieldLcpP75Ms`, `fieldInpP75Ms`, `fieldClsP75`, `fieldCategory` (FAST / AVERAGE / SLOW) and a `fieldData` object with page-level and origin-level CrUX values.

Failed URLs are kept in the dataset with `status: "error"`, an `errorType` (e.g. `INVALID_URL`, `PAGE_LOAD_FAILED`, `QUOTA_EXCEEDED_DAILY`, `INVALID_API_KEY`, `TIMEOUT`) and a readable `error` message. A run summary is saved in the key-value store as `SUMMARY`.

### Example tasks

Copy one of these into the JSON tab of the input (or save it as a Task) to get started quickly.

**Core Web Vitals for your key landing pages (mobile + desktop)**

```json
{
  "urls": [
    "https://www.example.com/",
    "https://www.example.com/pricing",
    "https://www.example.com/blog/"
  ],
  "strategies": [
    "mobile",
    "desktop"
  ]
}
```

**Fast bulk audit with your free Google API key (adds CrUX real-user INP/LCP/CLS)**

```json
{
  "urls": [
    "https://web.dev",
    "https://developer.mozilla.org"
  ],
  "strategies": [
    "mobile"
  ],
  "engine": "psi",
  "apiKey": "YOUR_GOOGLE_API_KEY",
  "includeFieldData": true
}
```

**Performance-only competitor benchmark**

```json
{
  "urls": [
    "https://www.shopify.com",
    "https://www.wix.com",
    "https://www.squarespace.com"
  ],
  "strategies": [
    "mobile"
  ],
  "categories": [
    "performance"
  ],
  "maxOpportunities": 3
}
```

### How much does a bulk PageSpeed audit cost?

You pay per **successful audit** (one URL on one device). Failed audits are free and there is no start fee.

| Job | Audits | With your free Google API key ($0.004/audit) | Built-in Lighthouse, no key ($0.015/audit) |
|---|---|---|---|
| 100 URLs, mobile | 100 | **$0.40** | **$1.50** |
| 1,000 URLs, mobile | 1,000 | **$4** | **$15** |
| 1,000 URLs, mobile + desktop | 2,000 | **$8** | **$30** |
| 50 key pages daily for a month (mobile) | 1,500 | **$6** | **$22.50** |

- Apify's **free plan includes $5 of monthly credit**: about **1,250 audits with your own key** or **330 local Lighthouse audits** every month at no cost.
- Paid Apify plans get automatic discounts: **Silver -10%**, **Gold and above -20%**.
- Set **Maximum cost per run** on the run options to hard-cap spend; the Actor stops cleanly at the limit.
- Google's PageSpeed Insights API itself is free within Google's quota, which is why bringing a key is the cheapest way to audit at scale.

### Bulk PageSpeed checker vs. the alternatives

| | This Actor | pagespeed.web.dev by hand | Calling the PSI API yourself | Monitoring SaaS (subscription) |
|---|---|---|---|---|
| Many URLs in one go | ✅ hundreds per run | ❌ one at a time | ✅ after you write the code | ✅ |
| Works without a Google API key | ✅ built-in Lighthouse fallback | ✅ | ❌ (keyless quota is usually exhausted) | ✅ |
| Core Web Vitals + CrUX field data (INP) | ✅ with a key | ✅ | ✅ | ✅ |
| Top fix-it opportunities per page | ✅ | ✅ | needs parsing | ✅ |
| CSV / Excel / JSON / Sheets export | ✅ | ❌ | DIY | varies |
| Retries, quota handling, per-URL errors | ✅ | – | DIY | ✅ |
| Cost model | pay per audit, no subscription | free, manual | free + your time | monthly fee |

### Use it as an API (Python, JavaScript, cURL, MCP)

Every Apify Actor is also a REST API, so you can call this bulk PageSpeed / Core Web Vitals checker from your own code, a no-code tool or an AI agent.

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("datawright-labs/pagespeed-auditor").call(run_input={"urls": ["https://example.com"], "strategies": ["mobile"]})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

#### JavaScript / Node.js

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('datawright-labs/pagespeed-auditor').call({"urls": ["https://example.com"], "strategies": ["mobile"]});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

#### cURL (run and get results in one request)

```bash
curl -X POST "https://api.apify.com/v2/acts/datawright-labs~pagespeed-auditor/run-sync-get-dataset-items?token=<YOUR_APIFY_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"urls": ["https://example.com"], "strategies": ["mobile"]}'
```

#### AI agents (MCP)

Add `https://mcp.apify.com/?tools=datawright-labs/pagespeed-auditor` to Claude, Cursor or any MCP client and the agent can run it as a tool.

Results can also go straight to **Google Sheets, Slack, Make, Zapier, n8n, Airbyte or a webhook** via Apify integrations, and you can run it on a **Schedule**.

### FAQ

#### Why are my scores different from pagespeed.web.dev?

Lighthouse scores vary between runs and machines. The PSI engine runs on Google's infrastructure like pagespeed.web.dev; the local engine runs on Apify servers. Run important pages more than once and compare trends rather than single numbers.

#### Where is INP?

INP is a field (real-user) metric and cannot be measured in a lab test. You get it from CrUX when you use the PSI engine with an API key and the page or origin has enough Chrome traffic. In lab results, TBT is the closest proxy.

#### Can I audit pages behind a login?

No. Both engines load pages as an anonymous visitor.

#### Can I schedule it?

Yes. Use Apify Schedules to run daily or weekly and integrations (Google Sheets, Slack, webhooks, Zapier, Make) to send results where you need them.

#### Is this affiliated with Google?

No. It is an independent tool that uses the public PageSpeed Insights API and the open-source Lighthouse project.

#### Something broke?

Open an issue on the Issues tab with the run ID and the URL, and we'll look at it.

#### Is there a free bulk PageSpeed Insights checker?

Apify's free plan gives $5 of credit every month, which covers about 1,250 audits with your own free Google API key, so for most small sites this checker is effectively free.

#### How do I check Core Web Vitals for many URLs at once?

Paste the URLs (or a whole sitemap's worth, see the Sitemap URL Extractor) into the `urls` field, pick mobile and/or desktop, and run. You get LCP, CLS, TBT and, with an API key, real-user INP for every page in one table.

#### Can I export PageSpeed scores to Google Sheets or CSV?

Yes. Download the dataset as CSV/Excel/JSON or connect the Google Sheets integration so every scheduled run appends fresh scores.

### More tools from Datawright Labs

- [Sitemap URL Extractor](https://apify.com/datawright-labs/sitemap-url-extractor): get every URL of a site from its sitemaps.
- [Website Screenshot API](https://apify.com/datawright-labs/website-screenshot): bulk full-page screenshots and PDFs.
- [Google Autocomplete Keyword Scraper](https://apify.com/datawright-labs/autocomplete-keyword-scraper): long-tail keyword ideas from Google, YouTube and Bing.
- [Greenhouse, Lever & Ashby Jobs Scraper](https://apify.com/datawright-labs/ats-jobs-scraper): normalized job feeds from 5 ATS platforms.
- [Broken Link Checker](https://apify.com/datawright-labs/broken-link-checker): find broken links, images and redirects across a whole site.
- [App Store Top Charts & Rank Tracker](https://apify.com/datawright-labs/app-store-top-charts): daily top free/paid/grossing app rankings with rank changes.

Tip: feed it the output of the **Sitemap URL Extractor** to audit a whole website.

Made by **Datawright Labs**: reliable, fairly priced web data tools. Questions or a missing feature? Open an issue on the Issues tab; we usually reply within a day.

# Actor input Schema

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

Pages to test. One URL per line. URLs without a scheme get https:// added.

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

Test as a mobile device, desktop, or both. Each URL is audited once per selected strategy (and billed per audit).

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

Which Lighthouse category scores to compute. Fewer categories = slightly faster audits.

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

Your own free Google Cloud API key with the PageSpeed Insights API enabled. With a key the Actor calls the official PSI API (Google's servers, includes Chrome UX Report field data such as real-user INP). Without a key the Actor uses Google's shared keyless quota when available, otherwise it runs Lighthouse inside the Actor.

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

auto = PSI API when a key is given (or the keyless quota is free), otherwise local Lighthouse. psi = always use the PSI API. local = always run Lighthouse inside the Actor (no field data).

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

When using the PSI API, include Chrome UX Report p75 LCP, INP, CLS, FCP and TTFB for the page (or origin as a fallback). Not available in local Lighthouse mode.

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

How many improvement opportunities (sorted by estimated time saved) to include per result.

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

Parallel audits. Leave empty for the automatic default: 10 in PSI API mode (max 20); in local Lighthouse mode one audit per CPU core (Apify gives 1 core per 4 GB of run memory), because a starved CPU distorts performance scores.

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

Retries for transient failures (timeouts, rate limits, 5xx). Permanent errors such as invalid URLs or DNS failures are not retried.

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

Language for audit titles, e.g. en, de, fr, es.

## `timeoutSecs` (type: `integer`):

Maximum time to wait for a single audit.

## Actor input object example

```json
{
  "urls": [
    "https://example.com",
    "https://web.dev"
  ],
  "strategies": [
    "mobile"
  ],
  "categories": [
    "performance",
    "accessibility",
    "best-practices",
    "seo"
  ],
  "engine": "auto",
  "includeFieldData": true,
  "maxOpportunities": 5,
  "maxRetries": 2,
  "locale": "en",
  "timeoutSecs": 90
}
```

# Actor output Schema

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

All audit rows (scores, lab Core Web Vitals, field data, opportunities, errors).

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

SUMMARY record with engine, total, succeeded and failed counts.

# 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",
        "https://web.dev"
    ],
    "strategies": [
        "mobile"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("datawright-labs/pagespeed-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 = {
    "urls": [
        "https://example.com",
        "https://web.dev",
    ],
    "strategies": ["mobile"],
}

# Run the Actor and wait for it to finish
run = client.actor("datawright-labs/pagespeed-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 '{
  "urls": [
    "https://example.com",
    "https://web.dev"
  ],
  "strategies": [
    "mobile"
  ]
}' |
apify call datawright-labs/pagespeed-auditor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,datawright-labs/pagespeed-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/TphleoEHFf3SzwafI/builds/q4a3BwC7sPOuGiusg/openapi.json
