How to Capture Webpage Screenshots with Chrome DevTools Protocol
Use CDP’s Page.captureScreenshot to capture a viewport, region, or full page. Learn how to send the command, save its image data, and troubleshoot common issues.
To capture a webpage with Chrome DevTools Protocol (CDP), send Page.captureScreenshot to the page target you want to capture, then decode the returned base64 image data and save it as a binary file. Use the default viewport capture for the visible area, clip for a region, or captureBeyondViewport for content outside the viewport when the Chrome protocol version supports it.
CDP defines the browser command, but your client or transport must connect to the correct page target, send the JSON command, receive the response, decode result.data, and write the bytes. The protocol schema documents PNG, JPEG, and WebP output; PNG is the default. Chromium DevTools Protocol: Page.captureScreenshot.
1. Send Page.captureScreenshot to the right target
A minimal CDP command is:
{"id":1,"method":"Page.captureScreenshot","params":{"format":"png"}}
The precise envelope depends on your CDP transport. Send this command over the debugging connection attached to the page target you intend to capture. A browser can have several tabs and targets, so attaching to the browser or a different tab does not guarantee that the desired page receives the command.
In a JSON-based transport, a successful response includes image data in result.data. That value is base64 encoded. Decode it to bytes before writing the file; saving the base64 text itself does not create a valid PNG, JPEG, or WebP image.
2. Choose viewport, clip, or full-page capture
| Goal | CDP approach | What to check |
|---|---|---|
| Visible viewport | Call Page.captureScreenshot without a clip and leave beyond-viewport capture off. |
The result follows the page’s current viewport. |
| Specific region | Pass a clip rectangle with its geometry and scale. |
Use the clip shape and units defined by the protocol version in the Chrome build you run. |
| Content beyond the viewport | Set captureBeyondViewport where supported. |
Check the protocol schema for the Chrome version and determine actual content dimensions. Page content size can differ from the defined viewport. |
A viewport screenshot is not automatically a full-page screenshot. The protocol schema lists clip, captureBeyondViewport, and other options, but some fields are marked experimental in the Chromium 140 schema. Treat support as version-dependent and consult the protocol metadata for the Chrome build you deploy. Page.captureScreenshot schema.
3. Select an image format
| Option | Use it when |
|---|---|
format: "png" |
You want lossless output. PNG is the default. |
format: "jpeg" |
A smaller lossy image is acceptable. The quality parameter is an integer from 0 to 100 and applies to JPEG. |
format: "webp" |
You want WebP output and your downstream tools accept it. |
Use a matching file extension when saving the decoded bytes. The protocol response contains image data, not a filename, so the client is responsible for choosing the extension and handling the bytes correctly.
4. Capture interactively with Protocol Monitor
For one-off exploration, Chrome DevTools Protocol Monitor can send and inspect CDP commands without writing a client. Enable the Protocol Monitor experiment if needed, open the panel from the Command menu or More tools, select the page target, and submit the command. The command editor accepts this form for a parameterized call:
{"cmd":"Page.captureScreenshot","args":{"format":"jpeg"}}
Protocol Monitor can also provide a structured command editor based on protocol definitions. Confirm that the selected target is the page you mean to capture. Chrome DevTools Protocol Monitor guide.
5. Use DevTools for manual screenshots
If you only need a screenshot by hand, Device Mode offers built-in capture actions. “Capture screenshot” captures the visible viewport; “Capture a full size screenshot” includes page content outside the visible area. DevTools also documents node, oversized node, device-frame, and area capture workflows. Chrome DevTools Device Mode and Chrome DevTools screenshot guide.
6. Use a command-line or library workflow when appropriate
Headless Chrome CLI
Chrome’s documented --screenshot option is a direct command-line alternative. It saves screenshot.png in the current working directory. A window size can be specified, and --timeout sets a maximum wait before capture, including when content is still loading:
chrome --headless --screenshot --window-size=412,892 --timeout=5000 https://example.com
Use the executable name or path appropriate for your installation. The timeout is a maximum wait, not proof that a site’s application has finished rendering. Chrome Headless mode.
Puppeteer
For JavaScript automation, Puppeteer offers higher-level screenshot workflows, including full-page and specific-element captures. Choose it when you want browser automation APIs around the capture. Use raw CDP when direct protocol control is the goal. Puppeteer documentation.
7. Handle image bytes in your CDP client
The protocol is transport-agnostic: it defines the command and response, while your client handles connection setup and decoding. The essential response-processing steps are:
- Read the response JSON for the command ID you sent.
- Check whether the response has an
error; if so, report it rather than treating it as image data. - Read
result.data, which is base64 image content in JSON transports. - Base64-decode the string to binary bytes.
- Write the bytes to a file with an extension that matches the requested format.
The dossier for this guide establishes the protocol behavior but does not specify or verify a particular CDP client library or end-to-end client implementation. Keep transport-specific code aligned with the documentation for the library and Chrome version you use.
8. Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| The image shows only the viewport. | A viewport capture was requested, or the target Chrome build does not support the beyond-viewport option used. | Check the protocol version and captureBeyondViewport support. For manual capture, use DevTools’ full-size screenshot action. |
| The crop is offset, scaled, or the wrong size. | The clip geometry or scale does not match the selected protocol definition. |
Check the clip object requirements in the target Chrome protocol schema and recalculate the rectangle against the intended page coordinates. |
| The saved image is corrupt or unreadable. | The client wrote the base64 string as text, or the file extension does not match the format. | Base64-decode result.data to bytes before writing. Match the extension to PNG, JPEG, or WebP. |
| The command returns an error or no expected page. | The CDP session may be attached to the wrong target, or the response may contain a protocol error. | Verify the selected page target and inspect the matching command response, including its error field. |
| The extension debugger reports “Screenshot capture is restricted by policy.” | Chrome’s browser.debugger extension API can be blocked by the enterprise DisableScreenshots policy or Data Loss Prevention rules. |
Check the applicable organization policy. This documented restriction is specific to the extension debugger API; do not assume it applies to every remote-debugging transport. Chrome extensions debugger API. |
9. Reliability, performance, and cost considerations
- Version compatibility: CDP fields can vary by Chrome version. Check versioned protocol metadata, especially for fields marked experimental.
- Rendering readiness: A screenshot captures the page state at command time. If the page is still loading or changing, coordinate capture with your application’s readiness conditions before sending the command.
- Image size: PNG preserves image data but can produce larger files than lossy JPEG. JPEG quality trades image fidelity for size. WebP is another supported choice; check that your consumer accepts it.
- Large pages: Full-page output can be substantially larger than a viewport capture. Confirm actual content dimensions and plan memory and storage for the resulting bytes.
- Cost: The protocol itself does not prescribe a price. Account for the browser infrastructure, execution time, storage, and any automation service you operate.
10. Or skip the browser setup
ScreenshotNeo is a website screenshot API: one GET request with a URL returns an image or PDF. It accepts parameter names used by other screenshot APIs, which can make switching easier. The API and its options are documented at ScreenshotNeo docs.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
Cookie banners, popups, and chat widgets are removed before the shot; each step can be turned off. Bot checks, blank pages, and failed loads are never billed, and response headers report the page verdict and billing status. ScreenshotNeo also provides an MCP server for AI agents, including Claude, Cursor, and other MCP clients. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 screenshots. See ScreenshotNeo and the API documentation.
Create a free ScreenshotNeo account for 1,000 screenshots a month with no card.
FAQ
Does Page.captureScreenshot capture the entire page by default?
No. A basic call captures the viewport. Use the beyond-viewport option when supported, or DevTools’ full-size screenshot workflow.
What does the CDP screenshot response contain?
In JSON transports, result.data contains base64-encoded image content. Decode it to bytes before saving.
Can I use CDP to capture a cropped area?
Yes. Pass a clip region using the geometry and scale requirements defined by the protocol version used by your Chrome build.
Which format should I choose?
Use PNG for lossless output. Choose JPEG when smaller lossy output is acceptable and set its 0–100 quality value as needed. WebP is also supported by the protocol.
Should I use raw CDP or a higher-level tool?
Use raw CDP for direct protocol control. For manual work, use DevTools or Protocol Monitor; for a simple CLI workflow, use Headless Chrome; for scripted browser automation, consider Puppeteer.


