Turn the whole rendered page into a PDF — JavaScript run, web fonts and lazy-loaded images in, its headings as bookmarks — on A4, Letter or the paper you choose, or as one long page exactly as it looks in a browser. The PDF comes back Base64-encoded, with a link to it in the response headers.
It uses no AI, and costs 1 credit per call — whichever options you use. See Credits.
Save a page as PDF
Body parameters
- Name
url- Type
- string
- Required
- Required
- Description
- The absolute URL of the page to process. Rendered with headless Chrome, so JavaScript runs and redirects are followed. It must not include a username or password (
https://user:pass@example.com).
- Name
pdf_options- Type
- object
- Description
- How to print it: paper, orientation, margins, scale and stylesheet. Every key is optional and included in the credit — see Options. Leave it out for A4 portrait.
- Name
page_options- Type
- object
- Description
- Wait for the page, and remove ads, cookie banners or your own elements from it before it is read — gone from this result, not merely hidden. See Page options.
- Name
residential- Type
- boolean
- Description
- Fetch the page from a residential exit — an address on a home broadband line rather than one in a datacentre. Reach for it when a site serves you less than it serves a browser, or nothing at all. Defaults to
false. Adds 25 credits per page fetch on top of what the operation costs, and its results are kept separate from the ordinary ones.
- Name
report_to- Type
- string
- Description
- Webhook URL — an
httporhttpsaddress URLpipe POSTs the result to when it's ready. Optional: without it we deliver to your project's default endpoint if it has one, and otherwise send no webhook at all — the result still waits for you at GET /result/:token. A value we cannot deliver to returns422. Ignored on async=truerequest. Deliveries can be signed so your endpoint can verify they came from us.
- Name
sync- Type
- boolean
- Description
- Process the request synchronously, returning the result inline in the response. Defaults to
false(async: return a token now, and either receive the result at a webhook or fetch it with GET /result/:token). See Async & sync modes for the full contract.
- Name
max_age- Type
- string | integer
- Description
- How fresh a cached result must be to be accepted. Either an integer number of seconds (
3600) or a duration string of the form"<number> <unit>"— unitss/min/h/d/w(e.g."2 hours","3 days","30m"). Defaults to7 days, clamped to a max of30 days;0always bypasses the cache. See Caching for all accepted units.
- Name
labels- Type
- object
- Description
- Your own keys to find and account for this request by — a client, a project, a campaign:
{"client": "acme"}. Returned with the result, in the webhook and in theX-Labelsheader, and your dashboard filters history and totals credits by them. Up to 16 keys; string values. See Labels.
Response
Content type text/plain — the body is the PDF, Base64-encoded. Decode it to bytes and save it as a .pdf file.
The whole page is printed, not just what fits on screen: it is scrolled through first, so images that load on scroll are on every sheet. By default it is printed the way the browser's own Print does — with the page's print stylesheet, if it has one, and its background colours.
The response also carries an X-Result-Url header: a link to the same PDF that needs no API key, to put in an email or hand to a user. It stays valid for the 30 days the result is kept — see Response headers.
curl -X POST https://urlpipe.dev/pdf \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com", "pdf_options": {"paper_size":"letter"}, "page_options": {"block_cookie_banners":true}}'import requests
res = requests.post(
"https://urlpipe.dev/pdf",
headers={"Authorization": "Bearer YOUR_API_KEY"},
json={"url": "https://example.com", "pdf_options": {"paper_size": "letter"}, "page_options": {"block_cookie_banners": True}},
)const res = await fetch("https://urlpipe.dev/pdf", {
method: "POST",
headers: {
"Authorization": "Bearer YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({ url: "https://example.com", pdf_options: {"paper_size":"letter"}, page_options: {"block_cookie_banners":true} }),
})$ch = curl_init("https://urlpipe.dev/pdf");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
"Authorization: Bearer YOUR_API_KEY",
"Content-Type: application/json",
],
CURLOPT_POSTFIELDS => json_encode(["url" => "https://example.com", "pdf_options" => ["paper_size" => "letter"], "page_options" => ["block_cookie_banners" => true]]),
]);
$response = curl_exec($ch);JVBERi0xLjQKJdPr6eEKMSAwIG9iago8PC9DcmVhdG9yIChDaHJvbWl1bSkK…
(Base64-encoded PDF, truncated)Options
The keys of pdf_options. Each one you leave out is its default, and a request that spells out a default is the same request as one that omits it — it is served the same stored result. A value out of range, or a key not listed here, is refused with invalid_options before anything is fetched or spent.
{
"url": "https://example.com/blog/post",
"pdf_options": {
"paper_size": "letter",
"margin": 15,
"print_background": false
},
"page_options": {
"block_ads": true,
"block_cookie_banners": true
}
}- Name
paper_size- Type
- string
- Description
- The paper:
letter,legal,tabloid,a3,a4,a5. Defaulta4.
- Name
landscape- Type
- boolean
- Description
- Turn the paper sideways. Default false.
- Name
print_background- Type
- boolean
- Description
- Print background colours and images. Default true; turn it off for a lighter, ink-friendly PDF.
- Name
scale- Type
- integer
- Description
- The page's size on the paper, 10 to 200 percent. Default 100. Lower it to fit a wide page on narrow paper.
- Name
margin- Type
- integer
- Description
- Margin on every side, 0 to 50 millimetres. Default 10.
- Name
media- Type
- string
- Description
print(the default) uses the page's print stylesheet, the way a browser prints it — many sites hide their navigation and ads for print.screenprints the page as it looks on screen.
- Name
single_page- Type
- boolean
- Description
- Put the whole page on one page, as wide as the browser window and as tall as the document — the PDF twin of a full-page screenshot, with selectable text and working links.
paper_sizeandlandscapedo not apply. A page taller than 200 inches, the most PDF viewers show, carries on onto a second one.
What the page is made to wait for or leave out — ads, cookie banners, an element that loads late — is set with page_options, which every endpoint that loads the page takes.
Saving the file
curl -s https://urlpipe.dev/pdf \
-H "Authorization: Bearer $URLPIPE_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com", "sync": true}' | base64 --decode > page.pdfpdf_too_large, like an oversized screenshot. Turning off print_background or removing what you do not need with page_options brings it back under.Responses
Whatever the status, the response carries metadata headers: the result token, whether it was served from cache and how old that result is, how long we took, what it cost in credits, and the allowance you have left.
200 OK422 Unprocessable Entity429 Too Many Requests504 Gateway Timeout401 UnauthorizedTry it live — no API key needed
Run this endpoint against any URL right in your browser.