# Bulk Website Speed & Quality Auditor (Lighthouse CWV) (`inn_corp/site-quality-auditor`) Actor

Run Google's own open-source Lighthouse against a list of URLs in a real headless Chrome. Get Performance, Accessibility, Best Practices, and SEO scores plus Core Web Vitals (LCP, CLS, TBT, FCP) per URL, with top opportunities and a hosted full report.

- **URL**: https://apify.com/inn\_corp/site-quality-auditor.md
- **Developed by:** [Inn Corp](https://apify.com/inn_corp) (community)
- **Categories:** Automation, SEO tools, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$40.00 / 1,000 page auditeds

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Bulk Website Speed & Quality Auditor (Lighthouse Core Web Vitals)

Give it a list of URLs, get back real **Google Lighthouse** scores and Core
Web Vitals for each one: Performance, Accessibility, Best Practices, SEO,
plus LCP, CLS, TBT, and FCP with their real units. Every audit runs in an
actual headless Chrome, the same engine behind Chrome DevTools' own
Lighthouse panel, not a headless-HTTP approximation. Built because the
store's cheapest real competitor charges about $0.04/page and clears roughly
100 users a month, proving people will pay for this; the only free
alternative sits at a fraction of that demand despite costing nothing, which
says the gap isn't price, it's whether the tool actually works reliably run
after run. That reliability gap is what this Actor is built to close.

### What it does

- Launches a real, isolated headless Chrome browser context per URL (via
  Puppeteer) and drives Google's own open-source `lighthouse` npm package
  against it, exactly the tool built into Chrome DevTools.
- Scores whichever of Lighthouse's four real categories you ask for:
  `performance`, `accessibility`, `best-practices`, `seo` (0-100 each).
- Reports Core Web Vitals straight from Lighthouse's own audit output:
  **LCP**, **CLS**, **TBT**, and **FCP**, each with the real unit Lighthouse
  itself reports (milliseconds or unitless). See "About INP" below for why
  Interaction to Next Paint is reported as `null` here rather than guessed.
- Surfaces the top scoring **opportunities** (Lighthouse's own
  savings-estimated audits, e.g. "reduce unused JavaScript") and top
  **diagnostics** (other failing audits) per URL, so you get a usable
  summary without downloading the full report.
- Hosts the complete Lighthouse report, JSON and HTML, in the run's
  key-value store and links it from `fullReportUrl`.
- Runs `mobile` (Lighthouse's own default, matching how Core Web Vitals
  field data is conventionally reported) or `desktop`, with realistic
  network/CPU throttling on by default, exactly matching Lighthouse's own
  defaults, both switchable per run.

### What it deliberately does not do

- **No content scraping.** This Actor never reads, stores, or returns page
  text, images, or markup. It measures how the page performs when loaded,
  the same thing Chrome DevTools measures locally on your own machine.
- **No invented numbers.** Every score and every metric comes straight out
  of Lighthouse's own report object (the `lhr`). A category you did not
  request, or a metric Lighthouse itself could not compute for that page, is
  `null`, never a guess or a zero standing in for "unknown."
- **No silent hangs.** Each URL gets a wall-clock budget
  (`timeoutPerUrlSecs`); a page that will not finish loading gets a clean
  `timeout` record instead of stalling the whole run. Verified against a
  server that never responds: the run continues cleanly to the next URL.

#### About INP

Real-world Core Web Vitals report **INP** (Interaction to Next Paint), which
needs an actual user interaction to measure. Lighthouse's own
`interaction-to-next-paint` audit only runs in a "timespan" user-flow mode
built around simulated interactions; a single-page navigation audit (what
every run of this Actor does, and what the Lighthouse CLI and PageSpeed
Insights' lab data both do too) never triggers it. This Actor reports `INP`
as `null` and reports **TBT** (Total Blocking Time) instead, which is
Lighthouse's own lab-metric proxy for responsiveness and the one that
actually carries scoring weight in the Performance category. That is not a
shortcut; it is what Lighthouse itself does.

#### About run-to-run variance

Lighthouse scores are not perfectly deterministic. Network jitter, the
Chrome process's own background work, and DNS timing can move the same
page's score by a few points between two runs seconds apart, even with
simulated throttling. This is a known, expected property of Lighthouse
itself (Google documents it), not a bug in this Actor. For scores you plan
to track over time, run more than once and look at the trend, not a single
number.

### Output example

A real record from an actual desktop run against `https://www.apify.com/`
(`timeoutPerUrlSecs: 90`, throttling on, all four categories):

```json
{
  "url": "https://www.apify.com/",
  "device": "desktop",
  "scores": { "performance": 61, "accessibility": 100, "bestPractices": 54, "seo": 92 },
  "coreWebVitals": {
    "LCP": { "value": 2229.379, "unit": "millisecond" },
    "CLS": { "value": 0.003442, "unit": "unitless" },
    "TBT": { "value": 474.5, "unit": "millisecond" },
    "FCP": { "value": 1273.448, "unit": "millisecond" },
    "INP": null
  },
  "topOpportunities": [
    { "id": "redirects", "title": "Avoid multiple page redirects", "savingsMs": 434, "description": "Redirects introduce additional delays before the page can be loaded. ..." },
    { "id": "unused-javascript", "title": "Reduce unused JavaScript", "savingsMs": 200, "description": "Reduce unused JavaScript and defer loading scripts until they are required ..." },
    { "id": "server-response-time", "title": "Initial server response time was short", "savingsMs": 126, "description": "Keep the server response time for the main document short ..." }
  ],
  "topDiagnostics": [
    { "id": "errors-in-console", "title": "Browser errors were logged to the console", "score": 0, "description": "Errors logged to the console indicate unresolved problems. ..." },
    { "id": "deprecations", "title": "Uses deprecated APIs", "score": 0, "description": "Deprecated APIs will eventually be removed from the browser. ..." }
  ],
  "fullReportUrl": "https://api.apify.com/v2/key-value-stores/<storeId>/records/report-www-apify-com-desktop.json",
  "status": "ok",
  "error": null,
  "fetchedAt": "2026-08-25T23:35:40.997Z"
}
```

The same run scored `https://www.wikipedia.org/` at a real `100` and
`https://developer.mozilla.org/en-US/` at a real `99` on desktop performance;
`apify.com`'s `61` came from real third-party tracking scripts and redirects
Lighthouse actually flagged, not a placeholder. A malformed URL (e.g.
`"not-a-real-url"`) or an unreachable host each return a clean
`status: "error"` record with `scores` and `coreWebVitals` all `null` and
zero charge; a URL that never finishes loading returns `status: "timeout"`,
also `null` fields, also zero charge.

### Input

| Field | Meaning |
| --- | --- |
| `urls` | Pages to audit. Required. Each gets its own Chrome run and its own record. |
| `device` | `mobile` (default, Lighthouse's own default) or `desktop`. |
| `categories` | Which of Lighthouse's four real categories to score: `performance`, `accessibility`, `best-practices`, `seo`. Default all four. Fewer categories run faster since Lighthouse only executes the audits each one needs. |
| `throttling` | Default on: `throttlingMethod` is Lighthouse's own default, `"simulate"` (mid-tier mobile device, throttled connection). Off sets `throttlingMethod` to `"provided"`: no simulation, Lighthouse measures the page under this Actor's own real network/CPU. |
| `timeoutPerUrlSecs` | Wall-clock budget per URL, default 90s (min 30, max 180). A full 4-category simulated-throttling run typically finishes in 20-60s; heavy pages can take longer. |

### Typical uses

- Audit every page on a client site before a launch, in one run, instead of
  opening DevTools tab by tab.
- Track Core Web Vitals for a set of competitor or portfolio URLs on a
  schedule and watch the trend.
- Feed `topOpportunities` straight into a report or ticket queue instead of
  reading the full Lighthouse HTML report for every page.
- Gate a CI/CD pipeline on a performance-score floor using the dataset's
  `scores.performance` field.

### Fair pricing

Pay per URL successfully audited (`page-audited`), once pay-per-event
pricing is enabled. A URL that errors (malformed, unreachable, blocked) or
times out is never charged; you only pay for a real, completed audit. No
subscription.

# Actor input Schema

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

Pages to run Google Lighthouse against. Each URL gets its own real headless-Chrome run and its own dataset record.

## `device` (type: `string`):

Which Lighthouse emulation profile to run. "Mobile" is Lighthouse's own default and matches the convention real Core Web Vitals field data is reported under.

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

Which Lighthouse category scores to compute (these are Lighthouse's own real category ids). Fewer categories means a faster run per URL, since Lighthouse only executes the audits each selected category needs.

## `throttling` (type: `boolean`):

On (default): throttlingMethod is Lighthouse's own default, "simulate" — scores reflect a mid-tier mobile device on a throttled connection, the same convention Lighthouse and PageSpeed Insights use. Off: throttlingMethod is set to "provided" — Lighthouse measures the page exactly as this Actor's own container network/CPU experiences it, with no simulation applied.

## `timeoutPerUrlSecs` (type: `integer`):

Wall-clock budget for one URL's full Lighthouse run (page load plus every selected category's audits). A full 4-category simulated-throttling mobile run typically finishes in 20-60 seconds; heavy pages can take longer. On timeout the URL's record gets status "timeout" and is not charged.

## Actor input object example

```json
{
  "urls": [
    "https://www.wikipedia.org/"
  ],
  "device": "mobile",
  "categories": [
    "performance",
    "accessibility",
    "best-practices",
    "seo"
  ],
  "throttling": true,
  "timeoutPerUrlSecs": 90
}
```

# Actor output Schema

## `records` (type: `string`):

No description

# 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://www.wikipedia.org/",
        "https://developer.mozilla.org/en-US/",
        "https://www.apify.com/"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("inn_corp/site-quality-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://www.wikipedia.org/",
        "https://developer.mozilla.org/en-US/",
        "https://www.apify.com/",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("inn_corp/site-quality-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://www.wikipedia.org/",
    "https://developer.mozilla.org/en-US/",
    "https://www.apify.com/"
  ]
}' |
apify call inn_corp/site-quality-auditor --silent --output-dataset

```

## MCP server setup

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