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

Bulk PageSpeed checker: run Google PageSpeed Insights on hundreds of URLs and get Lighthouse scores (performance, SEO, accessibility), real-user Core Web Vitals (LCP, INP, CLS), a pass/fail verdict and top fixes. Mobile + desktop. Use your free Google API key.

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

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-usage

## 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

## PageSpeed Insights & Core Web Vitals Checker (Bulk Lighthouse)

**Bulk PageSpeed Insights checker:** test hundreds of URLs at once for **Core Web Vitals** and **Lighthouse** scores, the same data you see on Google's PageSpeed Insights page.&#x20;

Audit a list of URLs, from 10 to thousands, with **Google's official PageSpeed Insights API** and get one clean row per URL and device:

- **Lighthouse scores (0–100)**: Performance, SEO, Accessibility and Best Practices. You choose which ones.
- **Lab metrics**: FCP, LCP, Total Blocking Time, CLS, Speed Index, Time to Interactive and server response time.
- **Real-user Core Web Vitals** from Chrome UX Report (CrUX) field data at the 75th percentile: **LCP, INP, CLS**, plus FCP and TTFB, with Google's FAST/AVERAGE/SLOW rating for each. You get both **URL-level and origin-level** data.
- **A clear "Core Web Vitals passed?" verdict**, using Google's thresholds (LCP ≤ 2.5 s, INP ≤ 200 ms, CLS ≤ 0.1). The verdict uses URL data when Google has it and falls back to origin data otherwise, and the row says which one it used.
- **Top fix opportunities** with estimated savings, for example "Eliminate render-blocking resources: 450 ms" or "Reduce unused JavaScript: 120 KiB".
- **Mobile, desktop or both**.

**Failed audits are free.** That covers pages that can't load, invalid URLs and Google errors.

### Who uses this

- **SEO agencies.** Audit every client page, or every competitor homepage, in one run and export to Sheets.
- **E-commerce and content teams.** Track Core Web Vitals across product and category templates. Schedule weekly runs to catch regressions.
- **Developers.** Check performance before and after a release across many routes.
- **Prospecting.** Find businesses with failing Core Web Vitals, a strong opener for web-performance services.

### Your free Google API key (1 minute)

Without a key, the tool uses Google's **shared anonymous quota**, which is often used up. When that happens the run ends quickly with one free row per URL explaining what happened (`error` + `howToFix`), and **you are not charged**. Your own key is free and gives you **25,000 audits a day**:

1. Open Google's [PageSpeed Insights API "Get Started" page](https://developers.google.com/speed/docs/insights/v5/get-started) and click **Get a Key**.
2. Pick an existing Google Cloud project or create a new one. The PageSpeed Insights API is enabled for you.
3. Copy the key (it starts with `AIza`) and paste it into the **Google API key** field.

The key is stored encrypted as a secret input and is never written to logs or output. If you prefer the Cloud Console, go to APIs & Services → Library → enable **PageSpeed Insights API**, then Credentials → Create credentials → API key. You can optionally restrict the key to that API.

If something is wrong with your key (it's invalid, the API is disabled, or its daily quota is used up), the run stops at once and is marked as failed so schedules notice. The status message and each row's `howToFix` field explain the fix in plain English.

### Input example

```json
{
  "urls": ["https://web.dev/", "example.com", "https://www.apify.com/pricing"],
  "googleApiKey": "AIza…",
  "strategies": ["mobile", "desktop"],
  "categories": ["performance", "seo"],
  "includeOpportunities": true,
  "maxConcurrency": 4
}
```

### Output example (shortened)

```json
{
  "url": "https://web.dev/", "strategy": "mobile", "finalUrl": "https://web.dev/",
  "scores": { "performance": 87, "seo": 100, "accessibility": null, "bestPractices": null },
  "lab": { "fcpMs": 1534, "lcpMs": 2951, "tbtMs": 180, "cls": 0.012, "speedIndexMs": 2100, "ttiMs": 3900, "serverResponseMs": 320 },
  "field": { "overallCategory": "FAST", "lcpP75": 1900, "lcpCategory": "FAST", "inpP75": 120, "clsP75": 0.05, "fcpP75": 1200, "ttfbP75": 600, "coreWebVitalsPassed": true, "isOriginFallback": false },
  "originField": { "overallCategory": "AVERAGE", "lcpP75": 2700, "inpP75": 180, "clsP75": 0.12, "coreWebVitalsPassed": false },
  "coreWebVitalsPassed": true, "coreWebVitalsSource": "url",
  "opportunities": [
    { "id": "render-blocking-resources", "title": "Eliminate render-blocking resources", "savingsMs": 450, "savingsKiB": 0 },
    { "id": "unused-javascript", "title": "Reduce unused JavaScript", "savingsMs": 300, "savingsKiB": 120 }
  ],
  "lighthouseVersion": "12.x", "error": null
}
```

The numbers above illustrate the format. The **Overview** table view flattens scores and vitals into columns for one-click CSV or Excel export. Pages with too little traffic for CrUX return `field: null`, and Google provides real-user data only for sufficiently popular pages and origins.

### Pricing (pay per event)

| Event | Price |
|---|---|
| Audit completed (one URL × one device) | **$0.003** |

Example: 500 URLs on mobile and desktop is 1,000 audits, which costs $3. Failed audits are free. Set a **maximum cost per run** and the tool stops cleanly at your limit.

### Notes

- Each audit takes Google 10–40 seconds. Concurrency 4 is safe within Google's per-key rate limits, and the tool retries 429/5xx responses automatically with backoff.
- If your key is invalid or out of quota, the run stops right away with a clear message, so you don't burn time on doomed requests.
- Data comes only from Google's official PageSpeed Insights API, run under your own key, with no scraping.

Questions or feature requests? Use the **Issues** tab.

***

Built by **PewterDesk** ([pewterdesk.pages.dev](https://pewterdesk.pages.dev)). More tools: [apify.com/pewterdesk](https://apify.com/pewterdesk).

# Actor input Schema

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

Pages to audit, one per line. Bare domains get https:// added.

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

Paste your own free Google API key. Get one in about a minute: open https://developers.google.com/speed/docs/insights/v5/get-started, click 'Get a Key', choose or create a project and copy the key. Free: 25,000 audits/day. Stored encrypted, never logged. Without a key the tool uses Google's shared anonymous quota, which is often used up; you are not charged when that happens.

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

Each URL is audited once per device. Each audit is billed separately.

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

Scores to compute. More categories = slower audits, same price.

## `includeOpportunities` (type: `boolean`):

Up to 8 Lighthouse opportunities per audit with estimated savings (ms / KiB).

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

Parallel audits. Google allows ~400 requests/100s per key; 4 is safe.

## Actor input object example

```json
{
  "urls": [
    "https://web.dev/"
  ],
  "strategies": [
    "mobile"
  ],
  "categories": [
    "performance"
  ],
  "includeOpportunities": true,
  "maxConcurrency": 4
}
```

# Actor output Schema

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

Lighthouse scores, lab metrics and Core Web Vitals per URL and device (default dataset).

## `runSummary` (type: `string`):

Counts for this run (processed, failed, stopped at spending limit) as JSON.

# 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://web.dev/"
    ]
};

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

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

```

## MCP server setup

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