Website Screenshot API — URL to PNG/JPEG/PDF for AI Agents avatar

Website Screenshot API — URL to PNG/JPEG/PDF for AI Agents

Pricing

from $2.00 / 1,000 screenshots

Go to Apify Store
Website Screenshot API — URL to PNG/JPEG/PDF for AI Agents

Website Screenshot API — URL to PNG/JPEG/PDF for AI Agents

Screenshot any public URL to PNG, JPEG or PDF with Chromium. Predictable JSON output with a direct image URL and explicit errors, built for AI agents, API callers and Apify MCP. $2 per 1,000 screenshots; failed URLs are free.

Pricing

from $2.00 / 1,000 screenshots

Rating

0.0

(0)

Developer

AgentReady Tools

AgentReady Tools

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

21 hours ago

Last modified

Features

Limited permissions

Share

Capture public web pages with Playwright Chromium. Each processed URL produces one JSON dataset item with a direct screenshotUrl, or a short error. Files live in the run's default key-value store. Use screenshots for visual inspection, responsive layout checks, document previews and agent workflows.

Quick start

Run with {} to capture https://example.com, or pass:

{"urls":["https://example.com"],"device":"mobile","format":"png"}

All options have defaults. An empty URL array also uses the example page. URL safety failures produce free error items; malformed input options fail the run. Extra unique URLs above maxUrls are ignored with a status message. Processing is sequential.

For local development (Node.js 22 or later):

npm ci
npx playwright install chromium
npm run build
npm test
npm start
# Optional real Chromium fixture checks:
RUN_BROWSER_TESTS=1 npm test

Local SDK storage is under storage/.

For AI agents

Connect your MCP client to the Apify MCP server and enable Actor samgov-tools/url-screenshot. To load just this Actor, use https://mcp.apify.com?tools=samgov-tools/url-screenshot. Sign in through the client’s OAuth flow or configure an Apify API token. Discover the exposed tool name through your client. See the MCP documentation for setup details.

Example prompt:

Use the Apify samgov-tools/url-screenshot Actor to capture https://example.com on mobile. Return the screenshotUrl and title. If error is non-null, report that error instead.

Pass urls; leave the other fields at defaults unless needed. Read each item's error before using screenshotUrl. Signed screenshotUrl links work without authentication. The HTTP status is independent of capture success: a 403/404 page can still be captured honestly. A successful screenshot does not mean the site allowed access to its intended content.

REST API (synchronous dataset endpoint):

curl --fail-with-body -X POST \
'https://api.apify.com/v2/acts/samgov-tools~url-screenshot/run-sync-get-dataset-items?timeout=300' \
-H "Authorization: Bearer $APIFY_TOKEN" \
-H 'Content-Type: application/json' \
-d '{"urls":["https://example.com"],"format":"png"}'

Large batches may exceed synchronous API limits; start an asynchronous run and retrieve its dataset when finished.

