DEV Community

Numerix Labs
Numerix Labs

Posted on

URL publication-quality PDF in one POST request

If you've ever tried to "just turn this page into a PDF on the server," you probably spent a Saturday on it.

Headless Chromium works — until it doesn't. CSS backgrounds disappear. Custom fonts come out as squares. The Lambda cold-starts a fresh Chromium each invocation and the first three PDFs of the morning take eleven seconds. By the time the PDF looks right and renders fast, you've shipped half a stack to keep one Chromium process happy.

So we made a smaller version of that problem: POST a URL, get a PDF back.

curl -X POST https://api.numerixlabs.com/screenshot \
  -H "Authorization: Bearer $SNAPAPI_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com/invoice/42","format":"pdf"}' \
  -o invoice-42.pdf
Enter fullscreen mode Exit fullscreen mode

That's the whole API. No render queue, no font upload pipeline, no Chromium process to babysit.

What "publication-quality" means here

It's easy to render a PDF that looks right in a viewer and falls apart when you print it. Three things usually fail:

  1. CSS background images and colours drop. Chromium's default printBackground is false — so the PDF you generate at midnight will not have your brand colour fills, even though the screenshot endpoint shows them. We turn printBackground on by default, so a format=pdf response now matches the on-screen render byte-for-byte across backgrounds, gradient fills, and tinted table rows. (This was the last regression we shipped a fix for; we hit it ourselves on the invoice path.)
  2. Web fonts don't load before the page is captured. We wait for networkidle2 (≤2 long-lived connections — the pragmatic stopping point for analytics-heavy pages that never go fully idle) before snapshotting, so @font-face resolution finishes before the render pass. No squares.
  3. Default A4 page size, full background fidelity. format=pdf renders at A4 with printBackground: true, so brand colour fills, gradient backgrounds, and tinted table rows survive into the file. Chromium emulates @media print by default during PDF generation — so if your page has a print stylesheet, you'll get the print layout in the PDF. If you've designed the page screen-only, the on-screen layout is what you'll get.

The combination is what we mean by "publication-quality." Not "renders without errors" — looks the same as the browser, every time, including the bits that print media queries traditionally murder.

Common use cases we've seen

  • Invoices and receipts. Render your existing HTML invoice page; ship the PDF as the email attachment. Removes the entire "build a separate PDF templating layer" project.
  • Reports. Dashboards or analytics views that exist as live HTML — once a month, snapshot them.
  • Compliance / audit captures. Snapshot a page state at a specific moment with a stable hash you can refer to later.
  • Newsletter archives. Render the issue at send-time and store the PDF.

What the request looks like

The minimum request is a URL and a format. Everything else has sensible defaults.

POST https://api.numerixlabs.com/screenshot
{
  "url": "https://example.com/invoice/42",
  "format": "pdf"
}
Enter fullscreen mode Exit fullscreen mode

You can override the viewport width, add a post-load delay, clip to a CSS selector, capture full-page or above-fold, and pass custom headers and cookies — the docs cover the full surface. The default behaviour is "do the polite thing": full-page capture at 1280px, wait for networkidle2, no delay.

Why we built it like this

A POST-with-a-URL is the smallest possible API that does the job. We chose it over a "PDF SDK with options for every PDF rendering library" because the same shape solves a lot of nearby problems (PNG, JPEG, webhooks for delivery later) without adding more verbs.

Same shape, same retry policy, same auth — different format.

Try it

Free trial is one POST away — get a key at numerixlabs.com. If you're already on Puppeteer-in-a-Lambda and the cold-start latency is hurting you, that's the migration we'd love to talk about.

If format=pdf doesn't match what you see in your browser, mail us — that's a bug, not a "feature request," and we want to know.

— Built by NumerixLabs.

Top comments (0)