# Bulk PageSpeed & Core Web Vitals Checker (PSI) (`tesselyn/pagespeed-checker`) Actor

Audit many URLs with Google PageSpeed Insights API v5. Returns performance score, LCP, CLS, INP/FID, FCP, TTFB and top opportunities for mobile, desktop or both. No API key needed (optional own key for heavy usage).

- **URL**: https://apify.com/tesselyn/pagespeed-checker.md
- **Developed by:** [Tesselyn](https://apify.com/tesselyn) (community)
- **Categories:** SEO tools, Developer tools
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $6.40 / 1,000 url auditeds

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

## Bulk PageSpeed & Core Web Vitals Checker (PSI)

Audit **many URLs at once** with the official **Google PageSpeed Insights API v5**. Get the **performance score**, **Core Web Vitals** (LCP, CLS, INP/FID), **FCP**, **TTFB** and a short list of the **top Lighthouse opportunities** — for **mobile**, **desktop**, or **both**. **No API key needed** — the Actor uses a built-in Google key by default; you can add your own key for heavy usage. You pay only for audits that return a Lighthouse result.

> ⚠️ **Automated, informational results, provided "as is".** Not legal, compliance or SEO advice. Lab scores vary by run; a good score does not guarantee rankings, a Core Web Vitals "pass" in Search Console or more traffic. See [Terms of use](#terms-of-use).

### What does it do?

- Takes a **list of public URLs** (up to 200) and an optional **strategy** (`mobile` / `desktop` / `both`).
- Calls [Google PageSpeed Insights API v5](https://developers.google.com/speed/docs/insights/v5/get-started) for each URL × strategy.
- Returns, per audit: **performance score (0–100)**, **LCP**, **CLS**, **INP** (or FID / max-potential-FID when INP is absent), **FCP**, **TTFB**, **TBT**, Speed Index, TTI, up to **10 opportunities** with estimated savings, optional CrUX field categories when Google still returns them, and **stable error codes** when something fails.
- Optionally also requests Accessibility, Best Practices and SEO category scores.
- Writes a **run-summary** row with counts and the average performance score.

### Who is it for?

SEO and performance agencies monitoring client sites, developers running pre-release checks, product teams watching Core Web Vitals over time, and AI / automation agents that need structured CWV data via the Apify API, MCP, Make, Zapier or n8n.

### Google API key (optional)

**No API key is needed by default.** If you leave the secret input field `googleApiKey` empty, the Actor uses its built-in Google PageSpeed Insights API key.

The built-in key shares one Google daily quota across all users. If that quota runs out, affected audits come back as rows with `error: "QUOTA_EXCEEDED"` and **`charged: false`** (the rest of the run is skipped and also not charged). Try again later (Google resets the daily quota), or use your own key.

**Heavy usage? Add your own key.** If you set `googleApiKey`, your key is always used instead of the built-in one, and Google's quota for it is yours alone:

1. Open [Google Cloud Console](https://console.cloud.google.com/) and create or pick a project.
2. Enable **PageSpeed Insights API**.
3. Create an **API key** (Credentials). Restrict it to the PageSpeed Insights API if you can.
4. Paste the key into `googleApiKey`. Apify encrypts secret inputs at rest; **this Actor never logs any key**. The run log only says which key source was used (`user key` or `built-in key`).

With your own key, Google API usage and quotas belong to your own Google Cloud project.

### How to use it

1. Add the **URLs** to audit.
2. Pick a **strategy** (start with `mobile`).
3. Set **Max audits** to cap cost.
4. Optional: paste your own **Google API key** into `googleApiKey` for heavy usage.
5. Run, then open the **Scores & Core Web Vitals** dataset view or download CSV/JSON.

#### Input example

```json
{
  "urls": [
    { "url": "https://www.example.com/" },
    { "url": "https://www.example.com/pricing" }
  ],
  "strategy": "mobile",
  "maxAudits": 20
}
```

### Output example

```json
{
  "type": "url-result",
  "url": "https://www.example.com/",
  "strategy": "mobile",
  "finalUrl": "https://www.example.com/",
  "performanceScore": 87,
  "lcpMs": 2450.0,
  "cls": 0.05,
  "inpMs": 180.0,
  "fcpMs": 1200.0,
  "ttfbMs": 320.0,
  "tbtMs": 150.0,
  "opportunities": [
    { "id": "unused-javascript", "title": "Reduce unused JavaScript", "savingsMs": 450.0 }
  ],
  "error": null,
  "charged": true
}
```

Failed audits (invalid URL, timeout, quota exhausted (`QUOTA_EXCEEDED`), bad key, non-public address) are written as rows with an `error` code and **`charged: false`**.

### How much does it cost?

Pay per event: **$0.008 per successful URL×strategy audit** (`url-audited`, = $8 per 1,000 audits; `both` counts as two audits). Failed audits, input errors and the summary row are free. See the Actor's Monetization tab for the live price once published. Set *Max audits* (and optionally the run's maximum charge) to cap spend. There is no extra charge for using the built-in Google key. If you add your own key, Google's API usage for it counts against **your** Google Cloud project.

### How we differ (honestly)

- **No key needed to start** — a built-in Google key works out of the box; add your own key any time to get your own quota.
- **Bulk-first** with `mobile` / `desktop` / `both` and a hard audit cap.
- **Clean CWV-focused schema** (scores + vitals + top opportunities), not a raw Lighthouse dump.
- **SSRF protection** on every input URL, polite rate limits toward Google, and no charge on failures.
- We wrap Google's hosted PSI (same engine as PageSpeed Insights). We do **not** run a local Lighthouse browser, so we inherit Google's lab environment and quotas.

### Integrations and API

Run from the Apify API, CLI, Schedules, Make, Zapier, n8n, LangChain or `mcp.apify.com`. The `OUTPUT` record and run-summary row are easy to pipe into sheets or alerts (e.g. webhook when average score drops).

### Responsible use

The Actor identifies outgoing requests to Google as `TesselynPageSpeedBot/1.0 (+https://apify.com/tesselyn)`. It only calls Google's PageSpeed Insights API. It does **not** crawl your site, does **not** execute JavaScript on Apify infrastructure, and does **not** use proxies to bypass bot protection. Input URLs must be public `http`/`https` on ports 80/443; private, loopback and cloud-metadata addresses are rejected. Default rate: 1 s between PSI calls, concurrency 2 (configurable, max 5).

### Terms of use

These terms add to the [Apify Standard Actor Contract](https://docs.apify.com/legal/standard-actor-contract), which governs your use of this Actor; they do not replace it.

- Only submit URLs you own, manage or otherwise have a legitimate interest and right to measure. You are responsible for complying with applicable laws, Google’s API Terms of Service and the target sites’ terms.
- Do not use the Actor to probe internal networks or to abuse Google’s API quotas. Abusive use may be blocked.
- **Sanctions and restricted countries.** You may not use this Actor if you are located in, ordinarily resident in, or acting on behalf of a person or organisation in a restricted country or region. Currently these are: Afghanistan, Belarus, Central African Republic, Cuba, Democratic Republic of the Congo, Haiti, Iran, Iraq, Lebanon, Libya, Mali, Myanmar, Nicaragua, North Korea, Russia, Somalia, South Sudan, Sudan, Syria, Venezuela, Yemen, Zimbabwe, Antarctica, and the Crimea, Sevastopol, Donetsk, Luhansk, Kherson and Zaporizhzhia regions of Ukraine. You also may not use it if you are on, or owned or controlled by someone on, any applicable sanctions list (including those of the United Nations, the United States (OFAC SDN), the European Union, the United Kingdom or Israel). We may block such use, and we may update this list when the law or our policy changes.
- Output is an automated, best-effort lab measurement from Google PageSpeed Insights / Lighthouse and is provided "as is". Scores and timings vary by run, location and Google’s lab environment. Field (CrUX) data, when present, reflects Chrome users and may be missing for low-traffic URLs. Check results before relying on them for important decisions.
- **Informational only; no guarantee of outcomes.** Output is not legal, regulatory, compliance, security, SEO or other professional advice, and using the Actor does not create an advisory relationship. Tesselyn does not promise any outcome, including rankings, Core Web Vitals assessments or traffic. You are responsible for checking results and for the changes and decisions you make based on them.
- **No warranty; limitation of liability.** To the maximum extent permitted by applicable law, the Actor and its output are provided "as is" and "as available", without warranties of any kind, express or implied (including accuracy, completeness, merchantability, fitness for a particular purpose and non-infringement), as set out in section 7 of the Apify Standard Actor Contract. The Actor creator (Tesselyn) is not liable for any indirect, incidental, special, consequential or punitive loss or damage, including lost traffic, rankings, revenue, profits or data, arising from use of or reliance on the Actor or its output. Any other liability is limited as set out in section 8 of that Contract, and nothing here limits liability that cannot be limited under applicable law. Output is for information only and is not SEO, legal or other professional advice.

### Privacy notice

- **What is processed:** the URLs you submit, your own Google API key if you provide one (held only for the duration of the run, encrypted at rest by Apify as a secret input), and the public technical metrics Google returns (scores, timings, opportunity titles). No page HTML, cookies, emails or other personal data are stored by this Actor.
- **Where it is stored:** only in your own Apify run storage (default dataset, `OUTPUT` record, run log and encrypted input), under your Apify account and Apify's retention settings. The Actor sends the audited URL and the API key in use (yours or the built-in one) to Google's PageSpeed Insights API as required to perform the measurement; it sends nothing else to third parties.
- **Roles:** for any personal data in your input or output, you are the controller and the Actor creator acts as processor, as set out in section 5 of the Apify Standard Actor Contract. Run logs contain only counts, error codes and which key source was used — **never any API key**.
- **Deletion:** delete the run or dataset in Apify Console at any time. For questions or privacy requests, open an issue on the Actor's Issues tab.

### FAQ

#### Do I need my own Google API key?

No. By default the Actor uses a built-in key. Google meters PageSpeed Insights API usage per Cloud project, and the built-in key's daily quota is shared by all users. For heavy or scheduled usage, add your own key in `googleApiKey` so you get your own quota; your key always takes priority.

#### What happens if the built-in key's quota runs out?

Audits come back as rows with `error: "QUOTA_EXCEEDED"` and `charged: false`, and the remaining audits in that run are skipped and not charged. Try again later or add your own key.

#### Is commercial use of PSI allowed?

Check Google's own terms: your use of the PageSpeed Insights API, including commercial use, is governed by the [Google APIs Terms of Service](https://developers.google.com/terms) and your Google Cloud project's terms. This is not legal advice.

#### Why is CrUX / field data missing?

Google only returns Chrome User Experience Report data for URLs/origins with enough traffic. Lab (Lighthouse) metrics are always attempted. Google has also announced plans to move CrUX out of this API toward the dedicated CrUX APIs.

#### Why was my URL rejected?

Only public `http`/`https` URLs on ports 80/443 are accepted. `localhost`, private IPs, link-local / cloud-metadata addresses and URLs with embedded credentials are blocked (SSRF protection).

#### Does a failed audit cost money?

No. Timeouts, quota errors (`QUOTA_EXCEEDED`), invalid keys, blocked URLs and malformed responses are free. Only rows with a Lighthouse result are charged as `url-audited`.

### Related Tesselyn tools

- [AI Crawler & llms.txt Checker](https://apify.com/tesselyn/ai-search-readiness-auditor): see which AI crawlers a site's robots.txt allows, check llms.txt and get a 0–100 GEO readiness score.
- [Broken Link & Redirect Checker](https://apify.com/tesselyn/broken-link-checker): crawl a site for broken links, redirect chains and missing #anchors.
- [Domain Health Checker](https://apify.com/tesselyn/domain-health-checker): domain expiry, DNS, SPF/DMARC/DKIM, SSL and HSTS in bulk.
- See [all Tesselyn Actors on the Apify Store](https://apify.com/tesselyn).

### Support

Built and maintained by **Tesselyn** (a brand of HevraBest Group Ltd). Found a bug or a wrong result, or need a feature? Open an issue on the Actor's **Issues** tab. That is our support channel and the route Apify uses for credit compensation.

**Failed runs and unexpected charges.** Rows that the "How much does it cost?" section lists as free are not charged. Apify's small per-run "Actor start" charge, when it is listed on the Pricing tab, still applies. If you think a run charged you for work it didn't deliver, open an issue with the run link. If we confirm the problem, we ask Apify to compensate you. Apify gives compensation as **platform credits**, not money. Apify's General Terms (section 7.9) require charge disputes to be sent to Apify in writing within 15 days of the charge or invoice date, so please report problems promptly.

# Actor input Schema

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

Optional. Leave empty to use the built-in key.

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

Public http(s) URLs on ports 80/443 only (up to 200). Private, loopback and cloud-metadata addresses are rejected. Each URL is audited once per selected strategy.

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

Lighthouse emulation form factor. 'both' runs mobile and desktop for every URL (two charged events per URL when both succeed).

## `maxAudits` (type: `integer`):

Hard cap on successful+attempted audits in this run. Bounds cost: you pay only for audits that return a Lighthouse result.

## `includeAllCategories` (type: `boolean`):

Off (default): only the Performance category (faster, cheaper on Google quota). On: also request accessibility, best-practices and seo scores.

## `requestTimeoutSecs` (type: `integer`):

Google runs Lighthouse remotely; 60–90 s is typical. Timeouts are reported as errors and not charged.

## `minDelayMs` (type: `integer`):

Politeness toward Google's API (and your quota). Default 1 s between calls.

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

Keep low to avoid Google rate limits. Free-tier projects are typically limited to a few QPS.

## Actor input object example

```json
{
  "urls": [
    {
      "url": "https://www.example.com/"
    },
    {
      "url": "https://web.dev/"
    }
  ],
  "strategy": "mobile",
  "maxAudits": 2,
  "includeAllCategories": false,
  "requestTimeoutSecs": 90,
  "minDelayMs": 1000,
  "maxConcurrency": 2
}
```

# Actor output Schema

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

All rows in the default dataset.

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

Run-level summary 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": [
        {
            "url": "https://www.example.com/"
        },
        {
            "url": "https://web.dev/"
        }
    ],
    "maxAudits": 2
};

// Run the Actor and wait for it to finish
const run = await client.actor("tesselyn/pagespeed-checker").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": [
        { "url": "https://www.example.com/" },
        { "url": "https://web.dev/" },
    ],
    "maxAudits": 2,
}

# Run the Actor and wait for it to finish
run = client.actor("tesselyn/pagespeed-checker").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": [
    {
      "url": "https://www.example.com/"
    },
    {
      "url": "https://web.dev/"
    }
  ],
  "maxAudits": 2
}' |
apify call tesselyn/pagespeed-checker --silent --output-dataset

```

## MCP server setup

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

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/Pugygyt2D69tDQAz3/builds/WpTvhg37wmwpGLnT1/openapi.json
