pennypdf

Developer API

HTML to PDF API

HTML-to-PDF is the workhorse endpoint in most invoice, report, and receipt pipelines. It's also the most overpriced category in the developer-PDF market — DocRaptor charges $0.12/doc after a $15/month minimum, PDFShift $0.18/doc overage on a $9/month base, and the self-hosted Puppeteer path eats engineering time forever.

PennyPDF's /v1/html-to-pdf runs headless Chromium with print-CSS media queries enabled. Pass an HTML string, a raw URL, or a HTML+CSS payload; receive the rendered PDF back in ~1–3 seconds for a typical invoice. 1 coin per render. That's 4 cents at the Saver pack, 3 cents at the Pro pack.

The endpoint supports page size (A4, Letter, custom), margins, header/footer templates (also HTML), landscape orientation, wait-for-selector (so your JS-rendered dashboard renders fully before we snapshot), and bundled webfont inlining. Everything you'd expect from Puppeteer, behind a bearer token.

Copy, paste, ship

Same bearer-token auth across every endpoint. Set PENNYPDF_API_KEY in your environment first.

curlPOST /v1/html-to-pdf (inline HTML)
curl -X POST https://api.pennypdf.com/v1/html-to-pdf \
  -H "Authorization: Bearer $PENNYPDF_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "html": "<h1>Invoice INV-1042</h1><p>Amount due: $1,200</p>",
    "page_size": "Letter",
    "margins": {"top": "1in", "bottom": "1in"}
  }' \
  -o invoice.pdf
PythonURL-based render
import os, requests

r = requests.post(
    "https://api.pennypdf.com/v1/html-to-pdf",
    headers={
        "Authorization": f"Bearer {os.environ['PENNYPDF_API_KEY']}",
        "Content-Type": "application/json",
    },
    json={
        "url": "https://reports.example.com/invoice/1042?render=true",
        "wait_for_selector": "#invoice-ready",
        "page_size": "A4",
    },
    timeout=30,
)
r.raise_for_status()
open("invoice.pdf", "wb").write(r.content)

PennyPDF vs DocRaptor

 PennyPDFDocRaptor
Price per doc1 coin (~$0.04)$0.12/doc overage
Monthly minimum$0$15/mo for 125 docs
Test-mode docs10 welcome coins (3 free tests)Unlimited, but watermarked
PDF engineChromium (print CSS)PrinceXML
Output quality for printVery goodBest-in-class for typography
Pay-as-you-goYes, alwaysNo

How it works

  1. 1Grab an API key at /dashboard/api.
  2. 2POST {html} or {url} to /v1/html-to-pdf with your page-size and margin preferences.
  3. 3Receive the PDF synchronously in the response body — no job polling for standard renders.

Frequently asked

How does quality compare to DocRaptor's PrinceXML?+

For most invoices, reports, and statements, the output is indistinguishable. PrinceXML has an edge on complex typography (hyphenation, ligatures, orphans/widows control) because it's a print-first engine. Chromium wins on modern CSS (Grid, Flexbox, custom properties) and JavaScript-rendered content. Pick based on your primary use case.

Does it execute JavaScript?+

Yes. Full Chromium, so React/Vue/Svelte-rendered pages work. Use `wait_for_selector` or `wait_for_ms` to control when the snapshot happens — without it, we snapshot at the DOMContentLoaded event, which misses async data fetches.

What's the latency?+

Inline HTML: 90th percentile 1.1 s for a 5-page invoice. URL-based render: 2–4 s depending on how many assets the page loads. For anything over 5 s expected time, use the async variant (POST /v1/jobs/html-to-pdf) so you don't tie up a connection.

How do headers and footers work?+

Pass `header_template` and `footer_template` as HTML strings. They render on every page. Standard Chromium template variables work: `<span class="pageNumber"></span>`, `<span class="totalPages"></span>`, `<span class="date"></span>`, `<span class="title"></span>`.

Rate limits?+

200 requests/minute baseline, burst to 400. For bulk document generation (invoicing runs, end-of-month reports), the async jobs endpoint runs without the per-minute cap — coins are the only limit there.

Can I use my own fonts?+

Yes. Reference them via @font-face in your HTML with absolute URLs — Chromium will fetch them during render. For offline-only fonts, base64-encode them into the CSS to avoid the fetch.

Why PennyPDF

  • No subscription. Ever.
  • Coins never expire — use them in 5 years.
  • Client-side processing for 14 of 22 tools.
  • No watermarks at any tier.
  • Per-operation pricing, shown before you click.
  • Same coins for web + public API.