Website Screenshot & Visual Diff avatar

Website Screenshot & Visual Diff

Pricing

Pay per event

Go to Apify Store
Website Screenshot & Visual Diff

Website Screenshot & Visual Diff

Capture public website screenshots and compare them with page or image baselines. Get pixel-level diff images and change percentages for visual regression testing, monitoring, CI, and AI agents.

Pricing

Pay per event

Rating

0.0

(0)

Developer

Lintlab

Lintlab

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 hours ago

Last modified

Share

Capture public web pages and compare them with live-page or PNG/JPEG baselines. Get stored screenshots, pixel-level diff images, and a clear change percentage for visual regression QA.

Highlights

  • Full-page, viewport, or CSS-selector captures in PNG or JPEG
  • Desktop, laptop, tablet, and mobile device presets
  • Optional page or image baselines with configurable diff thresholds
  • Structured dataset rows plus direct screenshot and diff-image URLs
  • $0.004 per successful capture; $0.002 per computed diff

Quick start

{"urls":["https://example.com"],"mode":"fullPage","device":"desktop"}

Use with AI agents / MCP

Call lintlab/screenshot-diff through the Apify API or Apify MCP server. Read the default dataset, then pass screenshotUrl or diff.diffImageUrl to the next vision-capable agent step.

Overview

screenshot-diff is a lintlab Apify Actor that captures screenshots of public web pages. It can compare each capture with another public page or a public PNG/JPEG baseline and store a pixel-level diff image.

The Actor uses Playwright Chromium, honors robots.txt for the lintlab-screenshot user agent (an unreachable or 5xx robots.txt counts as "disallow", per RFC 9309), re-checks every redirect hop, and rejects non-HTTP URLs and private, loopback, or link-local network destinations.

Input

{
"urls": [
"https://example.com",
"https://example.org"
],
"mode": "fullPage",
"device": "desktop",
"waitUntil": "networkidle",
"delayMs": 500,
"hideSelectors": [".cookie-banner"],
"format": "png",
"baselineImageUrls": [
"https://assets.example.net/baselines/example.png",
"https://assets.example.net/baselines/example-org.png"
],
"threshold": 0.1,
"changedThresholdPercent": 0.5,
"timeoutSecs": 45
}

urls is required and accepts at most 200 entries. Baselines are optional. Use either baselineUrls (pages captured with the same settings) or baselineImageUrls (public PNG/JPEG files), with one baseline per input URL in the same order.

Capture modes:

  • fullPage captures the full document.
  • viewport captures the configured viewport.
  • selector captures the first element matching selector.

Device presets are desktop (1366×768), laptop (1440×900), tablet (768×1024), and mobile (390×844 at 3× device scale with a mobile user agent). networkidle is the default readiness setting and falls back to load if the page does not become idle before the timeout.

Output

The default dataset contains one item for each requested URL. Screenshots and diff images are records in the run's default key-value store.

{
"url": "https://example.com",
"finalUrl": "https://example.com/",
"status": 200,
"device": "desktop",
"mode": "fullPage",
"width": 1366,
"height": 768,
"bytes": 18452,
"screenshotUrl": "https://api.apify.com/v2/key-value-stores/STORE_ID/records/screenshot-001-100680ad546c.png",
"capturedAt": "2026-09-25T12:34:56.000Z",
"diff": {
"baseline": "https://assets.example.net/baselines/example.png",
"diffPixels": 218,
"diffPercent": 0.020763,
"diffImageUrl": "https://api.apify.com/v2/key-value-stores/STORE_ID/records/diff-001-100680ad546c.png",
"changed": false
}
}

Failed or policy-blocked URLs still receive a dataset item with an error field and null capture fields. A path blocked by the site's robots policy reports "error": "disallowed by robots.txt".

Pricing

EventPrice
Screenshot captured and stored$0.004
Visual diff computed and stored$0.002
Start fee from us$0.00

A failed capture is not charged. A diff is charged only after it is computed and its image is stored. Apify platform usage or storage charges may still apply under the platform's terms. The Actor respects a run's maximum charge limit and stops scheduling work when that limit is reached.

Use cases

  • Visual regression checks in CI
  • Monitoring your own public pages for visual changes
  • Giving AI agents eyes on public web interfaces

Limits and behavior

  • Public HTTP(S) pages only. DNS answers resolving to private, loopback, link-local, reserved, or other non-public IP ranges are blocked.
  • robots.txt is fetched once per origin per run and honored for target pages, baseline pages, baseline images, and navigation redirects.
  • No login, cookies input, CAPTCHA handling, proxy, or stealth/anti-detection behavior is provided.
  • The Actor does not bypass access controls. Use it only on pages you are allowed to access and capture.
  • PNG and JPEG baselines are supported. Differently sized images are aligned at the top-left and padded with white to the larger canvas before comparison.
  • Dynamic pages can vary between runs. Use waitForSelector, delayMs, and hideSelectors to reduce expected noise.
  • Public key-value-store record URLs use the store ID. Access remains subject to the run storage's Apify access and retention settings.

Local development

Node.js 20 or later is required.

npm ci
npm test
npx playwright install chromium
npm run test:e2e

The end-to-end script writes only to ./storage, captures https://example.com, and prints elapsed time plus a 2 GB memory × seconds compute estimate.

Built by lintlab — small, reliable data tools. AI-assisted (Claude/Codex), reviewed before release. Support: lintlab.dev@gmail.com · https://github.com/lintlab/lintlab/issues