# Website Screenshot Monitor - Visual Diff & Change Alerts (`signalgrove/website-screenshot-monitor`) Actor

Capture full-page screenshots on a schedule, compare them pixel-by-pixel with the previous run, highlight what changed, and get webhook alerts. No API keys needed.

- **URL**: https://apify.com/signalgrove/website-screenshot-monitor.md
- **Developed by:** [Starsurfer](https://apify.com/signalgrove) (community)
- **Categories:** Developer tools, Automation, SEO tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $10.00 / 1,000 results

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js/docs.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/integrations/mcp.md).

If your project is in a different language, use 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

## Website Screenshot Monitor — Visual Diff & Change Alerts

Capture pixel-perfect **full-page screenshots** of any website on a schedule, automatically **compare them with the previous run**, and get alerted the moment a page **visually changes** — with the percentage changed, the exact **changed regions highlighted**, and a **red-on-gray diff image** you can eyeball in seconds.

No API keys. No LLMs. No proxies required. Just URLs in → screenshots, diffs, and alerts out.

### What it does

1. 📸 Opens each URL in a real Chrome browser and captures a full-page (or viewport) PNG screenshot.
2. 🔍 Compares it pixel-by-pixel against the screenshot from the previous run (stored automatically between runs).
3. 📊 Reports **% of pixels changed**, the number of changed pixels, and **bounding boxes of every changed region**.
4. 🖼️ Saves three images per changed page: the new **screenshot**, a **diff image** (changes in red on a faded page), and a **highlight image** (red boxes drawn on the real screenshot).
5. 🔔 Optionally POSTs a **webhook alert** (Slack, Zapier, Make, n8n, or your own endpoint) — only when something actually changed.

### Why this one?

- ✅ **Reliable by design** — automatic retries, per-URL error isolation (one broken URL never kills the run), CSS-animation freezing to prevent false positives, and lazy-load scrolling so below-the-fold images actually render.
- ✅ **True visual diffing** — most "website change monitors" compare text or HTML only. This Actor sees what your users see: layout shifts, image swaps, banner changes, redesigns, broken CSS.
- ✅ **Changes-only mode** — schedule it hourly/daily and process only what changed. Every run pushes at least one dataset item (a heartbeat when nothing changed), so your integrations never see an empty dataset and can tell "no changes" apart from "monitor broke".
- ✅ **Catches small changes on long pages** — reports a change when EITHER the changed-pixel percentage OR an absolute changed-pixel floor is hit, so a single price digit changing on a 10,000-px-tall page still triggers.
- ✅ **Two baseline modes** — compare against the *previous run* (classic monitoring) or a *fixed baseline* (visual-regression testing against an approved state).

### Common use cases

- **Competitor monitoring** — know when a competitor changes pricing, launches a banner, or redesigns.
- **Visual regression testing** — verify deploys didn't visually break production pages (use `baselineMode: fixed`).
- **Compliance & legal archiving** — scheduled, timestamped screenshot evidence of how a page looked.
- **Uptime/defacement watch** — a hacked or badly broken page is a massive visual change; alert on it.
- **Landing-page QA** — catch broken images, overflowing text, or CSS regressions across your marketing pages.

### Input

The only required field is `startUrls`. Sensible defaults handle the rest.

