# Website Carbon & Page Weight Checker – Bulk CO2 per Page (`fast_data_asap/page-weight-carbon-checker`) Actor

Bulk-measure page weight, requests, JS/CSS/image bytes and estimated CO2 per page view. Find heavy pages and missing compression. $4 per 1,000.

- **URL**: https://apify.com/fast_data_asap/page-weight-carbon-checker.md
- **Developed by:** [Fast Data](https://apify.com/fast_data_asap) (community)
- **Categories:** SEO tools, Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$4.00 / 1,000 page analyseds

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

## Page Weight, Resource Budget & Website Carbon Checker

Measure **how heavy your web pages really are** and **how much CO2 each page view emits**, for a list of URLs or a whole sitemap, without starting a browser.

For every page the actor downloads the HTML and every resource it references (scripts, stylesheets, images including `srcset` and `<picture>`, web fonts from CSS `@font-face`, CSS `@import`, iframes, icons and preloads). It records the real **transfer size**, **compression** (gzip / brotli), **cache headers** and **third-party domains**, then estimates **grams of CO2 per page view** with the **Sustainable Web Design Model v4** and checks each page against your **performance budgets** (default: 2 MB and 60 requests).

### What you get per page

- `totalBytes` / `totalKB`, and bytes by type: `htmlBytes`, `jsBytes`, `cssBytes`, `imageBytes`, `fontBytes`, `otherBytes`
- `requestCount` plus requests by type, `failedRequests`
- `thirdPartyRequests`, `thirdPartyBytes`, `thirdPartyDomains`
- `largestResources`: the 5 heaviest files
- `uncompressedTextResources`: JS/CSS/HTML/SVG/JSON served without gzip or brotli (with estimated savings)
- `nonModernImages`: JPEG/PNG/GIF images that could be WebP or AVIF
- `poorlyCachedResources`: files with no cache header or a max-age under 1 day
- `co2GramsPerView`, `co2GramsPer1000Views`, `energyKwhPerView`, `carbonRating` (A+ to F)
- `budgetPass` and `budgetFailures` (human-readable reasons)
- optional `resources`: the full list of every resource with type, bytes, encoding, cache max-age and third-party flag

### Who it is for

- **SEO and web performance agencies** auditing many client pages at once
- **Developers and CI pipelines** enforcing page weight and request budgets
- **Sustainability / ESG teams** reporting website emissions with a documented, standard model
- **Ecommerce and content teams** finding oversized images, missing compression and third-party bloat

### Why this actor

- **Fast and cheap**: plain HTTP, no headless browser. The default 2-page test finishes in about 4 seconds.
- **Real transfer bytes**: every resource is actually downloaded with `Accept-Encoding: gzip, deflate, br`, and the compressed bytes on the wire are counted, not guessed from HTML.
- **Smart about what browsers really load**: picks one `srcset` candidate per image (like a desktop browser), takes the first `<picture>` source instead of the fallback, skips `@font-face` subsets that do not cover Latin characters, follows CSS `@import`.
- **Bulk**: paste hundreds of URLs or give a sitemap (including sitemap indexes and `.xml.gz`).
- **Transparent carbon model** with documented constants (below) and a configurable grid intensity.
- **Pay only for pages that were analysed**: pages that fail to load are free and returned with `status: "error"`.

### Input example

```json
{
  "urls": ["https://www.gov.uk/", "https://www.wikipedia.org/"],
  "sitemapUrl": "https://www.example.com/sitemap.xml",
  "maxUrls": 50,
  "budgetTotalKb": 2048,
  "budgetRequests": 60,
  "budgetJsKb": 500,
  "budgetCo2Grams": "0.3",
  "gridIntensity": 494,
  "includeAllResources": false
}
```

Only `urls` or `sitemapUrl` is required. Optional budgets set to 0 (or empty) are off.

### Output example

Real values from a test run (shortened):

```json
{
  "url": "https://www.gov.uk/",
  "status": "ok",
  "title": "Welcome to GOV.UK",
  "totalBytes": 185641,
  "totalKB": 181.3,
  "htmlBytes": 11262,
  "jsBytes": 55087,
  "cssBytes": 44185,
  "imageBytes": 10245,
  "fontBytes": 64862,
  "otherBytes": 0,
  "htmlDecodedBytes": 85520,
  "htmlCompression": "br",
  "requestCount": 16,
  "jsRequests": 5,
  "cssRequests": 2,
  "imageRequests": 6,
  "fontRequests": 2,
  "thirdPartyRequests": 0,
  "thirdPartyDomains": [],
  "co2GramsPerView": 0.0275,
  "co2GramsPer1000Views": 27.5,
  "carbonRating": "A+",
  "budgetPass": true,
  "budgetFailures": [],
  "largestResources": [
    {"url": "https://www.gov.uk/assets/frontend/application-5c33....css", "type": "css", "bytes": 42756},
    {"url": "https://www.gov.uk/assets/frontend/application-8fe6....js", "type": "js", "bytes": 41563}
  ],
  "uncompressedTextCount": 0,
  "nonModernImageCount": 4,
  "nonModernImageBytes": 8228,
  "nonModernImages": [
    {"url": "https://www.gov.uk/assets/frontend/app-promo/govuk-app-icon-0bca....png", "contentType": "image/png", "bytes": 4351}
  ],
  "poorlyCachedCount": 0
}
```

The second test page, `https://www.wikipedia.org/`, came out at 201.7 KB and 11 requests. 6 of those requests went to the third-party domain `upload.wikimedia.org`, and most of the weight was PNG images (0.0306 g CO2 per view, A+).

### Carbon model: Sustainable Web Design Model v4

`co2GramsPerView = totalBytes / 10^9 × 0.300 kWh/GB × grid intensity`

| Segment | Operational kWh/GB | Embodied kWh/GB |
|---|---|---|
| Data centres | 0.055 | 0.012 |
| Networks | 0.059 | 0.013 |
| User devices | 0.080 | 0.081 |
| **Total** | | **0.300** |

- Grid intensity default: **494 gCO2e/kWh** (global average, Ember 2023, as used by SWD v4 and CO2.js). Set `gridIntensity` to use your country's value.
- The estimate covers one first visit (no browser cache) and has no green-hosting adjustment.
- Rating thresholds (g per view): A+ ≤ 0.040, A ≤ 0.079, B ≤ 0.145, C ≤ 0.209, D ≤ 0.278, E ≤ 0.359, F above.

### Notes and limits

- This is static analysis: resources injected later by JavaScript (ads, lazy widgets, tag managers) are not followed, so JS-heavy pages show a **lower bound**. Iframe documents are counted, but not their sub-resources.
- Bytes are response body bytes on the wire (HTTP headers not included). Third-party = different registrable domain from the page.
- CSS background images are only counted when set in inline `style` attributes.
- Only public pages. No logins and no bot-protection bypass. A proxy can be enabled if a site blocks datacenter IPs.

### Pricing

**$0.004 per page analysed** ($4 per 1,000 pages), charged with the `page` event. Pages that fail to load are free. Platform usage is minimal because no browser runs.

### API, n8n and MCP usage

**API** (sync, returns dataset items):

```bash
curl -X POST "https://api.apify.com/v2/acts/fast_data_asap~page-weight-carbon-checker/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"urls": ["https://www.gov.uk/"], "budgetTotalKb": 1024}'
```

**n8n / Make / Zapier**: use the Apify node or app, pick the actor `fast_data_asap/page-weight-carbon-checker`, pass the same JSON input and read the dataset items. One way to use it in CI: fail a build when `budgetPass` is `false`.

**MCP (Claude, Cursor and other AI agents)**: add the server
`https://mcp.apify.com?tools=fast_data_asap/page-weight-carbon-checker`
and ask, for example: "Check the page weight and CO2 per view of these 20 URLs and list which ones fail a 1 MB budget."

# Actor input Schema

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

Pages to analyse. Each page's HTML and every resource it references (scripts, stylesheets, images incl. srcset, fonts, iframes) are downloaded to measure the real transfer size.

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

Optional. A sitemap.xml (or sitemap index, .xml.gz or text sitemap). Its page URLs are added to the list, up to 'Max URLs from sitemap'.

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

Limits how many pages are taken from the sitemap.

## `budgetTotalKb` (type: `integer`):

Pages heavier than this fail the budget. 2048 KB = 2 MB. 0 = off.

## `budgetRequests` (type: `integer`):

Pages with more requests than this fail the budget. 0 = off.

## `budgetJsKb` (type: `integer`):

Optional. 0 = off.

## `budgetCssKb` (type: `integer`):

Optional. 0 = off.

## `budgetImageKb` (type: `integer`):

Optional. 0 = off.

## `budgetFontKb` (type: `integer`):

Optional. 0 = off.

## `budgetCo2Grams` (type: `string`):

Optional, e.g. 0.3. Pages emitting more CO2 per view fail the budget. Empty = off.

## `gridIntensity` (type: `integer`):

Used for the CO2 estimate. Default 494 = global average used by the Sustainable Web Design Model v4.

## `includeAllResources` (type: `boolean`):

Adds every resource (URL, type, bytes, encoding, cache max-age, third-party flag) to each page item.

## `maxResourcesPerPage` (type: `integer`):

Safety limit on how many resources are downloaded for one page.

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

How many resource requests run at the same time (across all pages).

## `pageConcurrency` (type: `integer`):

How many pages are analysed at the same time.

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

Timeout per request.

## `proxyConfiguration` (type: `object`):

Optional. Not needed for most public sites.

## Actor input object example

```json
{
  "urls": [
    "https://www.gov.uk/",
    "https://www.wikipedia.org/"
  ],
  "maxUrls": 20,
  "budgetTotalKb": 2048,
  "budgetRequests": 60,
  "budgetJsKb": 0,
  "budgetCssKb": 0,
  "budgetImageKb": 0,
  "budgetFontKb": 0,
  "gridIntensity": 494,
  "includeAllResources": false,
  "maxResourcesPerPage": 200,
  "maxConcurrency": 12,
  "pageConcurrency": 3,
  "requestTimeoutSecs": 20,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `results` (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.gov.uk/",
        "https://www.wikipedia.org/"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("fast_data_asap/page-weight-carbon-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": [
        "https://www.gov.uk/",
        "https://www.wikipedia.org/",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("fast_data_asap/page-weight-carbon-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": [
    "https://www.gov.uk/",
    "https://www.wikipedia.org/"
  ]
}' |
apify call fast_data_asap/page-weight-carbon-checker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,fast_data_asap/page-weight-carbon-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/l2i097JcFbhjkfR2h/builds/C9xVl36m1HK2dVGwL/openapi.json
