ScreenshotNeo

BlogHow-to

How to Capture a Website Screenshot as a PDF with CaptureKit

Use CaptureKit’s API to save a webpage as a PDF, capture full pages, tune readiness, and troubleshoot common request errors.

By the ScreenshotNeo team4 October 20268 min read

To capture a webpage as a PDF with CaptureKit, send a GET request to https://api.capturekit.dev/v1/capture with the page’s URL, format=pdf, and your API key in the x-api-key header. Add full_page=true to include content below the initial viewport; full-page capture is off by default. The API returns PDF output, while PNG is the documented default format. CaptureKit’s API reference documents the endpoint and parameters.

1. Get an API key and make a PDF request

Create a CaptureKit API key and keep it private. Pass it in the x-api-key header. The following cURL example requests a full-page PDF from a publicly accessible page and saves the response as page.pdf:

curl --get 'https://api.capturekit.dev/v1/capture' \
  --header 'x-api-key: YOUR_API_KEY' \
  --data-urlencode 'url=https://example.com' \
  --data-urlencode 'format=pdf' \
  --data-urlencode 'full_page=true' \
  --output page.pdf

Replace YOUR_API_KEY and the example URL with your credentials and target page. URL-encoding the target avoids breaking the query string when it contains characters such as &. Store the key in a secret manager or environment variable in applications; do not commit it to source control or expose it in client-side code.

Python

This Python example uses requests, checks for an HTTP error, and writes the response bytes to a PDF file:

import os
from pathlib import Path

import requests

api_key = os.environ["CAPTUREKIT_API_KEY"]
response = requests.get(
    "https://api.capturekit.dev/v1/capture",
    headers={"x-api-key": api_key},
    params={
        "url": "https://example.com",
        "format": "pdf",
        "full_page": "true",
    },
    timeout=90,
)
response.raise_for_status()
Path("page.pdf").write_bytes(response.content)

Install the dependency with python -m pip install requests, then set CAPTUREKIT_API_KEY in the process environment. A successful HTTP response is expected to contain the requested file. If you need stronger validation in a pipeline, also check the response content type and verify that the saved file can be opened by your PDF tooling.

Node.js

With Node.js 18 or newer, use the built-in fetch API. This example encodes parameters safely and writes the returned bytes to disk:

import { writeFile } from "node:fs/promises";

const apiKey = process.env.CAPTUREKIT_API_KEY;
if (!apiKey) throw new Error("Set CAPTUREKIT_API_KEY first");

const query = new URLSearchParams({
  url: "https://example.com",
  format: "pdf",
  full_page: "true",
});

const response = await fetch(
  `https://api.capturekit.dev/v1/capture?${query}`,
  { headers: { "x-api-key": apiKey } },
);

if (!response.ok) {
  throw new Error(`CaptureKit returned HTTP ${response.status}: ${await response.text()}`);
}

const pdf = Buffer.from(await response.arrayBuffer());
await writeFile("page.pdf", pdf);

2. Choose the page area and readiness behavior

The request parameters control what the browser captures and when it captures it. The documented defaults matter: without an explicit full-page option, the capture is limited to the viewport; without a format, the output defaults to PNG.

Parameter What it controls Documented behavior or practical use
url Target page to render Required. Supply a complete URL, including the scheme such as https://.
format Output format Set to pdf. The documented default is PNG.
full_page Capture beyond the viewport Defaults to false. Set true when the PDF should include the full page.
full_page_scroll Scrolling during full-page capture Available for pages whose content loads as the browser scrolls.
full_page_scroll_duration Time allotted to full-page scrolling The documented default is 400 milliseconds. Consider adjusting it when lazy-loaded content needs more time.
viewport_width, viewport_height Browser viewport dimensions in pixels Documented defaults are 1280 by 1024. Set these when a page’s responsive layout must be rendered at specific dimensions.
delay Additional wait before capture Use when a page needs a known extra settling interval after loading.
wait_until Page readiness condition Choose the documented readiness behavior appropriate to the target. A page reporting an early load event may still be updating dynamic content.
wait_for_selector Wait for a page element Useful when the content of interest appears after client-side rendering; select a stable selector that actually exists on the page.

For a normal static page, start with format=pdf and full_page=true. If important content is missing, first determine whether it is below the fold, appears only after scrolling, or is inserted after the initial page load. Then use full-page scrolling, a suitable wait condition, a selector, or a delay as appropriate instead of adding a long delay to every request.

3. Understand what the PDF documentation does and does not promise

