URL to PDF API

Give it a public URL, get the printed page back. Useful for archiving a receipt page, snapshotting a dashboard, or keeping evidence of what a page said on a date. This page is one real capture — a 25-page Wikipedia article — plus every way it failed, measured against the live service on 30 August 2026.

One call #

curl -X POST https://pdf.mintapis.com/v1/pdf \
  -H "Authorization: Bearer $PDFMINT_KEY" -H "content-type: application/json" \
  -d '{"url": "https://en.wikipedia.org/wiki/Portable_Document_Format",
       "format": "A4", "margin": "14mm", "pageNumbers": true}' --output page.pdf

The same page options apply as everywhere else: format, margin, landscape, scale, pageRanges, a header or footer. "mediaType": "screen" renders what a visitor sees rather than what the site’s print stylesheet says — worth trying when a capture comes back stripped of its layout, because many sites hide navigation and images for print.

A real page, measured #

That exact call, from Germany:

MeasureValue
Server-side render5,978 ms
Round trip6,385 ms
Output25 pages, 1,091,879 bytes
Credits1

Six seconds, against 187 ms for an invoice from a stored template on the same account minutes earlier. That difference is the honest headline of this page: rendering a URL is dominated by someone else’s site — their DNS, their TLS handshake, their server, their images, their fonts, their JavaScript. Almost none of it is the PDF step. Size a timeout and a retry policy for that, not for the numbers on our other pages.

If you already have the markup, send it as html instead. It is the same renderer without the network round trip, and it is dramatically faster.

Waiting for the page to be ready #

A modern page is often empty at load and filled by JavaScript. Two controls:

  • "waitFor" — a CSS selector to wait for, or a number of milliseconds. A selector is far better than a sleep: it finishes as soon as the thing exists instead of always costing the full delay, and it fails loudly when the page changed.
  • "timeout" — the ceiling, in milliseconds. On a slow third-party site, raise it; the default is tuned for pages you control.

For a capture that may take many seconds, "async": true returns HTTP 202 with a job_id and a status URL immediately, and "webhookUrl" has the result delivered instead of polled. The credit is taken when the job is accepted.

Anything behind a login #

This is the thing people find out last, so it is here near the top: the render happens on our servers, in a fresh browser, with no session. Your cookies are not there. A page that needs a login renders as the login page, and it renders successfully — HTTP 200, one page, a credit spent, and a PDF of a sign-in form. Nothing in the response says you got the wrong document, because from the renderer’s point of view nothing went wrong.

Options, honestly ranked:

  1. Fetch the page yourself with your own session and POST the resulting markup as html. Correct, fast, and it works for every authentication scheme. This is the answer almost every time.
  2. Send request headers. "headers" is passed to the fetch, so a bearer token or a signed URL can work — if the site accepts a header rather than a session cookie.
  3. A signed public link, where the site offers one.

Do not put a customer’s session cookie in a third-party API call. Not to us, not to anyone.

Addresses we refuse #

A URL-to-PDF service is a request forwarder, and a naive one is a way to read things inside the network it runs in. Private, loopback and link-local addresses are refused before anything is fetched, and the refusal survives a redirect and a hostname that resolves to a private address:

{"url": "http://127.0.0.1:8080/admin"}
→ HTTP 400 private_address_blocked
   "\"url\" points at the private address 127.0.0.1."

The same guard applies to webhookUrl, for the same reason. It also means the obvious local test — pointing the API at something on your own laptop — cannot work: our servers have no route to your machine. Use a tunnel with a public hostname, or send the markup.

What the failures look like #

Measured on the live service, same session as the capture above:

What was sentResponseCredits
A private address400 private_address_blocked0
A host that does not resolve400 dns_failed, “Check the spelling of the URL, and that the host is publicly resolvable.”0

Every error carries a machine-readable code, a sentence a human can act on, a link into the reference, and a request_id to quote. A call that returns no document is not billed, and a render that fails after the credit was taken has it refunded — so a retry loop against a flaky site does not quietly drain the month’s quota.

The failure that is not in that table is the important one: a site that answers with a cookie wall, a consent banner or a bot check returns HTTP 200 and a perfectly good PDF of the wrong thing. Check the page count or the byte size against what you expect. A capture that came back as one short page when you expected twenty is the signal.

When not to use us #

  • You already have the HTML. Send html and skip the network entirely. An inline render on the same account the same afternoon took 57 ms; the six seconds measured above is almost all someone else’s site.
  • The page needs a session. See above — fetch it yourself.
  • You want a screenshot, not a document. POST /v1/image returns PNG, JPEG or WebP and takes fullPage and deviceScaleFactor.
  • You are crawling at scale. Thousands of arbitrary pages an hour is a scraping platform’s job — proxy rotation, robots handling, retry policy. That is not what this is.
  • Legal-grade web archiving. Timestamped, signed, chain-of-custody captures are a specialist product. We print a PDF; we do not attest to when or from where.

What we cannot claim #

No outside customer has paid for PDFMint yet. The free tier is 10 documents a month. One region, one service, no SLA, no SOC 2. We do not run a proxy pool, so a site that blocks datacentre addresses blocks us. The 5,978 ms above is a single capture of one article on one day — your number depends almost entirely on the site you point at, not on us. No PDF/A, no signatures, no timestamping.

Try it #

Point it at the page you actually want to keep, and look at the page count before you look at anything else. That single number catches the consent banner, the bot wall and the login page in one glance.

Get an API key   URL options   Live latency and success rate

Related #

HTML to PDF APIWhat the job really involves, and what six products charge.
Invoice PDF APIA line-item table, VAT and a per-page footer.
Markdown to PDFGFM tables, page numbers, no toolchain.
Merge PDFsSeveral captures into one file, in one call.