How to Generate a PDF from a URL with Abstract Screenshot API
Abstract’s documented Screenshot API returns images, not a confirmed PDF. Here’s how to capture a page and turn the image into a PDF.
Short answer: Abstract’s Website Screenshot API documentation describes URL or raw HTML input and image output, including JPEG, PNG, and GIF. It does not document a direct PDF response. To make a PDF with this API, capture an image and convert that image to a PDF in a separate step. The result is a raster PDF: page text generally will not be selectable as text. If you need a directly generated, text-selectable PDF, use a PDF renderer whose official documentation confirms that capability.
This guide shows the documented request shape, a Python capture-and-convert workflow, and ways to check the response before saving it. Abstract’s live [Website Screenshot API page](https://www.abstractapi.com/api/website-screenshot-api) is the source for its current endpoint and options; verify its current docs and account limits before shipping an integration.
1. Confirm what the API returns
Abstract displays the endpoint https://screenshot.abstractapi.com/v1/ and a request using api_key and url. Its product page describes screenshots as images and names JPEG, PNG, and GIF. It does not establish a format=pdf option or a PDF endpoint. Do not send an assumed PDF parameter: a successful screenshot request is not evidence that the response is a PDF.
The request parameters below are the documented example shape. URL-encode the target page as a query parameter, keep the API key on the server, and consult Abstract’s current documentation for any additional parameters, response details, and error behavior before relying on them in production. [Abstract Website Screenshot API](https://www.abstractapi.com/api/website-screenshot-api)
2. Choose the right PDF workflow
| Need | Workflow | What to expect |
|---|---|---|
| A visual record of a page | Abstract screenshot, then image-to-PDF conversion | Page content is rasterized. Text selection, links, and accessibility structure are not preserved by the image conversion. |
| Selectable text, links, or print layout | Use a separately documented HTML-to-PDF renderer | Check its print CSS, page size, page breaks, font loading, and handling of dynamic content. |
| A private page or customized capture | Check Abstract’s live docs for current authentication and capture behavior; raw HTML is also described as an input | Do not assume undocumented login, cookie, or request parameters. |
Image-to-PDF conversion usually places the image on a PDF page. It does not reconstruct the original DOM. For long pages, decide whether one tall image page is acceptable or whether the image should be split across standard pages; splitting can cut content and reduce legibility.
3. Capture with Abstract and convert with Python
The example below calls the documented endpoint with api_key and url, checks the HTTP result and response content type, and converts the returned image to a single-page PDF using Pillow. Install the dependency with python -m pip install requests Pillow. Set the key in an environment variable rather than committing it to source control.
import os
from io import BytesIO
from pathlib import Path
import requests
from PIL import Image
API_KEY = os.environ["ABSTRACT_API_KEY"]
TARGET_URL = "https://example.com"
ENDPOINT = "https://screenshot.abstractapi.com/v1/"
response = requests.get(
ENDPOINT,
params={"api_key": API_KEY, "url": TARGET_URL},
timeout=(10, 120),
)
response.raise_for_status()
content_type = response.headers.get("Content-Type", "").lower()
if not content_type.startswith("image/"):
raise RuntimeError(
f"Expected an image response; got Content-Type={content_type!r}. "
"Check the API response and current Abstract documentation."
)
try:
image = Image.open(BytesIO(response.content))
image.load()
except Exception as exc:
raise RuntimeError("The response was not a readable image.") from exc
# PDF requires RGB or grayscale image data; normalize transparency and palette images.
if image.mode in ("RGBA", "LA") or "transparency" in image.info:
rgba = image.convert("RGBA")
background = Image.new("RGB", rgba.size, "white")
background.paste(rgba, mask=rgba.getchannel("A"))
pdf_image = background
else:
pdf_image = image.convert("RGB")
output = Path("page.pdf")
pdf_image.save(output, "PDF", resolution=150.0)
print(f"Saved {output} ({pdf_image.width} x {pdf_image.height} pixels)")
Run it with ABSTRACT_API_KEY set in the process environment. For example, in a Unix-like shell: export ABSTRACT_API_KEY='your-key', then run the Python file. Avoid putting a real key in shell history or logs. The timeout is a client-side wait limit, not a promise about the API’s rendering time.
This produces one PDF page whose dimensions follow the screenshot image’s pixel dimensions and the chosen resolution metadata. It does not create letter- or A4-sized pages. If standard paper dimensions matter, use a PDF library to size and position the image on the intended page, or choose an HTML-to-PDF renderer.
4. Make the documented request with cURL
cURL can save the API response to a file, but cURL itself does not convert an image into a PDF. The example safely URL-encodes the query values and writes the response as an image file. Confirm the actual response format using the current API documentation and the response headers before choosing the extension.
curl --fail --show-error --silent \
-G 'https://screenshot.abstractapi.com/v1/' \
--data-urlencode "api_key=$ABSTRACT_API_KEY" \
--data-urlencode 'url=https://example.com' \
-o page-image
Inspect the response content type or open the downloaded file before handing it to an image-to-PDF tool. Do not rename image bytes to .pdf; changing a filename does not convert the file format. Keep the key out of shared scripts and command logs.
5. Node.js capture and conversion
This Node.js example uses the built-in fetch available in modern Node.js and the sharp package for image-to-PDF conversion. Install it with npm install sharp. The code checks the HTTP status and image metadata before conversion.
import sharp from "sharp";
import { writeFile } from "node:fs/promises";
const apiKey = process.env.ABSTRACT_API_KEY;
if (!apiKey) throw new Error("Set ABSTRACT_API_KEY in the environment.");
const endpoint = new URL("https://screenshot.abstractapi.com/v1/");
endpoint.search = new URLSearchParams({
api_key: apiKey,
url: "https://example.com",
}).toString();
const response = await fetch(endpoint, { signal: AbortSignal.timeout(120_000) });
if (!response.ok) {
throw new Error(`Screenshot request failed: HTTP ${response.status}`);
}
const contentType = response.headers.get("content-type") ?? "";
if (!contentType.toLowerCase().startsWith("image/")) {
throw new Error(`Expected an image response, got ${contentType || "no content type"}`);
}
const imageBytes = Buffer.from(await response.arrayBuffer());
const metadata = await sharp(imageBytes).metadata();
if (!metadata.width || !metadata.height) {
throw new Error("Response does not appear to be a valid image.");
}
// sharp's PDF output uses a white background for transparent input.
const pdfBytes = await sharp(imageBytes)
.flatten({ background: "white" })
.pdf()
.toBuffer();
await writeFile("page.pdf", pdfBytes);
console.log(`Saved page.pdf (${metadata.width} x ${metadata.height} pixels)`);
As with the Python example, this is a single image-based PDF page. If the installed sharp build or version does not support PDF output, use a PDF library that embeds the image, and verify its supported formats in that library’s documentation.
6. Capture controls and input choices
Abstract’s product page describes viewport dimensions, custom CSS injection, and capture delays. Those options can help prepare a screenshot before converting it. The page also says its renderer handles HTML, CSS, SVG, web fonts, graphs, and images. Confirm exact parameter names and limits in Abstract’s live documentation; the product page alone is not a complete parameter reference.
- Viewport and dimensions: choose a viewport that matches the intended visual record. A narrow viewport may trigger mobile page layouts; a wide one may change navigation and line wrapping.
- Custom CSS: use documented CSS injection to hide irrelevant page elements or adjust the capture presentation. CSS changes can alter content, so retain the source URL and capture settings with the PDF when auditability matters.
- Capture delay: a delay can give client-rendered content more time to appear, but fixed waits add latency and cannot guarantee every asynchronous element is ready.
- URL or raw HTML: Abstract’s FAQ describes raw HTML as an alternative to a public URL. This can be useful for generated markup, but external assets referenced by that HTML may still need to be reachable by the renderer. Confirm the supported submission method and size limits in current docs.
- Location-dependent pages: Abstract says capture from different locations is not currently supported. If a page varies by visitor IP location, the resulting image may not represent the region you need.
7. ScreenshotNeo option: direct PDF capture
If the deliverable must be a PDF and you do not want to build a browser-rendering and conversion pipeline, ScreenshotNeo accepts a URL in one request and returns a PDF or screenshot image. See the [ScreenshotNeo API documentation](https://screenshotneo.com/docs/) for request options.
curl -G "https://api.screenshotneo.com/v1/shot" \
-d access_key=YOUR_API_KEY \
--data-urlencode url=https://example.com \
-d format=pdf \
-o page.pdf
ScreenshotNeo removes cookie and consent banners, newsletter popups, and chat widgets before capture; each step can be disabled. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and the response identifies page verdict and billing status in headers. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for MCP clients such as Claude and Cursor. The free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots. Every feature is available on every plan. Visit [ScreenshotNeo](https://screenshotneo.com) or [create a free account](https://screenshotneo.com/account/sign-up/) to try it.
8. Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| The result is not a PDF | The Screenshot API returns an image, or the response is an API error body. | Check HTTP status and content type; convert valid image bytes with a PDF library. Do not rely on an undocumented PDF parameter. |
| The image library cannot open the response | The response may be an error payload, unexpected format, or truncated data. | Check status and headers before conversion; inspect a small, redacted error response and consult current API docs. |
| Authentication fails | Missing, invalid, expired, or incorrectly encoded API key. | Check the account key and query encoding. Keep the key on the server and do not log full request URLs that contain it. |
| Screenshot shows a loading state or missing chart | Dynamic content had not rendered at capture time, or requires interaction. | Use a documented delay or CSS/customization option where available; confirm whether the API supports the interaction needed. A delay cannot fix content blocked by authentication or the target site. |
| Page layout differs from a browser | Viewport, responsive breakpoints, fonts, region, or page state differ. | Set the documented viewport and CSS controls; verify required assets can load. Abstract says capture from different locations is not currently supported. |
| PDF is huge or hard to read | A high-resolution or very tall screenshot was embedded as one page. | Resize carefully, split the image across pages with a PDF library, or use a true HTML-to-PDF renderer when selectable text and pagination matter. |
| PDF has a black or unexpected background | Transparency was not flattened consistently by the converter. | Flatten transparent images onto a chosen background before creating the PDF. |
| Request times out or receives an error status | Slow target rendering, network trouble, API limits, or an invalid request. | Set a bounded client timeout, record status and request identifiers if provided, and retry transient failures with backoff. Check your plan and the current API’s documented limits before increasing concurrency. |
9. Performance, reliability, and cost
A screenshot call includes page loading and rendering, followed by the image download and local PDF conversion. Keep timeouts finite, avoid unbounded parallel requests, and retry only errors that are likely transient. Use exponential backoff with a maximum attempt count, and avoid retrying authentication or invalid-parameter errors unchanged.
Image-based PDFs can be large because each page contains a bitmap. Higher pixel dimensions improve detail but consume more bandwidth, storage, and memory during conversion. Resizing or lowering image quality can reduce file size, with a corresponding loss of detail. Standard paper pages require deliberate scaling and pagination.
Abstract’s page currently displays a Free plan with 100 requests and one request per second, and a Standard plan at $99/month; the Standard quota is shown differently between annual and monthly billing views. Pricing and quotas can change, so check the live pricing page and billing basis before estimating cost. The page also advertises a 99.99% uptime SLA for Enterprise; that is a vendor-stated offer, not an independent performance measurement. [Abstract pricing and product details](https://www.abstractapi.com/api/website-screenshot-api)
10. Frequently asked questions
Does Abstract Screenshot API support PDF?
The reviewed official product page documents image output and does not document direct PDF output. Confirm the current official docs before publication or implementation; do not infer PDF support from image capture.
Can I make searchable text from the screenshot PDF?
Not with image embedding alone. The PDF contains pixels. Searchable text requires an HTML-to-PDF workflow that preserves text or a separate OCR step.
Can Abstract capture a page that is not public?
Its FAQ says raw HTML can be supplied instead of a public URL, and a dated changelog mentions password-protected website capture. Confirm the current authentication workflow and requirements in Abstract’s docs.
Will the PDF look exactly like the browser’s Print command?
No guarantee follows from a screenshot workflow. A screenshot captures pixels at a viewport; browser printing uses print layout and pagination. Use a documented PDF renderer when print behavior is the requirement.
Sources
- Abstract Website Screenshot API — endpoint example, supported image formats, capture controls, FAQ, and displayed pricing.
- ScreenshotNeo API documentation — ScreenshotNeo request reference.


