# Bulk Lighthouse Audit — PageSpeed Scores Without an API Key (`nexgensignal/website-performance-audit-api`) Actor

Bulk Lighthouse audits with no PageSpeed API key or quota: for every URL, the four Lighthouse scores, Core Web Vitals lab metrics (LCP, CLS, TBT) and the audits the page fails, on mobile or desktop. Pay per audited page. Part of NexGen Signal — data tools and official-source data products

- **URL**: https://apify.com/nexgensignal/website-performance-audit-api.md
- **Developed by:** [NexGen Signal](https://apify.com/nexgensignal) (community)
- **Categories:** SEO tools, Automation, Developer tools
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $33.50 / 1,000 website audit records

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 Lighthouse Audit — PageSpeed Scores Without an API Key

**PageSpeed-style Lighthouse scores for a whole list of pages, with no Google API key, no daily quota and no setup.** Send web addresses and get one audit per page: performance, accessibility, best-practices and SEO scores (0–100), the lab Core Web Vitals and loading metrics — Largest Contentful Paint, Cumulative Layout Shift, Total Blocking Time, First Contentful Paint, Speed Index, server response time, page weight — and every audit the page fails, with its id and title. Mobile or desktop.

**Pay per audited page.** Use it to rank a site's pages or a client portfolio by score, compare before and after a release, or schedule a weekly check on your landing pages.

Every audit is run by this Actor with **Google Lighthouse 13.5.0 in its own headless Chrome** — the same open-source engine (Apache License 2.0) behind Chrome DevTools and PageSpeed Insights. It does not call the PageSpeed Insights API, so there is no Google API key, no daily quota and no extra fee.

Use it three ways:

- **Site or portfolio audit.** Send every important page of one site, or the home pages of all your clients, and sort by score.
- **Before-and-after checks.** Audit the same addresses before and after a release, a theme change or a CDN switch.
- **Monitoring.** Schedule a run each week on your key landing pages and watch the scores and LCP over time.

### Who buys this and for what job

- **SEO agencies and consultants** producing performance and technical-SEO reports for many client sites at once.
- **Web developers and agencies** checking speed and accessibility before and after a launch.
- **E-commerce and marketing teams** watching landing-page speed, which affects conversion and ad quality.
- **Accessibility and QA teams** screening many pages for common accessibility failures.
- **Lead-generation and sales teams** qualifying websites by how slow or dated they are.

### Sample output

![Sample output — Website Performance Audit API](https://api.apify.com/v2/key-value-stores/IXCaMKjxSmUTLHhmq/records/website-performance-audit-api.png)

One record from live run c8ij5zydVNENdO9RI (2 October 2026, mobile settings):

```json
{
  "record_id": "LH:988c511fc2e9",
  "requested_url": "https://www.python.org/",
  "final_url": "https://www.python.org/",
  "form_factor": "mobile",
  "performance_score": 83,
  "accessibility_score": 75,
  "best_practices_score": 96,
  "seo_score": 92,
  "first_contentful_paint_ms": 2908,
  "largest_contentful_paint_ms": 3957,
  "total_blocking_time_ms": 42,
  "cumulative_layout_shift": 0.003,
  "speed_index_ms": 2908,
  "time_to_interactive_ms": 4105,
  "server_response_time_ms": 2,
  "total_byte_weight_bytes": 483110,
  "failing_performance_audits": [
    {
      "id": "largest-contentful-paint",
      "title": "Largest Contentful Paint",
      "score": 51
    },
    {
      "id": "first-contentful-paint",
      "title": "First Contentful Paint",
      "score": 53
    },
    {
      "id": "cache-insight",
      "title": "Use efficient cache lifetimes",
      "score": 0
    },
    {
      "id": "image-delivery-insight",
      "title": "Improve image delivery",
      "score": 0
    },
    {
      "id": "network-dependency-tree-insight",
      "title": "Network dependency tree",
      "score": 0
    },
    {
      "id": "render-blocking-insight",
      "title": "Render-blocking requests",
      "score": 0
    },
    {
      "id": "unminified-css",
      "title": "Minify CSS",
      "score": 0
    },
    {
      "id": "unused-css-rules",
      "title": "Reduce unused CSS",
      "score": 0
    },
    {
      "id": "unused-javascript",
      "title": "Reduce unused JavaScript",
      "score": 0
    },
    {
      "id": "font-display-insight",
      "title": "Font display",
      "score": 50
    },
    {
      "id": "unminified-javascript",
      "title": "Minify JavaScript",
      "score": 50
    },
    {
      "id": "interactive",
      "title": "Time to Interactive",
      "score": 86
    }
  ],
  "failing_accessibility_audits": [
    {
      "id": "aria-required-children",
      "title": "Elements with an ARIA `[role]` that require children to contain a specific `[role]` are missing some or all of those required children.",
      "score": 0
    },
    {
      "id": "aria-required-parent",
      "title": "`[role]`s are not contained by their required parent element",
      "score": 0
    },
    {
      "id": "aria-hidden-focus",
      "title": "`[aria-hidden=\"true\"]` elements contain focusable descendents",
      "score": 0
    },
    {
      "id": "color-contrast",
      "title": "Background and foreground colors do not have a sufficient contrast ratio.",
      "score": 0
    },
    {
      "id": "list",
      "title": "Lists do not contain only `<li>` elements and script supporting elements (`<script>` and `<template>`).",
      "score": 0
    },
    {
      "id": "listitem",
      "title": "List items (`<li>`) are not contained within `<ul>`, `<ol>` or `<menu>` parent elements.",
      "score": 0
    },
    {
      "id": "tabindex",
      "title": "Some elements have a `[tabindex]` value greater than 0",
      "score": 0
    }
  ],
  "failing_best_practices_audits": [
    {
      "id": "errors-in-console",
      "title": "Browser errors were logged to the console",
      "score": 0
    }
  ],
  "failing_seo_audits": [
    {
      "id": "link-text",
      "title": "Links do not have descriptive text",
      "score": 0
    }
  ],
  "lighthouse_version": "13.5.0",
  "throttling_method": "simulate",
  "benchmark_index": 2051,
  "run_warnings": [],
  "source": "Google Lighthouse 13.5.0, run by this Actor in its own headless Chrome against the address you supplied (https://github.com/GoogleChrome/lighthouse)",
  "source_dataset": "Lighthouse audit — performance, accessibility, best-practices and SEO categories, mobile settings",
  "licence": "Lighthouse is open-source software under the Apache License 2.0. This audit was generated by this run; the audited page belongs to its owner and no page content is copied into the record.",
  "attribution": "Audit produced with Google Lighthouse (Apache License 2.0); reformatted by NexGen Signal.",
  "observed_at": "2026-10-03T05:20:17Z"
}
```

### What you get in each record

| Field | Meaning |
|---|---|
| `performance_score`, `accessibility_score`, `best_practices_score`, `seo_score` | Lighthouse category scores, 0–100 |
| `largest_contentful_paint_ms`, `cumulative_layout_shift`, `total_blocking_time_ms` | Lab Core Web Vitals (TBT is the lab stand-in for Interaction to Next Paint) |
| `first_contentful_paint_ms`, `speed_index_ms`, `time_to_interactive_ms` | Other loading metrics |
| `server_response_time_ms`, `total_byte_weight_bytes` | Main-document response time and total page weight |
| `failing_*_audits` | Up to 15 failing audits per category: Lighthouse audit id, title and score |
| `requested_url`, `final_url`, `form_factor` | What was audited, where redirects ended, mobile or desktop settings |
| `source`, `source_dataset`, `licence`, `attribution`, `observed_at` | Provenance stamped on every record |

Scores are **lab** results from one Lighthouse run with simulated throttling on Apify's servers. They follow the same scoring as PageSpeed Insights but can differ by a few points from run to run and from one machine to another (`benchmark_index` records the machine's CPU benchmark). Field data from real Chrome users (CrUX) is not included.

### Input

```json
{
  "urls": ["https://www.python.org/", "https://www.wikipedia.org/"],
  "formFactor": "mobile",
  "maxRecords": 2
}
```

- `urls` — up to 5,000 addresses per run; `https://` is added when missing.
- `formFactor` — `mobile` (Lighthouse default, as shown first in PageSpeed Insights) or `desktop`.
- `maxRecords` — the most audits delivered and billed in this run.
- `pageTimeoutSecs` — how long to wait for a page to load (default 60).

