Why Automate Website Screenshots?
Manual screenshots don't scale. Whether you're building a link preview service, monitoring visual regressions, generating social media thumbnails, or archiving web content, you need a programmatic approach.
Automated screenshot capture is essential for modern web development workflows. Common use cases include generating Open Graph preview images for social sharing, building visual regression testing pipelines, creating website monitoring dashboards, producing thumbnail galleries for content aggregators, and archiving web pages for compliance or research purposes. Traditional approaches involve installing headless browsers locally, managing Chromium dependencies, and writing complex Playwright or Puppeteer scripts. A free screenshot API eliminates all of that complexity by handling the browser infrastructure for you. In this tutorial, you will learn how to capture website screenshots programmatically using the PageShot API with step-by-step examples in three popular languages. Every example in this guide uses real, working code that you can copy and run immediately against the live API at pageshot.site.
Capture Screenshots in 5 Steps
From zero to pixel-perfect captures in minutes. No installation, no API key, no configuration.
Choose Your Screenshot Method
PageShot provides two primary endpoints for capturing website screenshots. The GET endpoint is ideal for quick captures and browser-based usage — just pass the target URL as a query parameter. The POST endpoint gives you full control over viewport dimensions, output format, wait strategies, and advanced options like CSS injection and element selectors. There is also an HTML-to-image endpoint that renders raw HTML markup directly into a screenshot without needing a live URL. Choose the method that fits your workflow: GET for simplicity, POST for power, or HTML rendering for dynamic content generation.
# Simple GET request — pass URL as query param GET /v1/screenshot?url=https://example.com # Full-featured POST request — JSON body with options POST /v1/screenshot Content-Type: application/json { "url": "https://example.com", "options": { ... } } # Render raw HTML to image — no URL needed POST /v1/html Content-Type: application/json { "html": "<h1>Hello World</h1>" }
Basic Screenshot with cURL
The fastest way to test the API is with a simple cURL command. The GET endpoint accepts a url query parameter and returns the screenshot image directly in the response body. By default, PageShot captures a 1280×720 viewport in PNG format. The response includes headers like Content-Type and X-PageShot-Title with the page title. You can redirect the output to a file to save the screenshot locally. This approach works on any system with cURL installed — Linux, macOS, Windows, or inside CI/CD pipelines.
# Capture a screenshot and save as PNG curl -o screenshot.png \ "https://pageshot.site/v1/screenshot?url=https://example.com" # Capture in WebP format with custom viewport curl -o screenshot.webp \ "https://pageshot.site/v1/screenshot?url=https://example.com&format=webp&width=1920&height=1080" # Full-page screenshot (captures entire scrollable area) curl -o fullpage.png \ "https://pageshot.site/v1/screenshot?url=https://example.com&fullPage=true"
curl -X POST "https://pageshot.site/v1/screenshot" \ -H "Content-Type: application/json" \ -d '{ "url": "https://github.com", "options": { "format": "jpeg", "quality": 85, "width": 1440, "height": 900, "fullPage": false, "delay": 2000 } }' \ -o github-screenshot.jpeg
JavaScript Integration
For Node.js and browser-based applications, the fetch API provides a clean integration path. The example below demonstrates both a simple GET capture and a full-featured POST request with viewport configuration, output format selection, and delay timing for JavaScript-heavy pages. The response arrives as a binary buffer that you can write to disk, upload to cloud storage, or serve directly to users. In a browser context, you can convert the response to a blob URL for immediate display in an <img> tag.
import { writeFileSync } from 'fs'; // Simple GET screenshot const simple = await fetch( 'https://pageshot.site/v1/screenshot?url=https://example.com' ); writeFileSync('example.png', Buffer.from(await simple.arrayBuffer())); // Advanced POST with full options const response = await fetch('https://pageshot.site/v1/screenshot', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ url: 'https://github.com', options: { format: 'webp', width: 1440, height: 900, fullPage: false, delay: 1500, darkMode: true } }) }); const buffer = Buffer.from(await response.arrayBuffer()); writeFileSync('github-dark.webp', buffer); console.log('Page title:', response.headers.get('x-pageshot-title'));
Python Integration
Python developers can use the requests library for a straightforward integration. The pattern is identical: send an HTTP request to the PageShot API, receive the screenshot binary in the response, and write it to a file. For asynchronous workflows, httpx or aiohttp work just as well. The API returns standard HTTP status codes — 200 for success, 400 for invalid parameters, 422 for unreachable URLs, and 429 if you exceed the rate limit of 30 requests per minute. Each response includes rate-limit headers so you can implement backoff logic in production systems.
import requests # Simple GET screenshot response = requests.get( "https://pageshot.site/v1/screenshot", params={"url": "https://example.com", "format": "png"} ) with open("screenshot.png", "wb") as f: f.write(response.content) # Advanced POST with viewport and format options response = requests.post( "https://pageshot.site/v1/screenshot", json={ "url": "https://github.com", "options": { "format": "jpeg", "quality": 90, "width": 1920, "height": 1080, "fullPage": True, "delay": 2000 } } ) with open("github-full.jpeg", "wb") as f: f.write(response.content) print(f"Status: {response.status_code}") print(f"Page title: {response.headers.get('x-pageshot-title')}")
Advanced Options — Viewport, Format, Full Page, Device Emulation
PageShot's API goes far beyond basic screenshots. You can control the exact viewport dimensions to emulate any device resolution, choose between PNG, JPEG, and WebP output formats, capture the full scrollable page or just the visible viewport, inject custom CSS to modify the page before capture, wait for specific elements to appear using CSS selectors, emulate dark mode preferences, block advertisements, and even capture a specific DOM element instead of the entire page. These options make PageShot suitable for everything from simple thumbnail generation to complex visual regression testing workflows. For a complete list of available parameters, see the API documentation.
{
"url": "https://example.com",
"options": {
// Output format: "png" (default), "jpeg", or "webp"
"format": "webp",
// JPEG/WebP quality: 1-100 (default: 80)
"quality": 90,
// Viewport dimensions in pixels
"width": 1440,
"height": 900,
// Capture the full scrollable page
"fullPage": true,
// Wait time in ms before capture (for JS-heavy pages)
"delay": 3000,
// Emulate dark mode (prefers-color-scheme: dark)
"darkMode": true,
// Block ads and trackers before capture
"blockAds": true,
// Inject custom CSS before capture
"css": "body { font-family: Arial; } .banner { display: none; }",
// Capture a specific element (CSS selector)
"selector": "#main-content",
// Device emulation presets
"device": "iPhone 14 Pro",
// Disable JavaScript execution
"disableJavascript": true,
// Set geolocation for location-aware pages
"geolocation": { "latitude": 52.52, "longitude": 13.405 }
}
}Common Use Cases
Real-world scenarios where automated screenshot capture saves time and eliminates manual work.
Link Preview Thumbnails
Generate thumbnail images for shared links in chat applications, social media platforms, and content management systems. Capture a screenshot at card dimensions and serve it as the preview image for any URL.
Visual Regression Testing
Capture screenshots of your web application across different viewports and compare them against baseline images. Detect unintended visual changes before they reach production by integrating into your CI/CD pipeline.
Website Monitoring Dashboards
Build monitoring systems that periodically capture screenshots of critical pages. Track visual changes over time, detect downtime or defacement, and maintain a visual audit trail of your web properties.
Multi-Device Previews
Generate screenshot previews across multiple device viewports — desktop, tablet, and mobile — from a single API call sequence. Perfect for responsive design validation and client presentations.
Tutorial FAQ
Answers to common questions about capturing website screenshots programmatically.
Do I need an API key to capture screenshots?
No. PageShot is completely free and requires no API key, no account registration, and no credit card. Send requests directly to pageshot.site/v1/screenshot and start capturing immediately. The API is rate-limited to 30 requests per minute per IP address to ensure fair usage for everyone. Rate limit headers (X-RateLimit-Remaining) are included in every response.
What output formats does the screenshot API support?
PageShot supports three image formats: PNG (default, lossless, best for text-heavy pages), JPEG (smaller file size, configurable quality 1-100, ideal for photographic content), and WebP (modern format with superior compression, supported by all major browsers). Set the format using the format parameter. For JPEG and WebP, the quality parameter controls the compression level.
How do I capture a full-page screenshot including content below the fold?
Set the fullPage parameter to true. PageShot will automatically scroll the page and stitch together a complete screenshot of the entire document, including all content below the visible viewport. This works with both the GET query parameter (?fullPage=true) and the POST JSON body ("fullPage": true). The resulting image height will match the full document height. Be aware that very long pages may produce large images.
Can I screenshot pages that require JavaScript to render?
Yes. PageShot uses a real Chromium browser instance via Playwright, which means full JavaScript execution is enabled by default. Single-page applications (React, Vue, Angular), dynamically loaded content, and JavaScript-rendered widgets all capture correctly. Use the delay parameter (in milliseconds) to wait for asynchronous content to finish loading before the screenshot is taken. For example, "delay": 3000 waits 3 seconds after the initial page load.
How do I capture screenshots of specific page elements?
Use the selector option with a CSS selector that targets the element you want to capture. For example, "selector": "#hero-section" captures only the element with that ID, cropped precisely to its bounding box. This is useful for capturing individual components, charts, tables, or any specific section of a page without including the surrounding content. The selector follows standard CSS selector syntax.
What is the difference between PageShot and running my own headless browser?
Running your own headless Chromium instance requires installing browser binaries (200+ MB), managing system dependencies (fonts, graphics libraries), handling browser crashes and memory leaks, and maintaining concurrency controls. PageShot handles all of this infrastructure for you behind a simple REST API. You get the same Chromium rendering quality without any of the operational overhead. For projects that need self-hosting, PageShot is open source and ships with a production-ready Dockerfile.
Can I convert the screenshot to a PDF instead?
PageShot specializes in image captures (PNG, JPEG, WebP). If you need to convert a webpage to PDF, use PDFSpark — our complementary API that converts HTML and URLs to pixel-perfect PDF documents with full CSS3, JavaScript, and web font support. Both APIs are free, require no API key, and are powered by the same Chromium engine.