# PageSpeed and Core Web Vitals Auditor (`vizellie/pagespeed-auditor`) Actor

Runs PageSpeed Insights on a list of URLs or a whole sitemap and puts mobile and desktop Core Web Vitals in one row per page. $0.005 per page per device with the built-in key, or $0.002 with your own Google API key. An optional client report is $0.03.

- **URL**: https://apify.com/vizellie/pagespeed-auditor.md
- **Developed by:** [Vi Zellie](https://apify.com/vizellie) (community)
- **Categories:** SEO tools, Developer tools, Automation
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 audit with your api keys

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

## PageSpeed and Core Web Vitals Auditor

Audit Core Web Vitals and PageSpeed scores for many pages in one run. Give it a list of URLs, a sitemap, or both. Each page comes back as one row, with mobile and desktop side by side, a pass or fail against Google's Core Web Vitals thresholds, and a short list of what to fix first.

Not legal advice; general information only.

### Who it is for

Developers, SEO consultants and agencies who need a repeatable performance check after a release, a template change, or as a scheduled watch on the pages that matter.

### What you get

- A list of page URLs, a sitemap URL, or both. Large sitemaps are limited by **Max URLs**.
- Mobile, desktop, or both. Both devices are stored in the same row.
- For each successful audit: performance score, LCP, INP when field data exists, Total Blocking Time from the lab audit, CLS, FCP, TTFB, and a pass or fail.
- Field data for the page when Google has it, otherwise field data for the origin when that is available.
- The top opportunities, ranked by estimated time saved.
- A run summary with a fix-these-first list. Pages that fail Core Web Vitals come first, then the lowest scores.
- Optional comparison with the previous run. Pages whose score dropped, or whose Core Web Vitals pass became a fail, are flagged.
- Private and internal addresses are skipped and are not charged.

### Tutorial

1. Paste page URLs into **Page URLs**, or set **Sitemap URL**, or use both.
2. Choose **Devices**. `both` is the default and writes mobile and desktop into one row. Each device is charged on its own.
3. Set **Max URLs** to the budget you want. With both devices, 10 pages where both checks succeed cost $0.10 with the key supplied with the Actor, or $0.04 with your own key, plus the start fee.
4. **Google API key** is optional. Leave it empty to use the key supplied with the Actor. The price is $0.005 per page per device, so checking both mobile and desktop costs $0.01 per page. Add your own free Google PageSpeed API key and the price is $0.002 per page per device, so both devices cost $0.004 per page.
5. Leave **Concurrency** at 2 unless you know your quota can take more.
6. To compare with last time, turn on **Compare with the previous run** and keep the same store name and record key for that site.
7. Run the Actor. Open the dataset for each page, and the `OUTPUT` record for the summary and the fix-these-first list.
8. Schedule the task if you want a standing check. Failed audits are not charged.

### Client-ready report

Use this when you want one file to send to a client. It is off by default. Off does not add a file and does not add a fee.

1. Add the pages or the sitemap you want to audit.
2. Set **Client-ready report** to **HTML**.
3. Run the Actor.
4. Open the Output tab. **Client report (HTML)** is `REPORT.html` in the key-value store. **Client report summary** lists that key.

The page has a cover with the site, the date and a performance grade, a short summary in plain language, and a table of findings. Each finding says what it means and how to fix it. Pages from more than one site are grouped by site. Pass, warning and fail stay readable in black and white. The footer says Generated with PageSpeed and Core Web Vitals Auditor.

The report fee is charged once per run, and only after the file is saved. A failed save is not charged. The dataset stays priced as below. This Actor saves HTML. It does not save a PDF.

### Example input

```json
{
  "urls": ["https://example.com/", "https://example.com/pricing"],
  "sitemapUrl": "https://example.com/sitemap.xml",
  "devices": "both",
  "maxUrls": 20,
  "concurrency": 2,
  "trackChanges": true,
  "changesKey": "example.com"
}
```

Leave `googleApiKey` out of shared examples. It is a secret input and is not written to the dataset.

### Example output

One dataset row per page:

```json
{
  "url": "https://example.com/",
  "keySource": "user",
  "coreWebVitalsPassed": true,
  "mobileScore": 91,
  "desktopScore": 98,
  "mobile": {
    "performanceScore": 91,
    "lcpMs": 1800,
    "lcpRating": "good",
    "inpMs": 150,
    "inpRating": "good",
    "tbtMs": 80,
    "cls": 0.04,
    "clsRating": "good",
    "fcpMs": 900,
    "ttfbMs": 120,
    "coreWebVitalsPassed": true,
    "opportunities": [
      { "id": "unused-javascript", "title": "Reduce unused JavaScript", "savingsMs": 400 }
    ]
  },
  "desktop": {
    "performanceScore": 98,
    "coreWebVitalsPassed": true
  },
  "regressed": false
}
```

`keySource` is `user` when you supplied the Google API key, and `actor` when the key supplied with the Actor was used. The key itself is never included.

The `OUTPUT` record holds `fixFirst`, audit counts, and `changes` when comparison is on. `changes.regressions` lists pages that got worse. Pages that were simply not part of this run are not treated as removed.

### Pricing

You pay a small start fee, then one fee for each successful audit. One audit is one page on one device. With the key supplied with the Actor, the price is $0.005 per page per device, so checking both mobile and desktop costs $0.01 per page. With your own API key, the price is $0.002 per page per device, so both devices cost $0.004 per page. A failed audit is free. A skipped private address is free.

| What | Price |
|---|---|
| Run started | $0.00005 |
| Successful audit with your API key, per page per device | $0.002 |
| Successful audit with the key supplied with the Actor, per page per device | $0.005 |
| Both devices on one page, your API key (two audits in total) | $0.004 |
| Both devices on one page, key supplied with the Actor (two audits in total) | $0.01 |
| Client-ready report, once per run, only when the file is saved | $0.03 |

**Examples**

- 10 pages, mobile only, your key: 10 × $0.002 = $0.02, plus the $0.00005 start fee.
- 10 pages, mobile only, the key supplied with the Actor: 10 × $0.005 = $0.05, plus the start fee.
- 10 pages, both devices, your key: 10 × $0.004 = $0.04, plus the start fee.
- 10 pages, both devices, the key supplied with the Actor: 10 × $0.01 = $0.10, plus the start fee.
- A page that fails to load, or a request Google rejects, is not charged. A page where only one device succeeds is charged for that device only.

### Integrations and scheduling

Save the input as an Apify task and schedule it daily or weekly. Use the same changes key so each run can flag regressions. The dataset and the `OUTPUT` record are available from the Apify API and from webhooks, so you can post a summary to Slack or email when a page regresses. Export the dataset as JSON or CSV.

### FAQ

**What does pass or fail mean?**

A device passes when LCP, INP and CLS are all in Google's "good" range. The page passes when every device you requested passes. If a metric was not measured, the pass flag is empty rather than a guess.

**What are the thresholds?**

These are Google's published Core Web Vitals ranges.

- LCP: good at 2.5 seconds or less, needs improvement up to 4 seconds, poor above 4 seconds.
- INP: good at 200 milliseconds or less, needs improvement up to 500 milliseconds, poor above 500 milliseconds.
- CLS: good at 0.1 or less, needs improvement up to 0.25, poor above 0.25.

**Why is INP sometimes empty?**

INP comes from field data, which is measured on real visits. The lab audit does not produce INP. It reports Total Blocking Time instead, in `tbtMs`. When field data has no INP, the Core Web Vitals pass flag is empty and the lab numbers are still saved.

**Where does field data come from?**

From the page when Google has enough visits for that URL. Otherwise from the origin, when that is available. `field.scope` is `url` or `origin`.

**Which key is used?**

**Google API key** is optional. Leave it empty to use the key supplied with the Actor. The price is $0.005 per page per device, so checking both mobile and desktop costs $0.01 per page. Add your own free Google PageSpeed API key and the price is $0.002 per page per device, so both devices cost $0.004 per page. The key is not stored in the dataset, the summary, or the log.

**Are failed audits charged?**

No. A timeout, a rate limit that still fails, a quota error, or a page that does not load is stored with an error and is not charged. If you asked for both devices and only one succeeds, you pay for that device only.

**Will you keep my page content?**

No. Page bodies, screenshots and the raw audit payload are not stored.

### No personal data

This Actor does not collect personal data.

- Page HTML, screenshots and raw responses are discarded.
- Email addresses, phone numbers and secret query parameters are removed before a page is sent for audit, and again before anything is stored.
- The API key is never written to results or logs.
- Change tracking stores the page URL, the scores and the pass flag. It does not store page content.
- Private and internal addresses are not requested.

### Next additions

- Agency white-label logo
- Dutch report

# Actor input Schema

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

Pages to audit, for example https://example.com/. Private and internal addresses are skipped. You can combine this list with a sitemap.

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

Optional sitemap or sitemap index. Page addresses are taken from it, up to Max URLs. Private addresses listed in the sitemap are skipped.

## `devices` (type: `string`):

Audit mobile, desktop, or both. Both devices are saved in one row. The price is $0.005 per page per device with the key supplied with the Actor, so checking both mobile and desktop costs $0.01 per page. With your own API key the price is $0.002 per page per device, so both devices cost $0.004 per page. A failed check is free.

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

Optional. Leave it empty to use the key supplied with the Actor. The price is $0.005 per page per device, so checking both mobile and desktop costs $0.01 per page. With your own free Google PageSpeed Insights API key, the price is $0.002 per page per device, so both devices cost $0.004 per page. The key is secret and is never saved in the results.

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

Maximum number of pages to audit in one run. The charge is per page per device. Both devices cost twice a single device when both succeed.

## `concurrency` (type: `integer`):

How many pages to audit at the same time. Lower values stay within Google's rate limits more easily.

## `trackChanges` (type: `boolean`):

Save scores in a named key-value store and flag pages that got worse since the last run.

## `changesStoreName` (type: `string`):

Named key-value store used when change tracking is on. Letters, numbers, hyphens and underscores only.

## `changesKey` (type: `string`):

Record name inside the changes store. Use a different key for each site if you audit more than one.

## `report` (type: `string`):

Save an HTML report you can hand to a client. Off is the default: the run, the dataset and the price stay as they are today. The report fee is charged once per run, and only after the file is saved.

## Actor input object example

```json
{
  "urls": [
    "https://example.com/"
  ],
  "sitemapUrl": "https://example.com/sitemap.xml",
  "devices": "both",
  "maxUrls": 20,
  "concurrency": 2,
  "trackChanges": false,
  "changesStoreName": "pagespeed-audit-state",
  "changesKey": "default",
  "report": "off"
}
```

# Actor output Schema

## `pages` (type: `string`):

One dataset row per page. Mobile and desktop share that row. The price is $0.005 per page per device with the key supplied with the Actor, so checking both mobile and desktop costs $0.01 per page. Your own key is $0.002 per page per device, so both devices cost $0.004 per page.

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

The OUTPUT record in the default key-value store.

## `clientReport` (type: `string`):

The REPORT.html record. Saved when Client-ready report is HTML.

## `clientReportSummary` (type: `string`):

The CLIENT_REPORT record, with the report key.

# 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/"
    ],
    "devices": "both",
    "maxUrls": 20,
    "concurrency": 2,
    "changesStoreName": "pagespeed-audit-state",
    "changesKey": "default"
};

// Run the Actor and wait for it to finish
const run = await client.actor("vizellie/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/"],
    "devices": "both",
    "maxUrls": 20,
    "concurrency": 2,
    "changesStoreName": "pagespeed-audit-state",
    "changesKey": "default",
}

# Run the Actor and wait for it to finish
run = client.actor("vizellie/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/"
  ],
  "devices": "both",
  "maxUrls": 20,
  "concurrency": 2,
  "changesStoreName": "pagespeed-audit-state",
  "changesKey": "default"
}' |
apify call vizellie/pagespeed-auditor --silent --output-dataset

```

## MCP server setup

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