The API reference documents PDF as an output format, but the reviewed reference does not specify the resulting PDF’s page dimensions, pagination rules, or whether text is selectable or the page is represented as a raster image. Do not assume those details match a browser’s print-to-PDF feature. If print layout, selectable text, accessibility, or fixed paper dimensions are requirements, inspect the produced file with your actual target pages and confirm the behavior before relying on it.

Also distinguish a full-page capture from a paginated print layout. full_page=true requests content beyond the viewport; it does not, by itself, document how that content is divided across PDF pages.

4. Handle errors and unreliable pages

CaptureKit’s reference lists HTTP 400, 401, 402, 429, and 500 responses. Treat the status code as part of the result; do not save an error response under a .pdf filename.

HTTP status Documented meaning What to check
400 Bad request Check that url is present and valid, format is supported, and parameter values are correctly encoded.
401 Invalid API key Confirm the key is correct, active, and sent in the x-api-key header.
402 Payment required Check the account’s credit or payment status in CaptureKit.
429 Rate limit exceeded Reduce request concurrency or pace requests, then retry according to your application’s retry policy.
500 Internal error Retry transient failures with bounded backoff. Log the status and response body, and avoid an unbounded retry loop.

Common capture problems

  • The PDF contains only the top of the page: set full_page=true; it defaults to false.
  • The output is an image instead of a PDF: explicitly set format=pdf; PNG is the documented default.
  • Images or sections that load on scroll are missing: enable the full-page scrolling controls and allow enough scroll duration for the page to load its content.
  • A dynamic section is blank or stale: wait for a reliable selector or choose an appropriate wait_until condition. A delay can help when the update time is predictable, but it is less targeted.
  • The layout differs from your expected design: set the viewport dimensions explicitly and check the page’s responsive breakpoints. The default viewport is 1280 by 1024 pixels.
  • The saved file is not a valid PDF: check the HTTP status before writing the response, inspect the response body on errors, and confirm the request explicitly asks for format=pdf.
  • A private page cannot be captured: the target must be reachable by the capture service. The reviewed API reference does not establish a way to access a page behind your local network or an interactive login flow; do not assume your local browser session is shared with the API.

5. Performance, reliability, and cost

The API reference lists one credit per call. That means retries and separate captures consume calls, so avoid retrying every failure indiscriminately. Use bounded retries for transient server or rate-limit errors, and fix malformed URLs or invalid credentials rather than repeating them. The reference lists a rate-limit response but the reviewed material does not specify a universal request rate.

Capture time depends on the target page and how long it takes to reach the requested readiness condition. Full-page scrolling and extra waiting can increase the time for an individual capture. For batch jobs, use a finite timeout, cap concurrency, record each URL’s status, and retry only failures that may be transient. Keep the API key out of logs and URLs.

The official pricing page reviewed lists PDF output on Free (100 credits, $0), Starter (1,000 credits, $7/month), and Pro (10,000 credits, $29/month). Pricing and plan terms can change, so confirm them on CaptureKit’s pricing page before estimating a current workload. Those credit figures are plan details, not a performance benchmark.

6. When to use an API versus a local browser

For a one-off document, browser print controls may be enough. For recurring captures, scheduled jobs, or integration into a pipeline, an API avoids maintaining the rendering workflow in each calling application. CaptureKit describes its service as a browser-like screenshot API for capture without a headless setup; that is the vendor’s description. Choose based on the controls you need, whether you can run a browser environment yourself, how much PDF layout control is required, and the expected request volume. CaptureKit’s reviewed reference does not settle pagination or selectable-text behavior, so verify those requirements directly against generated output.

Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server. One GET request can return a screenshot or PDF; the API supports PDF settings such as paper size, margins, landscape, and page ranges. Use the ScreenshotNeo API docs for the available parameters and current request details.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.pdf

Set the PDF output options supported by the API when you need specific paper size, margins, orientation, or page ranges. ScreenshotNeo removes cookie banners, newsletter popups, and chat widgets before capture; each cleanup 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. Its MCP server lets AI agents use take_screenshot, get_page_info, and capture_pdf. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots.

Sign up free for ScreenshotNeo: 1,000 screenshots a month, no card required.

FAQ

Does CaptureKit capture the full page as a PDF by default?

No. The documented default for full_page is false. Set it to true to request content beyond the viewport.

How many credits does one CaptureKit capture use?

The reviewed API reference lists one credit per call.

Will the PDF have selectable text or browser-style print pagination?

The reviewed CaptureKit API reference does not specify text-layer behavior, PDF page dimensions, or pagination. Check the generated file against your requirements.

Can I use this endpoint for automated recurring captures?

Yes, an API request can be integrated into a recurring workflow. Add timeouts, bounded retries, rate control, and status logging so temporary failures do not create runaway requests.

Sources