URL to PDF API

URL to PDF API: convert any webpage into a clean PDF

Pass a URL and get a PDF of the fully loaded page, with JavaScript finished, fonts ready and print styles applied. No headless browser to host, patch or scale.

  • 50 free renders/month
  • No credit card
  • Chromium 153

What does a URL to PDF API do?

A URL to PDF API opens a web address in a headless browser, waits until the page has finished loading, and saves what it shows as a PDF. You send the URL in an HTTP request and get the file back, so you can archive pages, export dashboards or offer downloads without running a browser yourself.

URL to PDF API key facts
EndpointPOST https://api.dynamicdocumentapi.com/v1/pdf/from-url
InputAny public http or https URL, optionally with cookies, headers or basic auth
OutputPDF as a signed URL (default), raw binary or base64
Rendering engineEngine 2026.4 on Chromium (Chrome 153.0.8010.47), JavaScript on by default
Waitingload, networkidle, CSS selector, ready_flag or fixed delay; timeout 100 ms to 300 s
Render timeMostly set by how fast the target site loads. Across all renders: median 216 ms, p95 516 ms1
Page sizes13 named sizes or custom up to 200 inches; one continuous page with single_page
PriceFree: 50 renders/month. Paid from €15/month (billed annually) for 3,000 renders, auto top-ups from €6 per 1,000

1. Measured over 1,664 successful renders on engine 2026.4. total_ms = time in the queue plus processing in the worker, excluding API overhead and network transfer. The figures cover all input types; a URL capture takes as long as the target site needs to load, plus the wait condition you set.

Convert a URL to PDF with one request

The request needs one field, url. Everything else is optional: print settings go into pdf, and credentials for pages behind a login go into http. The example waits until the network is idle, which catches most content that loads after the first paint, and saves a US Letter PDF.

curl https://api.dynamicdocumentapi.com/v1/pdf/from-url \
  -H "Authorization: Bearer $DYNAMIC_DOCUMENT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/pricing",
    "pdf": {
      "paper": { "size": "Letter" },
      "wait":  { "until": "networkidle", "timeout_ms": 20000 }
    },
    "delivery": "binary"
  }' \
  --output page.pdf
// Node.js 18+ (built-in fetch)
const res = await fetch("https://api.dynamicdocumentapi.com/v1/pdf/from-url", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.DYNAMIC_DOCUMENT_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    url: "https://example.com/pricing",
    pdf: {
      paper: { size: "Letter" },
      wait:  { until: "networkidle", timeout_ms: 20000 },
    },
  }),
});

const render = await res.json();
console.log(render.files[0].url); // signed URL, valid for 1 hour
import os
import requests

res = requests.post(
    "https://api.dynamicdocumentapi.com/v1/pdf/from-url",
    headers={"Authorization": f"Bearer {os.environ['DYNAMIC_DOCUMENT_API_KEY']}"},
    json={
        "url": "https://example.com/pricing",
        "pdf": {
            "paper": {"size": "Letter"},
            "wait":  {"until": "networkidle", "timeout_ms": 20000},
        },
        "delivery": "binary",
    },
    timeout=60,
)
res.raise_for_status()

with open("page.pdf", "wb") as f:
    f.write(res.content)
<?php
$payload = [
    'url' => 'https://example.com/pricing',
    'pdf' => [
        'paper' => ['size' => 'Letter'],
        'wait'  => ['until' => 'networkidle', 'timeout_ms' => 20000],
    ],
];

$ch = curl_init('https://api.dynamicdocumentapi.com/v1/pdf/from-url');
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer ' . getenv('DYNAMIC_DOCUMENT_API_KEY'),
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS     => json_encode($payload),
]);

$render = json_decode(curl_exec($ch), true);
echo $render['files'][0]['url'];

Capture the page at the right moment

Most broken URL-to-PDF output has one cause: the snapshot was taken too early. Charts are still empty, images are grey boxes, and the text is set in a fallback font. The engine always waits for the load event, then for web fonts, image decoding and two rendered frames. For everything that loads later, you decide what "ready" means.

Wait for JavaScript and lazy-loaded content

networkidle waits until no request has been open for 500 ms. selector waits for an element, for example a chart container that gets a data-ready attribute. ready_flag lets the page's own script say when it is done, and delay adds a fixed pause.

"wait": { "until": "selector",
  "selector": ".dashboard[data-ready]",
  "timeout_ms": 30000, "strict": false }

With strict: false a timeout still returns the PDF, plus a wait_timeout warning; with true the render fails instead.

Pages behind a login

Pass what the site needs to recognise a signed-in user: up to 50 cookies, up to 50 headers such as a bearer token, basic_auth, or a custom user_agent.

Credentials only go to the same registrable domain as the URL, cookies set by other domains are dropped, and secrets are redacted in logs. Interactive login forms and OAuth flows are not supported: create a session or a token first, then pass it.