Audits run one after another so that one page's load does not slow another's score: allow about 10–25 seconds per page. The default run timeout is 12 hours, enough for roughly 2,500 or more pages in one run; raise it in the run options for larger lists.

### What is skipped and never charged

- **Robots.txt.** Before auditing, the Actor reads `robots.txt` on the exact host of each address. Addresses disallowed for all robots (or for `Chrome-Lighthouse` or `NexGenSignal`) are skipped.
- **Private and local addresses** (localhost, 10.x, 192.168.x, cloud metadata addresses and similar), addresses with a user name or password, non-web schemes and duplicates.
- **Pages that cannot be audited**: host names that do not resolve, pages returning an error status, pages that never finish loading.

Each address and its outcome — audited, excluded, failed or not attempted — is listed in the `RUN_RECEIPT` record of the run's key-value store. Only audited pages create dataset records, and only dataset records are charged: the dataset row count always equals the charged count.

### Privacy

Records hold scores, metric numbers and Lighthouse audit ids and titles only. Page text, HTML snippets, screenshots, cookies and request lists are not copied into the record, so personal data that appears on an audited page does not end up in your dataset.

### Pricing

| Apify plan | Price per audit record |
|---|---|
| Free | $0.05 |
| Bronze | $0.045 |
| Silver | $0.04 |
| Gold, Platinum, Diamond | $0.0335 |

