·6 min read

Convert HTML to PDF with a Simple API Call

Generate invoices, reports, and documents as PDFs from HTML — no Puppeteer, no wkhtmltopdf, no headless browser infrastructure.

PDF generation is one of those features that sounds simple until you try to implement it. You need to generate an invoice? A report? A shipping label? The usual answer is Puppeteer, wkhtmltopdf, or a headless Chrome setup — and suddenly you're managing browser binaries, fighting memory limits, and debugging rendering differences between environments.

There's a far simpler path: send HTML, get back a PDF.

Why PDF Generation Is Harder Than It Looks

The most common approaches each have significant operational costs:

  • Puppeteer / Playwright — requires a headless Chromium binary (~300MB). Works, but massively inflates Docker images and isn't viable on most serverless platforms. (For a deeper dive on the trade-offs, see Puppeteer vs Screenshot API.)
  • wkhtmltopdf — a battle-tested tool, but depends on Qt WebKit, which is increasingly out of date. Installation varies wildly across Linux distros.
  • Prince, WeasyPrint, PDFKit — each has its own CSS support quirks, and none match browser rendering perfectly.

All of these approaches mean you own the rendering infrastructure. With an API, you don't.

HTML to PDF in One Request

The API Snap PDF endpoint takes HTML content and returns a downloadable PDF:

curl -X POST "https://api-snap.com/api/pdf" \
  -H "Authorization: Bearer snp_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "html": "<h1>Invoice #1042</h1><p>Amount: $299.00</p><p>Due: April 1, 2026</p>",
    "title": "Invoice 1042"
  }' -o invoice.pdf

You get back a PDF file. No Chromium binary. No 300MB Docker layer. No browser pool to manage.

Building an Invoice Generator

Here's a practical pattern for generating invoices in a Node.js backend:

async function generateInvoicePdf(invoice) {
  const html = `
    <style>
      body { font-family: system-ui, sans-serif; padding: 40px; }
      table { width: 100%; border-collapse: collapse; margin-top: 20px; }
      th, td { padding: 8px 12px; border-bottom: 1px solid #eee; text-align: left; }
      .total { font-size: 1.5em; font-weight: bold; margin-top: 20px; }
    </style>
    <h1>Invoice #${invoice.number}</h1>
    <p>Date: ${invoice.date}</p>
    <p>Bill to: ${invoice.customerName}</p>
    <table>
      <tr><th>Item</th><th>Qty</th><th>Price</th></tr>
      ${invoice.items.map(i =>
        `<tr><td>${i.name}</td><td>${i.qty}</td><td>$${i.price}</td></tr>`
      ).join("")}
    </table>
    <p class="total">Total: $${invoice.total}</p>
  `;

  const res = await fetch("https://api-snap.com/api/pdf", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.SNAPAPI_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ html, title: `Invoice ${invoice.number}` }),
  });
  return Buffer.from(await res.arrayBuffer());
}

Other PDF Use Cases

  • Reports and dashboards — render a summary page as HTML with inline CSS, convert to PDF for email distribution
  • Contracts and agreements — template your legal docs in HTML, generate PDFs with filled-in customer details
  • Shipping labels — format label HTML at the exact dimensions you need, convert to a printable PDF
  • Receipts — pair with the QR Code API to embed scannable codes directly in PDF receipts

Tips for Clean PDF Output

  • Use inline CSS or a <style> block — external stylesheets aren't loaded
  • Use system-ui or web-safe fonts for consistent rendering
  • Test your HTML in a browser first — if it looks right there, it'll look right in the PDF
  • Keep it simple: tables, headings, and basic layout work perfectly

Pricing

PDF generation is included in every API Snap plan. The free tier gives you 100 calls/month to test your templates. For production invoice generation, the Hobby plan ($9/mo) covers 5,000 PDFs/month, and the Pro plan ($29/mo) handles 50,000.

Get Started

Create a free account, copy your API key, and generate your first PDF in under a minute. Try it in the Playground to experiment with your HTML templates before integrating. Need to capture existing web pages instead of rendering HTML? Check out the screenshot automation guide.

Ready to try it?

Get your free API key and start building in under a minute.