Cookie banners

A consent banner covering half of page one is the second most common complaint. The reliable fix is to send the cookie the site stores after a visitor clicks "Accept". Open the site in your browser, accept, copy the consent cookie, and pass it in http.cookies. The banner never renders.

"http": { "cookies": [
  { "name": "cookie_consent", "value": "accepted",
    "domain": "example.com" } ] }

Print CSS or screen CSS

By default the page is rendered with print media, so a site's print stylesheet applies: navigation hidden, links expanded, colors adjusted. Many sites have no real print styles. If the result looks stripped down, set emulate_media to screen to get the layout visitors see.

Custom CSS or scripts cannot be injected into a URL capture. That keeps a third-party page exactly as its owner built it; if you need to change the layout, fetch the HTML and use the HTML to PDF endpoint instead.

Paginated or one long page

A webpage has no pages; a PDF does. You choose how the page is split:

  • Standard paper. One of 13 named sizes, from A0 to A6, B4, B5, Letter, Legal, Tabloid and Ledger, in portrait or landscape, with your own margins and scale from 0.1 to 2.0.
  • Custom size. Any width and height from 0.1 to 200 inches, for example a 1280 px wide page that matches a desktop layout.
  • One continuous page. single_page: true makes the PDF exactly as tall as the content. No page break cuts through a chart or a table row.
  • Only some pages. page_ranges such as "1-2" returns only the first part of a very long page.

What teams use URL to PDF for

  • Dashboard exports. Your app already renders the dashboard. Capture its URL with a session cookie and send the PDF as a weekly report, instead of rebuilding every chart in a separate template.
  • Compliance snapshots. Save the state of a terms page, a price list or a published ad at a given moment, with the capture time in your own records.
  • Web invoices and order pages. If invoices already exist as pages in your customer portal, a PDF copy is one request away.
  • Downloadable content. Offer a PDF version of articles, documentation or reports next to the web version.

URL capture is one of four inputs of our PDF generation API: the same engine also renders raw HTML, Markdown and stored templates.

URL to PDF or HTML to PDF: which should you use?

Both run on the same Chromium engine. The difference is who controls the page.

When to use URL to PDF and when to use HTML to PDF
Criterion URL to PDF HTML to PDF
The page already exists onlineBest choiceYou would have to fetch and send its HTML
You need to change the layoutNot possible, no CSS injectionFull control over HTML, CSS and scripts
Page behind a loginCookies, headers or basic authNo login needed, you send the content
Relative links to images and fontsResolved against the URLUse absolute URLs
Depends on the target siteYes: speed, uptime and changesNo

Rule of thumb: capture a URL when the page is the source of truth, and send raw HTML instead when you generate the content yourself or need a print layout that differs from the website.

URL to PDF API pricing

Start free, then pay a flat monthly price for a fixed PDF volume.

Free

€0

50 renders per month, full REST API. For testing and prototypes.

Starter

€15 / month

3,000 renders per month, billed annually (€19 billed monthly). About €0.005 per render.

Larger volumes are on the Growth, Pro and Scale plans. Compare them in the full pricing.

FAQ

URL to PDF API: frequently asked questions

Can it convert pages that require a login?

Yes, as long as the page accepts a session cookie, a header such as a bearer token, or HTTP basic auth. Send them in http.cookies, http.headers or http.basic_auth. They are only sent to the same site as the URL. An interactive login form or an OAuth flow cannot be filled in for you.

Does it wait for JavaScript to finish?

Yes. JavaScript runs by default and the engine always waits for the load event, web fonts, image decoding and two rendered frames. For pages that keep loading after that, set pdf.wait.until to networkidle, a CSS selector, a ready_flag or a fixed delay.

How do I remove cookie banners from the PDF?

Send the consent cookie the site sets after a visitor accepts, in http.cookies. The banner then never appears. Custom CSS cannot be injected into a URL capture, so hiding the banner with a style rule is not possible; if you need to restyle the page, fetch its HTML yourself and use the HTML to PDF endpoint.

Can I get one continuous page instead of A4 or Letter pages?

Yes. Set pdf.single_page to true and the PDF becomes one page as tall as the content. This is useful for long landing pages, receipts and archives where page breaks would cut through content.

What are the timeout and page-size limits?

The wait timeout defaults to 30 seconds and can be set from 100 milliseconds to 300 seconds. Paper can be one of 13 named sizes or any custom size from 0.1 to 200 inches per side.

Can I convert any public website?

Technically, any page that is reachable on the public internet. Addresses in private or internal networks are blocked. You are responsible for having the right to store or share the content you capture.

Convert your first URL free

50 renders a month on the free plan, no credit card, auto top-ups on paid plans, no browser to run.

Start free