One record = one audited address. You set the maximum with `maxRecords`, and you can also set a maximum total charge in the run options: the Actor stops before auditing a page it could not charge for.

### Run end states

- **Delivered N website audit(s)** — everything audited.
- **PARTIAL** — some addresses were audited; the others were excluded or failed (listed in the receipt, not charged).
- **CAPPED** — stopped at your maximum total charge.
- **Every address was checked, but none could be audited under the rules** — nothing charged.
- **SOURCE UNAVAILABLE** — none of the pages attempted could be audited; nothing charged.

Only invalid input fails a run.

### Source and licence

Audits are produced with [Google Lighthouse](https://github.com/GoogleChrome/lighthouse) 13.5.0, open-source software under the Apache License 2.0, run inside this Actor. Each audited page belongs to its owner; the record holds measurements of the page, not its content. Lighthouse and Chrome are trademarks of Google LLC; this Actor is not affiliated with or endorsed by Google.

Part of NexGen Signal — official-source data products.

# Actor input Schema

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

The pages to audit, one per line (https:// is added when missing). Each address gets one Lighthouse audit and one record. Up to 5,000 per run. Private or local addresses, addresses that the site's robots.txt disallows, and duplicates are skipped and never charged.

## `formFactor` (type: `string`):

Lighthouse's mobile or desktop settings. Mobile matches what PageSpeed Insights shows first.

## `maxRecords` (type: `integer`):

Maximum audits delivered and billed in this run. One record = one audited address. Addresses beyond this number are listed in the run receipt as not attempted.

## `pageTimeoutSecs` (type: `integer`):

How long Lighthouse waits for a page to load. A page that never finishes loading is reported as failed and not charged.

## Actor input object example

```json
{
  "urls": [
    "https://www.python.org/",
    "https://www.wikipedia.org/"
  ],
  "formFactor": "mobile",
  "maxRecords": 2,
  "pageTimeoutSecs": 60
}
```

# Actor output Schema

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

The delivered (and billed) audit records.

## `receipt` (type: `string`):

Every address with its outcome (audited, excluded, failed, not attempted) and the robots.txt decision per site.

# 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.python.org/",
        "https://www.wikipedia.org/"
    ],
    "maxRecords": 2
};

// Run the Actor and wait for it to finish
const run = await client.actor("nexgensignal/website-performance-audit-api").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.python.org/",
        "https://www.wikipedia.org/",
    ],
    "maxRecords": 2,
}

# Run the Actor and wait for it to finish
run = client.actor("nexgensignal/website-performance-audit-api").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.python.org/",
    "https://www.wikipedia.org/"
  ],
  "maxRecords": 2
}' |
apify call nexgensignal/website-performance-audit-api --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,nexgensignal/website-performance-audit-api"
        }
    }
}
```

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/zdor1HfMX5Y2F2dVC/builds/eqUjeyDcNUJeFDAke/openapi.json