```json
{
    "startUrls": [{ "url": "https://example.com" }],
    "deltaMode": "changes-only",
    "webhookUrl": "https://hooks.example.com/notify",
    "hideSelectors": ["#cookie-banner", ".ad-slot"]
}
````

Key options (see the input tab for the full list):

| Option | Default | What it does |
| --- | --- | --- |
| `deltaMode` | `all` | `changes-only` pushes items only for changed/new/error pages + a heartbeat when nothing changed |
| `fullPage` | `true` | Full scrollable page vs. viewport only |
| `hideSelectors` | `[]` | CSS selectors to hide before capture (cookie banners, ads, clocks…) |
| `minChangePct` | `0.1` | Minimum % of pixels changed to count as a change |
| `minChangedPixels` | `200` | Absolute changed-pixel floor — catches small localized changes |
| `baselineMode` | `previous-run` | Or `fixed` to always compare against the original baseline |
| `forceBaseline` | `false` | Reset baselines this run (after an intentional site change) |
| `webhookUrl` | — | POST a JSON alert when any page changed |

### Output

One dataset item per monitored URL (plus a heartbeat item when nothing changed in changes-only mode):

```json
{
    "url": "https://example.com",
    "status": "changed",
    "pageTitle": "Example Domain",
    "changedPct": 2.41,
    "changedPixels": 55296,
    "totalPixels": 2293760,
    "dimensionsChanged": false,
    "regions": [{ "x": 0, "y": 224, "width": 896, "height": 96 }],
    "screenshotUrl": "https://api.apify.com/v2/key-value-stores/…/records/screenshot-….png",
    "previousScreenshotUrl": "https://api.apify.com/v2/key-value-stores/…/records/baseline-…",
    "diffUrl": "https://api.apify.com/v2/key-value-stores/…/records/diff-….png",
    "highlightUrl": "https://api.apify.com/v2/key-value-stores/…/records/highlight-….png",
    "checkedAt": "2026-07-20T12:00:00.000Z"
}
```

`status` is one of `baseline` (first run for a URL), `changed`, `unchanged`, `error`, or `heartbeat`.

### Webhook alert payload

Sent once per run, only if at least one page changed:

```json
{
    "source": "website-screenshot-monitor",
    "changedCount": 1,
    "changes": [{
        "url": "https://example.com",
        "changedPct": 2.41,
        "regions": 1,
        "screenshotUrl": "…", "diffUrl": "…", "highlightUrl": "…"
    }],
    "datasetUrl": "https://api.apify.com/v2/datasets/…/items",
    "timestamp": "2026-07-20T12:00:00.000Z"
}
```

### Scheduling

Pair this Actor with an [Apify Schedule](https://docs.apify.com/platform/schedules) (e.g. every hour) and `deltaMode: "changes-only"` + a webhook for a fully hands-off visual monitoring pipeline.

### Tips for clean diffs

- Hide dynamic elements (carousels, ads, cookie banners, live chats, clocks) with `hideSelectors` — this is the #1 fix for noisy diffs.
- Animations and transitions are frozen automatically; keep `disableAnimations` on.
- After an intentional site update, run once with `forceBaseline: true` to accept the new look.
- Very long pages are capped at `maxScreenshotHeight` (default 8,000 px) to keep memory predictable — raise it up to 16,000 px if you need more.

### Related Actors from signalgrove

- [AI Search Rank Tracker](https://apify.com/signalgrove/ai-search-rank-tracker) — track how ChatGPT & Gemini rank your brand in AI search results.
- [ATS Jobs API](https://apify.com/signalgrove/ats-jobs-api) — jobs from Greenhouse, Lever, Ashby, Workday & more, with delta mode and webhook alerts.

# Actor input Schema

## `startUrls` (type: `array`):

One or more web pages to screenshot and monitor for visual changes.

## `deltaMode` (type: `string`):

<b>All results</b>: every URL gets a dataset item each run. <b>Changes only</b>: items are pushed only when a page visually changed (or a baseline/error occurred) — ideal for scheduled monitoring with alerts. A heartbeat item is added when nothing changed, so the dataset is never empty.

## `webhookUrl` (type: `string`):

Optional. When any monitored page visually changed, a single JSON POST is sent here with the list of changed URLs, change percentages, and links to the screenshot/diff images. Works with Slack (via workflow webhook), Zapier, Make, n8n, or your own endpoint.

## `fullPage` (type: `boolean`):

Capture the entire scrollable page instead of just the viewport.

## `viewportWidth` (type: `integer`):

Browser viewport width in pixels.

## `viewportHeight` (type: `integer`):

Browser viewport height in pixels. Also the screenshot height when full-page capture is off.

## `hideSelectors` (type: `array`):

Elements to hide before the screenshot — use this to ignore noisy parts of the page such as cookie banners, ads, chat widgets, rotating carousels, or clocks. Example: <code>#cookie-banner</code>, <code>.ad-slot</code>.

## `minChangePct` (type: `number`):

A page counts as "changed" only when at least this percentage of pixels differ from the previous run. Raise it to ignore tiny changes; lower it to catch subtle ones.

## `minChangedPixels` (type: `integer`):

A page also counts as "changed" when at least this many pixels differ, even if the percentage is tiny — this catches small but real changes (like one price digit) on long pages. Set to 0 to disable and use only the percentage threshold.

## `delaySeconds` (type: `number`):

Additional wait after the page loads, for late-rendering content.

## `waitForSelector` (type: `string`):

Optional. Wait until this element appears before taking the screenshot.

## `waitUntil` (type: `string`):

Navigation is considered finished at this event. <b>load</b> is the safest default; <b>networkidle</b> waits for network silence (better for SPAs, but can be slower).

## `scrollToBottom` (type: `boolean`):

Scroll through the page before capturing so lazy-loaded images render. Only applies to full-page screenshots.

## `disableAnimations` (type: `boolean`):

Disable CSS animations, transitions, and the text cursor to avoid false-positive diffs.

## `maxScreenshotHeight` (type: `integer`):

Full-page screenshots are capped at this height to keep memory usage predictable on very long pages.

## `navigationTimeoutSecs` (type: `integer`):

Maximum time for a page to load before the attempt is retried.

## `pixelThreshold` (type: `number`):

Per-pixel color-difference threshold (0-1) used by the diff algorithm. Lower = more sensitive. The default 0.1 ignores invisible sub-pixel rendering noise.

## `baselineMode` (type: `string`):

<b>Previous run</b>: each run compares against the run before it (classic change monitoring). <b>Fixed</b>: always compare against the original baseline — useful for visual-regression testing against an approved state.

## `forceBaseline` (type: `boolean`):

Store fresh baselines for all URLs on this run (no comparison). Use after an intentional site change.

## `stateStoreName` (type: `string`):

Name of the key-value store holding baselines between runs. Change it to keep several independent monitors.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://example.com"
    },
    {
      "url": "https://www.wikipedia.org"
    }
  ],
  "deltaMode": "all",
  "fullPage": true,
  "viewportWidth": 1280,
  "viewportHeight": 720,
  "hideSelectors": [],
  "minChangePct": 0.1,
  "minChangedPixels": 200,
  "delaySeconds": 1,
  "waitUntil": "load",
  "scrollToBottom": true,
  "disableAnimations": true,
  "maxScreenshotHeight": 8000,
  "navigationTimeoutSecs": 45,
  "pixelThreshold": 0.1,
  "baselineMode": "previous-run",
  "forceBaseline": false,
  "stateStoreName": "visual-diff-monitor-state"
}
```