JavaScript client:

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('samgov-tools/url-screenshot').call({
urls: ['https://example.com'], fullPage: true,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const item of items) console.log(item.error ?? item.screenshotUrl);

Paying agents without an Apify account (x402 / MPP)

An agent without an Apify account can buy a prepaid Apify API token from Apify AGI (agi.apify.com) with x402 (USDC on Base or Solana), MPP (Tempo or Solana) or Skyfire, then use it as the Apify API token in this README's REST example (Actor samgov-tools~url-screenshot) or as the bearer token for the Apify MCP server. This Actor uses limited permissions, which prepaid tokens require. Apify's current terms: minimum $1, the balance is a hard spending cap, the token expires 14 days after purchase, unused balance is non-refundable, and the feature is experimental. Check agi.apify.com for current terms before paying.

The token pays this Actor's normal pay-per-event prices: apify-actor-start: $0.0005 per run, screenshot: $0.002 per stored capture, full-page-or-pdf: +$0.001 per full-page capture or PDF. See Let your AI agent pay for Actor runs, x402 and MPP.

Input

FieldDefaultPurpose / example
urls["https://example.com"]Public URLs; trimmed, deduplicated in order. API also accepts [{"url":"https://example.com"}]. Missing/empty array uses default.
maxUrls10Process at most 1–100 unique URLs; e.g. 3.
fullPagefalseCapture a long page; e.g. true. Raster height clips at 16,384 CSS px.
devicedesktopdesktop: 1280×800 DPR 1; mobile: 390×844 DPR 2; tablet: 820×1180 DPR 2. Mobile uses the built-in iPhone 13 descriptor and ordinary mobile UA; mobile/tablet use touch.
widthDevice widthOverride viewport, 320–3840 CSS px; e.g. 1440.
heightDevice heightOverride viewport, 240–2160 CSS px; e.g. 900.
formatpngpng, jpeg, or pdf; e.g. pdf for print output.
jpegQuality801–100, JPEG only; e.g. 60 for smaller files.
waitUntilloadload, domcontentloaded, or networkidle; e.g. domcontentloaded for speed. Busy pages may never reach networkidle.
delayMs0Wait after load, 0–10000 ms; e.g. 1000 for client-rendered pages.
blockCookieBannerstrueCSS-hide common banners; e.g. false to inspect consent UI. No clicking or consent submission.
timeoutSecs30Navigation timeout, 5–60 seconds; e.g. 45 for a slow page.

The console schema makes urls optional with both a default and prefill. Empty input captures the example page. Schema string-list editing is intended for strings; object entries are a runtime API convenience.

Output

{
"url": "https://example.com",
"finalUrl": "https://example.com/",
"status": 200,
"title": "Example Domain",
"screenshotUrl": "https://api.apify.com/v2/key-value-stores/STORE_ID/records/screenshot-1-example-com",
"format": "png",
"width": 1280,
"height": 800,
"fullPage": false,
"bytes": 15432,
"takenAt": "2026-11-14T12:00:00.000Z",
"error": null
}

Field order is stable. width and height report the actual PNG/JPEG image dimensions in physical pixels, read from the PNG IHDR or JPEG SOF header. Raster pixels scale with DPR; full-page height includes the current scrollable content up to the 16,384 CSS pixel cap. Full-page capture uses Playwright fullPage: true, with a clip at the cap for taller pages. For successful PDF captures these fields report the configured viewport in CSS pixels. Failed captures return null for both dimensions. PDF uses Chromium's print layout, background printing and normal pagination; screen viewport dimensions do not specify PDF paper size. PDF layout is clipped at 16,384 CSS px and printing is limited to 50 pages. fullPage is always true for PDF.

On failure screenshotUrl, bytes, width and height are null; available navigation metadata remains populated. takenAt is an ISO timestamp of successful storage completion, or the failed attempt's start. Files use keys screenshot-<1-based-index>-<sanitized-host> and their actual MIME type. URLs come from the SDK's getPublicUrl, including signed URLs when needed. Signed screenshotUrl links work without authentication. Treat a signed URL as a bearer link and observe storage retention settings. A storage write that succeeds before a later URL/dataset operation fails can leave an uncharged file in the store.

Safety and limits

  • Only public HTTP/HTTPS pages and ports 80/443. No URL credentials, local hostnames, login/cookies input, user proxies, CAPTCHA solving or stealth techniques. Each URL uses a fresh context without saved cookies.
  • Hostnames resolve with dns.lookup({ all: true }); any private/reserved answer rejects the host. Each proxy connection/request resolves once and connects to a verified literal IP; answers are not reused for later connections. Guards reject loopback, link-local/metadata, private, CGNAT, documentation, multicast and reserved ranges, including IPv4-mapped IPv6 and private addresses embedded in NAT64/6to4. WHATWG URL parsing normalizes decimal, octal and hex IPv4 literals before checking.
  • A context route performs cheap scheme/host checks on main requests, subresources and iframes. Chromium uses an in-process proxy bound to a random port on 127.0.0.1 for HTTP and HTTPS/CONNECT, including loopback destinations. Every redirect hop and worker connection passes through the proxy. WebSockets are closed; service workers and downloads are blocked. CSS banner hiding does not bypass paywalls or site access controls.
  • The proxy pins upstream sockets to the validated IP, preventing DNS rebinding between validation and connection. Only destination ports 80 and 443 are allowed. DNS/policy checks, upstream connections and idle sockets have a 15-second timeout. QUIC and non-proxied WebRTC UDP are disabled. Proxy sockets and the server close with the browser. Network/egress isolation remains useful defense in depth.
  • One browser, concurrency 1. The browser deadline per URL is timeoutSecs + delayMs/1000 + 30 seconds; timeout closes its context. Storage operations are awaited separately. Navigation has its own timeoutSecs limit. A timed-out URL produces an error item and processing continues.
  • Up to 100 URLs, raster height 16,384 CSS pixels, PDF at most 50 pages, maximum stored file 20 MiB. Oversized files produce errors and are not stored. Rendering may allocate memory before the byte limit can be checked; pathological pages can still exhaust the container. Default memory 1024 MB; configurable 512–4096 MB.
  • A site's 4xx/5xx page is captured with its real HTTP status; unavailable pages produce safe errors without stack traces. File storage failures produce error items; dataset write failures fail the run because results cannot be delivered reliably.

Pricing

The Actor’s Pricing tab is authoritative. Current prices:

EventCharged whenPrice
apify-actor-startAutomatically by Apify once per run, up to 1 GB memory$0.0005 per run
screenshotOne successfully stored capture pushed to the dataset$0.002 ($2 per 1,000)
full-page-or-pdfExtra for each successful full-page capture or PDF+$0.001 per capture

100 viewport screenshots in one run cost $0.2005; 100 full-page screenshots cost $0.3005. The synthetic apify-actor-start event is charged automatically by Apify; the Actor does not charge it in code or add it per URL.

Failed URLs are free; the run-start fee still applies. A PDF with fullPage: true gets only one extra event. Before each URL both required event budgets and their combined cost (including any platform default-dataset-item fee) are checked; if insufficient, processing stops successfully and reports stored counts. ACTOR_MAX_PAID_DATASET_ITEMS additionally clamps URLs attempted (including failures); zero processes none. Dataset push charge-limit results are respected. Budget checks use platform pricing. Budget checks and the two event charges are separate SDK operations, so a concurrently changing platform budget can prevent an extra charge after capture; the Actor stops when this occurs.

FAQ

Why is my screenshot blank or blocked? Some pages require authentication, reject automated browsers or render slowly. Inspect status and error; try a modest delay or another wait condition. There is no bypass feature.

Does banner hiding always work? No. It only adds CSS for common selectors. It does not click, submit consent, or inspect closed shadow roots.

Can I capture localhost, metadata endpoints or private apps? No. Public pages only. Nonstandard ports are also rejected.

Does fullPage scroll and load every lazy image? No. It captures the current layout; it does not run an incremental scrolling crawl.

Can I use a screenshot URL later? Yes while the store and its access policy remain available. Signed links and run retention can limit lifetime.

Build notes

Both Docker stages use apify/actor-node-playwright-chrome:22-1.65.1; npm Playwright is exactly 1.65.1. The official base Dockerfile uses non-root myuser, /home/myuser and /pw-browsers; project copies use ownership accordingly. Browser downloading is disabled during Docker installs and the inherited browser path is preserved.

python3 scripts/make-icon.py regenerates the 1024×1024 browser capture icon (Pillow required). python3 scripts/make-schemas.py regenerates the committed schemas.