How to convert a URL to PDF with ScreenshotMachine API
Convert a webpage URL to PDF with ScreenshotMachine’s API. Get a runnable cURL, Python, and Node.js example, plus options for page layout and state.
To convert a URL to PDF with ScreenshotMachine, send a GET request to https://pdfapi.screenshotmachine.com/ with your customer key in key and the page address in url. Save the response bytes as a .pdf file. For example:
curl -G "https://pdfapi.screenshotmachine.com/" \
--data-urlencode "key=YOUR_CUSTOMER_KEY" \
--data-urlencode "url=https://example.com" \
--output output.pdf
This guide covers the request, output choices, runnable examples, and common integration concerns. The parameter details are based on ScreenshotMachine’s official PDF API documentation. Check that documentation before deployment because API details can change.
1. Get a key and make the first request
- Get a customer key through ScreenshotMachine’s account flow.
- Set
urlto the page to render. Include the scheme, such ashttps://. - Send a GET request and write the response body to a file with a
.pdfextension. - Open the saved file with a PDF reader and confirm that the expected content and layout were captured.
The required inputs are key and url. The endpoint returns the generated PDF. Treat the response as binary data: do not decode it as text or print its contents to a terminal.
2. Runnable examples
cURL
curl --fail --show-error --silent -G "https://pdfapi.screenshotmachine.com/" \
--data-urlencode "key=YOUR_CUSTOMER_KEY" \
--data-urlencode "url=https://example.com" \
--data-urlencode "format=A4" \
--data-urlencode "orientation=portrait" \
--output output.pdf
For a minimal request, remove the optional format and orientation parameters. --data-urlencode safely encodes query parameter values, including the target URL. The output file is created in the current directory.
Python
import os
import requests
endpoint = "https://pdfapi.screenshotmachine.com/"
params = {
"key": os.environ["SCREENSHOTMACHINE_KEY"],
"url": "https://example.com",
"format": "A4",
"orientation": "portrait",
"media": "screen",
"bg": "bg",
}
response = requests.get(endpoint, params=params, timeout=120)
response.raise_for_status()
content_type = response.headers.get("content-type", "")
if "pdf" not in content_type.lower() and not response.content.startswith(b"%PDF"):
raise RuntimeError(f"Expected PDF response; got content type {content_type!r}")
with open("output.pdf", "wb") as pdf_file:
pdf_file.write(response.content)
Install the dependency with python -m pip install requests, and set the environment variable before running the script. The response check is a defensive integration check; consult the vendor documentation for its current response contract.
Node.js
import { writeFile } from "node:fs/promises";
const endpoint = new URL("https://pdfapi.screenshotmachine.com/");
endpoint.search = new URLSearchParams({
key: process.env.SCREENSHOTMACHINE_KEY,
url: "https://example.com",
format: "A4",
orientation: "portrait",
media: "screen",
bg: "bg",
}).toString();
const response = await fetch(endpoint);
if (!response.ok) {
throw new Error(`PDF request failed with HTTP ${response.status}`);
}
const bytes = Buffer.from(await response.arrayBuffer());
if (!bytes.subarray(0, 4).equals(Buffer.from("%PDF"))) {
throw new Error("Response did not start with a PDF signature");
}
await writeFile("output.pdf", bytes);
Set SCREENSHOTMACHINE_KEY in the process environment. The standard URL and query encoders avoid breaking the request when the target URL or another value contains reserved characters.
3. Choose the PDF output options
ScreenshotMachine documents these parameters for controlling the rendered document. Add only the options needed by your output requirements.
| Parameter | Choices or range | When to use it |
|---|---|---|
format |
letter by default; also legal, ledger, tabloid, and ISO A0–A6 |
Choose the paper size the PDF should use. |
orientation |
portrait by default or landscape |
Use landscape for wide tables or pages where portrait creates awkward line wrapping. |
media |
screen by default or print |
Use screen for browser-like appearance. Print favors a print-oriented rendering and can remove web-specific graphics or elements. |
bg |
bg by default or nobg |
Include or omit page backgrounds. |
delay |
0–10000 ms, in 200 ms increments; default 200 ms | Allow an animation or delayed page content time to appear before capture. |
scale |
10–200; default 100 | Adjust content zoom. A smaller scale can reduce the number of pages. |
click |
CSS selector | Click a page control before capture, for example a consent action, where appropriate. |
hide |
Comma-separated CSS selectors | Hide selected overlays or page elements before rendering. |
cookies |
Semicolon-separated name-value pairs | Supply cookie state needed to render a particular page. |
accept-language |
Language header value | Request content in a chosen language or locale. |
user-agent |
User agent string | Request a page variant intended for a particular browser or device. |
hash |
MD5 of the exact URL parameter value concatenated with the secret phrase | Protect calls made from public HTML when a secret phrase is configured, as described below. |
Parameter names and accepted values should be checked against the current API reference. For example, choose media=screen when visual similarity to the webpage matters, and media=print when the document is intended for printing. Use bg=nobg only if removing page backgrounds is desirable.
Page state and URL encoding
Some URLs contain their own query strings, fragments, spaces, or other reserved characters. Encode the complete target URL as a query parameter value; do not concatenate a raw URL into the endpoint query string. The examples above use cURL’s --data-urlencode, Python’s params, and JavaScript’s URLSearchParams.
Encode values such as CSS selectors, cookie strings, language values, and user-agent strings as well. A selector containing # or a cookie value containing punctuation can otherwise be parsed incorrectly. Use click and hide only with selectors that match the intended page, and check the resulting PDF when page markup changes.
Hash and credential handling
Keep the customer key and secret phrase on a server you control. Do not put them in browser JavaScript, a public repository, or a public page’s source. The vendor documents hash for calls from public HTML: calculate MD5 over the exact url parameter value followed by the secret phrase. When a secret phrase is set in account settings, the documentation says a missing or incorrect hash is ignored; verify current account behavior in the official guide.
A hash embedded in public HTML should not be treated as a way to keep a secret phrase secret. Prefer a backend endpoint that holds credentials and makes the ScreenshotMachine request itself. If you use the documented hash mechanism, make sure the URL string used in the hash is exactly the value sent as url, including its encoding and punctuation as required by the vendor.
4. Handle files and failures carefully
- Keep the response binary. Write bytes directly to disk or stream them to a file; do not convert the response to a string.
- Check for failure before saving. In Python, call
raise_for_status(); in Node.js, checkresponse.ok. In cURL,--failmakes HTTP error responses return a failure status. - Validate the result. Check a PDF content type or the leading
%PDFsignature before treating a response as a finished document. This guards against accidentally saving an error page as.pdf. - Choose a practical timeout. The examples set a client timeout where supported. Set it according to your application’s request budget; the research sources do not establish a vendor timeout guarantee.
- Use temporary files for critical workflows. Write to a temporary path and rename it after validation so interrupted downloads do not leave a partial file that looks complete.
The reviewed vendor materials describe request parameters and download examples, but do not establish a complete error-code taxonomy, PDF size limit, timeout guarantee, or data-retention policy. If your workflow depends on any of those, confirm them with the current vendor documentation or support rather than assuming a behavior.
5. Troubleshooting
| Symptom | Likely cause | What to check or change |
|---|---|---|
| The saved file is not a PDF | An HTTP error or other response body was saved with a .pdf name. |
Check the HTTP status and response headers; validate the %PDF signature before accepting the file. |
| The request fails for URLs with query strings or fragments | The target URL was concatenated without encoding. | Use --data-urlencode, a client parameter dictionary, or URLSearchParams to encode the full URL as one value. |
| Images or content loaded after the initial page are missing | The page may need more time or a different state before capture. | Try a suitable delay; supply required cookies or language settings; use click only when a page action is required. Confirm the selected options in the official guide. |
| The PDF is too long or content is too small | Paper format, orientation, or scale may not fit the page content. | Try landscape for wide content, choose a suitable paper size, or adjust scale. A smaller scale can reduce page count. |
| Consent or another overlay covers content | The page state still includes the overlay. | Use a matching click selector to activate a page control or hide to remove the overlay from the rendered page. |
| Language or layout differs from the expected page | The request is receiving a different locale or browser variant. | Set accept-language or user-agent as needed and encode the values. |
| A request from public HTML is rejected or behaves unexpectedly | A configured secret phrase may require the documented hash, or a public integration may expose credentials. | Review the account setting and current hash instructions. Move the key and secret phrase to a backend where possible. |
| The PDF is missing background colors | bg=nobg omits the background. |
Use bg=bg or omit the parameter to use its documented default. |
6. Performance, reliability, and cost
Each conversion requires a remote page render and a PDF download, so the application should account for network latency and the size of the resulting document. Keep the request timeout aligned with your own service budget, avoid starting duplicate conversions for the same URL when your application can reuse a saved result, and handle incomplete downloads as failures. The reviewed sources do not provide benchmark figures or a guaranteed rendering time.
For production jobs, keep credentials server-side, record enough request context to diagnose failures without logging secrets, and validate every saved document. If you add retries, limit them to transient failures and use a bounded retry policy so one slow destination does not create a retry storm. Confirm vendor-specific rate limits, billing rules, availability commitments, and retention terms directly; they were not established by the reviewed documentation.
7. Or skip the browser setup
If you need a URL-to-PDF request without wiring the ScreenshotMachine flow, ScreenshotNeo is a website screenshot API and MCP server from Yorker Media. Its API supports PDF output as well as PNG, JPEG, and WebP. See the ScreenshotNeo API documentation for current parameters.
curl -G "https://api.screenshotneo.com/v1/shot" \
-d access_key=YOUR_API_KEY \
--data-urlencode url=https://stripe.com \
-o page.pdf
For ScreenshotNeo, request PDF output using the PDF option documented for the API. Its capture flow accepts cookie and consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each cleanup step can be turned off. Bot checks, blank pages, failed loads, timeouts, and cache hits cost nothing, and response headers report the page verdict and billing status. Its MCP server gives AI agents tools for screenshots, page information, and PDF capture. The free plan includes 1,000 shots per month without a card; paid plans start at $5 for 3,000 shots.
Sign up for ScreenshotNeo’s free plan: 1,000 screenshots a month, no card required.
8. Frequently asked questions
Does the endpoint return a URL to a PDF or the PDF itself?
The documented integration pattern downloads or streams the response as PDF bytes. Save those bytes to a file or pass them to the next step in your application.
Can I make the PDF landscape?
Yes. Set orientation=landscape; portrait is the documented default.
Should I use screen or print rendering?
Use screen to preserve a browser-like look. Choose print when print-oriented output is the goal.
Can I remove a banner from the PDF?
The API documents click for a CSS selector to activate a page control and hide for selectors to remove from the rendered page. The correct selector depends on the target page.
Can this be called directly from a public webpage?
The docs describe a hash option for public HTML when a secret phrase is configured, but public code cannot keep a credential secret. A backend integration is the safer default for applications that must protect a key or secret phrase.