# Actor output Schema

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

No description

## `screenshots` (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 = {
    "startUrls": [
        {
            "url": "https://example.com"
        },
        {
            "url": "https://www.wikipedia.org"
        }
    ],
    "deltaMode": "all",
    "hideSelectors": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("signalgrove/website-screenshot-monitor").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 = {
    "startUrls": [
        { "url": "https://example.com" },
        { "url": "https://www.wikipedia.org" },
    ],
    "deltaMode": "all",
    "hideSelectors": [],
}

# Run the Actor and wait for it to finish
run = client.actor("signalgrove/website-screenshot-monitor").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "startUrls": [
    {
      "url": "https://example.com"
    },
    {
      "url": "https://www.wikipedia.org"
    }
  ],
  "deltaMode": "all",
  "hideSelectors": []
}' |
apify call signalgrove/website-screenshot-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=signalgrove/website-screenshot-monitor",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Website Screenshot Monitor - Visual Diff & Change Alerts",
        "description": "Capture full-page screenshots on a schedule, compare them pixel-by-pixel with the previous run, highlight what changed, and get webhook alerts. No API keys needed.",
        "version": "0.0",
        "x-build-id": "AahyOmDb0VsKbCgIF"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/signalgrove~website-screenshot-monitor/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-signalgrove-website-screenshot-monitor",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/signalgrove~website-screenshot-monitor/runs": {
            "post": {
                "operationId": "runs-sync-signalgrove-website-screenshot-monitor",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/signalgrove~website-screenshot-monitor/run-sync": {
            "post": {
                "operationId": "run-sync-signalgrove-website-screenshot-monitor",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "startUrls"
                ],
                "properties": {
                    "startUrls": {
                        "title": "URLs to monitor",
                        "type": "array",
                        "description": "One or more web pages to screenshot and monitor for visual changes.",
                        "items": {
                            "type": "object",
                            "required": [
                                "url"
                            ],
                            "properties": {
                                "url": {
                                    "type": "string",
                                    "title": "URL of a web page",
                                    "format": "uri"
                                }
                            }
                        }
                    },
                    "deltaMode": {
                        "title": "Reporting mode",
                        "enum": [
                            "all",
                            "changes-only"
                        ],
                        "type": "string",
                        "description": "<b>All results</b>: every URL gets a dataset item each run. <b>Changes only</b>: items are pushed only when a page visually changed (or a baseline/error occurred) — ideal for scheduled monitoring with alerts. A heartbeat item is added when nothing changed, so the dataset is never empty.",
                        "default": "all"
                    },
                    "webhookUrl": {
                        "title": "Webhook alert URL",
                        "type": "string",
                        "description": "Optional. When any monitored page visually changed, a single JSON POST is sent here with the list of changed URLs, change percentages, and links to the screenshot/diff images. Works with Slack (via workflow webhook), Zapier, Make, n8n, or your own endpoint."
                    },
                    "fullPage": {
                        "title": "Full-page screenshot",
                        "type": "boolean",
                        "description": "Capture the entire scrollable page instead of just the viewport.",
                        "default": true
                    },
                    "viewportWidth": {
                        "title": "Viewport width (px)",
                        "minimum": 320,
                        "maximum": 3840,
                        "type": "integer",
                        "description": "Browser viewport width in pixels.",
                        "default": 1280
                    },
                    "viewportHeight": {
                        "title": "Viewport height (px)",
                        "minimum": 320,
                        "maximum": 2160,
                        "type": "integer",
                        "description": "Browser viewport height in pixels. Also the screenshot height when full-page capture is off.",
                        "default": 720
                    },
                    "hideSelectors": {
                        "title": "Hide elements (CSS selectors)",
                        "type": "array",
                        "description": "Elements to hide before the screenshot — use this to ignore noisy parts of the page such as cookie banners, ads, chat widgets, rotating carousels, or clocks. Example: <code>#cookie-banner</code>, <code>.ad-slot</code>.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "minChangePct": {
                        "title": "Minimum change to report (%)",
                        "minimum": 0,
                        "maximum": 100,
                        "type": "number",
                        "description": "A page counts as \"changed\" only when at least this percentage of pixels differ from the previous run. Raise it to ignore tiny changes; lower it to catch subtle ones.",
                        "default": 0.1
                    },
                    "minChangedPixels": {
                        "title": "Minimum changed pixels to report",
                        "minimum": 0,
                        "maximum": 10000000,
                        "type": "integer",
                        "description": "A page also counts as \"changed\" when at least this many pixels differ, even if the percentage is tiny — this catches small but real changes (like one price digit) on long pages. Set to 0 to disable and use only the percentage threshold.",
                        "default": 200
                    },
                    "delaySeconds": {
                        "title": "Extra wait before screenshot (seconds)",
                        "minimum": 0,
                        "maximum": 30,
                        "type": "number",
                        "description": "Additional wait after the page loads, for late-rendering content.",
                        "default": 1
                    },
                    "waitForSelector": {
                        "title": "Wait for CSS selector",
                        "type": "string",
                        "description": "Optional. Wait until this element appears before taking the screenshot."
                    },
                    "waitUntil": {
                        "title": "Page load event",
                        "enum": [
                            "load",
                            "domcontentloaded",
                            "networkidle"
                        ],
                        "type": "string",
                        "description": "Navigation is considered finished at this event. <b>load</b> is the safest default; <b>networkidle</b> waits for network silence (better for SPAs, but can be slower).",
                        "default": "load"
                    },
                    "scrollToBottom": {
                        "title": "Scroll to trigger lazy-loaded content",
                        "type": "boolean",
                        "description": "Scroll through the page before capturing so lazy-loaded images render. Only applies to full-page screenshots.",
                        "default": true
                    },
                    "disableAnimations": {
                        "title": "Freeze CSS animations",
                        "type": "boolean",
                        "description": "Disable CSS animations, transitions, and the text cursor to avoid false-positive diffs.",
                        "default": true
                    },
                    "maxScreenshotHeight": {
                        "title": "Max screenshot height (px)",
                        "minimum": 600,
                        "maximum": 16000,
                        "type": "integer",
                        "description": "Full-page screenshots are capped at this height to keep memory usage predictable on very long pages.",
                        "default": 8000
                    },
                    "navigationTimeoutSecs": {
                        "title": "Navigation timeout (seconds)",
                        "minimum": 5,
                        "maximum": 180,
                        "type": "integer",
                        "description": "Maximum time for a page to load before the attempt is retried.",
                        "default": 45
                    },
                    "pixelThreshold": {
                        "title": "Pixel matching sensitivity",
                        "minimum": 0,
                        "maximum": 1,
                        "type": "number",
                        "description": "Per-pixel color-difference threshold (0-1) used by the diff algorithm. Lower = more sensitive. The default 0.1 ignores invisible sub-pixel rendering noise.",
                        "default": 0.1
                    },
                    "baselineMode": {
                        "title": "Baseline mode",
                        "enum": [
                            "previous-run",
                            "fixed"
                        ],
                        "type": "string",
                        "description": "<b>Previous run</b>: each run compares against the run before it (classic change monitoring). <b>Fixed</b>: always compare against the original baseline — useful for visual-regression testing against an approved state.",
                        "default": "previous-run"
                    },
                    "forceBaseline": {
                        "title": "Reset baselines this run",
                        "type": "boolean",
                        "description": "Store fresh baselines for all URLs on this run (no comparison). Use after an intentional site change.",
                        "default": false
                    },
                    "stateStoreName": {
                        "title": "State store name",
                        "type": "string",
                        "description": "Name of the key-value store holding baselines between runs. Change it to keep several independent monitors.",
                        "default": "visual-diff-monitor-state"
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
