# Bulk PageSpeed & Core Web Vitals Checker

> Run Google PageSpeed Insights on hundreds of URLs: performance, SEO, accessibility scores, lab metrics, real-user Core Web Vitals (LCP, INP, CLS from CrUX) with pass/fail, and the top fixes per page. Mobile and desktop. $5 per 1,000 tests, no Google key needed.

- Category: Rank tracking & site SEO
- Price: $5 per 1,000 × pagespeed test, billed per result by Apify (no subscription); any other billed events are listed on the Store page. Cap any run with `maxTotalChargeUsd`.
- Store page: https://apify.com/wrenfield-data/bulk-pagespeed-checker
- Human page: https://wrenfielddata.com/tools/bulk-pagespeed-checker/
- OpenAPI 3 spec: https://api.apify.com/v2/acts/wrenfield-data~bulk-pagespeed-checker/builds/default/openapi.json
- MCP tool: https://mcp.apify.com?tools=wrenfield-data/bulk-pagespeed-checker (appears as `wrenfield-data--bulk-pagespeed-checker`)

## Call it

Synchronous run that returns the dataset rows as JSON (use `/runs` for long jobs and poll; see the OpenAPI spec):

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/wrenfield-data~bulk-pagespeed-checker/run-sync-get-dataset-items" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"urls": ["https://apify.com", "https://example.com"], "devices": ["mobile"]}'
```

## Input

| Field | Type | Required | Default | Description |
|---|---|---|---|---|
| `urls` | array | yes | `["https://apify.com", "https://example.com"]` | Pages to test, one per line (up to 5,000). https:// is added when missing. |
| `devices` | array |  | `["mobile"]` | Each URL is tested once per device. |
| `categories` | array |  | `["performance", "seo"]` | Scores to include. Performance is always included. |
| `maxOpportunities` | integer |  | `5` | How many improvement opportunities (with estimated savings) to list per test. |
| `googleApiKey` | string |  |  | Optional free PageSpeed Insights API key from Google Cloud, for very large jobs. Not needed: the Actor has its own. |
| `useBackupService` | boolean |  | `true` | If Google PageSpeed Insights is over its quota, test pages on a backup Lighthouse service instead (lab data only, no real-user Core Web Vitals; lighthouse-test event). |

## Example input

```json
{
  "urls": [
    "https://apify.com",
    "https://example.com"
  ],
  "devices": [
    "mobile"
  ]
}
```

## Output fields

One flat row per result:

| Field | Type | Description |
|---|---|---|
| `url` | string | URL tested |
| `device` | string | mobile or desktop |
| `status` | string | ok or error |
| `error` | string | Why the test failed |
| `engine` | string | pagespeed_insights (Google, lab + real-user data) or lighthouse_backup (lab data only) |
| `final_url` | string | URL after redirects |
| `redirected` | boolean | The URL redirected |
| `performance_score` | integer | Lighthouse performance score 0-100 |
| `accessibility_score` | integer | Accessibility score 0-100 (if requested) |
| `best_practices_score` | integer | Best practices score 0-100 (if requested) |
| `seo_score` | integer | SEO score 0-100 (if requested) |
| `cwv_assessment` | string | Core Web Vitals assessment from real users (CrUX): passed, failed or no_data |
| `field_data_scope` | string | url = real-user data for this page; origin = whole-site data (page has too little traffic) |
| `origin_cwv_assessment` | string | Core Web Vitals assessment for the whole site |
| `field_lcp_p75` | number | Real-user LCP at the 75th percentile (ms) |
| `field_inp_p75` | number | Real-user INP at the 75th percentile (ms) |
| `field_cls_p75` | number | Real-user CLS at the 75th percentile (unitless) |
| `field_fcp_p75` | number | Real-user FCP at the 75th percentile (ms) |
| `field_ttfb_p75` | number | Real-user TTFB at the 75th percentile (ms) |
| `field_lcp_rating` | string | Real-user LCP rating: fast, average or slow |
| `field_inp_rating` | string | Real-user INP rating: fast, average or slow |
| `field_cls_rating` | string | Real-user CLS rating: fast, average or slow |
| `field_fcp_rating` | string | Real-user FCP rating: fast, average or slow |
| `field_ttfb_rating` | string | Real-user TTFB rating: fast, average or slow |
| `lab_fcp_ms` | integer | Lab First Contentful Paint (ms) |
| `lab_lcp_ms` | integer | Lab Largest Contentful Paint (ms) |
| `lab_tbt_ms` | integer | Lab Total Blocking Time (ms) |
| `lab_cls` | number | Lab Cumulative Layout Shift |
| `lab_speed_index_ms` | integer | Lab Speed Index (ms) |
| `lab_tti_ms` | integer | Lab Time to Interactive (ms) |
| `lab_server_response_ms` | integer | Server response time (ms) |
| `page_weight_bytes` | integer | Total page weight (bytes) |
| `requests_count` | integer | Network requests |
| `opportunities` | array | Top fixes with estimated savings |
| `failed_audits` | array | Common audits the page fails (compression, render-blocking, images, meta description, ...) |
| `lighthouse_version` | string | Lighthouse version |
| `checked_at` | string | When the test ran (ISO 8601, UTC) |

## Notes

- Auth: an Apify API token as `Authorization: Bearer <token>`; the MCP server also supports OAuth sign-in.
- Failed or empty results are not charged on most tools; check the pricing on the Store page.
- Questions: hello@wrenfielddata.com
