How to Generate PDFs from HTML in 2026: Server-Side API vs Local Headless Chrome
Invoices, reports, receipts — without installing Chromium, managing browser processes, or paying for infrastructure. One REST API call converts any URL or HTML string to PDF in under a second.
Every developer eventually needs to generate PDFs. Invoices, reports, receipts, contracts — the list goes on. The traditional approach is to spin up Puppeteer or Playwright, manage Chromium installation, and run the browser locally. But there's a simpler way: an HTTP API.
PageBolt's /pdf endpoint converts URLs or raw HTML to PDF with a single REST call. No browser installation, no infrastructure, no DevOps headaches.
The Problem With Local PDF Generation
Most teams generate PDFs like this:
// Traditional approach — Puppeteer + local Chromium
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('https://example.com/invoice/123');
await page.pdf({ path: 'invoice.pdf' });
await browser.close();
This works, but comes with hidden costs:
- Infrastructure overhead — Chromium is 300MB+. Multiply that by 100 CI/CD agents and you're paying for storage, bandwidth, and slow startup times.
- Memory bloat — Each browser instance consumes 200–500MB RAM. Scaling to 10 concurrent PDF generations costs $500+/month.
- Dependency management — Puppeteer version breaks, Chromium incompatibilities, Node.js version conflicts.
- Slow cold starts — Browser startup adds 2–5 seconds to every PDF request.
- No concurrency by default — You have to manually manage a browser pool and handle race conditions.
An API-first approach eliminates all of this.
URL-to-PDF: The Simplest Case
Convert any public URL to PDF in one HTTP call:
curl -X POST https://pagebolt.dev/api/v1/pdf \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/invoice/123",
"format": "A4",
"margin": "1cm"
}' \
-o invoice.pdf
That's it. The PDF is saved locally. No browser, no dependencies, no infrastructure.
Cost: 1 API request = 1 PDF. PageBolt's free tier includes 100 requests/month. At $29/month you get 5,000 requests (enough for small SaaS); at $199/month, 50,000 requests (enterprise scale).
HTML-to-PDF: Generate From Dynamic Content
Real-world scenario: your app builds a custom invoice as HTML (line items, taxes, totals). You need to convert that HTML string to PDF.
JavaScript example:
const response = await fetch('https://pagebolt.dev/api/v1/pdf', {
method: 'POST',
headers: {
'x-api-key': process.env.PAGEBOLT_API_KEY,
'Content-Type': 'application/json',
},
body: JSON.stringify({
html: `
<html>
<head>
<style>
body { font-family: Arial; margin: 40px; }
.header { font-size: 24px; font-weight: bold; margin-bottom: 20px; }
.line-item { display: flex; justify-content: space-between; margin: 10px 0; }
.total { font-weight: bold; border-top: 1px solid #ccc; margin-top: 20px; padding-top: 10px; }
</style>
</head>
<body>
<div class="header">Invoice #INV-2026-001</div>
<div class="line-item"><span>Product A</span><span>$50.00</span></div>
<div class="line-item"><span>Product B</span><span>$30.00</span></div>
<div class="total">Total: $80.00</div>
</body>
</html>
`,
format: 'A4',
margin: '1.5cm',
}),
});
const pdfData = await response.arrayBuffer();
fs.writeFileSync('invoice.pdf', Buffer.from(pdfData));
Python example:
import requests, os
response = requests.post(
'https://pagebolt.dev/api/v1/pdf',
headers={
'x-api-key': os.environ['PAGEBOLT_API_KEY'],
'Content-Type': 'application/json',
},
json={
'html': '''
<html>
<head><style>
body { font-family: Arial; margin: 40px; }
.header { font-size: 24px; font-weight: bold; margin-bottom: 20px; }
.line-item { display: flex; justify-content: space-between; margin: 10px 0; }
.total { font-weight: bold; border-top: 1px solid #ccc; margin-top: 20px; padding-top: 10px; }
</style></head>
<body>
<div class="header">Invoice #INV-2026-001</div>
<div class="line-item"><span>Product A</span><span>$50.00</span></div>
<div class="line-item"><span>Product B</span><span>$30.00</span></div>
<div class="total">Total: $80.00</div>
</body>
</html>
''',
'format': 'A4',
'margin': '1.5cm',
}
)
with open('invoice.pdf', 'wb') as f:
f.write(response.content)
Both examples generate a professional invoice PDF in under 1 second, with no local browser or dependencies.
Adding Headers, Footers, and Page Numbers
Common requirement: page numbers and a footer on every page.
curl -X POST https://pagebolt.dev/api/v1/pdf \
-H "x-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/report",
"format": "A4",
"displayHeaderFooter": true,
"headerTemplate": "<div style=\"font-size:12px;text-align:center;width:100%\">Confidential Report</div>",
"footerTemplate": "<div style=\"font-size:10px;text-align:center;width:100%;color:#666\">Page <span class=\"pageNumber\"></span> of <span class=\"totalPages\"></span></div>",
"margin": "1cm"
}' \
-o report.pdf
The pageNumber and totalPages placeholders are automatically replaced with the correct values.
Page Format Options
| Format | Dimensions | Use Case |
|---|---|---|
| A4 (default) | 210×297mm | Standard documents, invoices, reports |
| Letter | 8.5×11in | US documents, contracts, forms |
| Legal | 8.5×14in | Legal documents, extended letters |
| Tabloid | 11×17in | Large reports, posters |
| A3 | 297×420mm | Blueprints, large-format documents |
| A5 | 148×210mm | Small booklets, receipts |
Also supported: landscape mode ("landscape": true), custom margins ("margins": {"top": "1cm", "bottom": "2cm"}), and scale ("scale": 0.8 to shrink or enlarge content, range 0.1–2.0).
Batch PDF Generation in CI/CD
Your SaaS generates monthly invoices for 1,000 customers. You need to create PDFs, store them, and email them out.
#!/bin/bash
# Generate invoices for all customers
for customer_id in $(get_customer_ids); do
curl -X POST https://pagebolt.dev/api/v1/pdf \
-H "x-api-key: $PAGEBOLT_API_KEY" \
-H "Content-Type: application/json" \
-d "{
\"url\": \"https://my-saas.com/invoice/$customer_id\",
\"format\": \"A4\",
\"margin\": \"1cm\",
\"displayHeaderFooter\": true,
\"footerTemplate\": \"<div style='font-size:10px;text-align:center;width:100%'>Invoice Generated $(date +%Y-%m-%d)</div>\"
}" \
-o "invoices/invoice-$customer_id.pdf"
done
Cost analysis: 1,000 invoices × 1 request each = 1,000 API calls/month ≈ $10–20 at PageBolt's plans. Compare to running Puppeteer: 1,000 browser instances × 300MB = 300GB of infrastructure plus CPU/memory for concurrency = $500+/month.
Puppeteer vs PageBolt for PDF Generation
| Scenario | PageBolt | Puppeteer |
|---|---|---|
| Simple URL-to-PDF | ✓ | |
| HTML string-to-PDF | ✓ | ✓ |
| Batch PDF generation | ✓ | |
| Complex page interactions before PDF | ✓ | |
| Running locally during development | ✓ | |
| Serverless/FaaS (Lambda, Vercel) | ✓ | |
| No dependency management | ✓ | |
| Cost-effective at scale | ✓ |
PageBolt wins when you need: API-first PDF generation, serverless compatibility, no infrastructure, and cost efficiency.
Puppeteer wins when you need: Complex interactions (login, form fill, dynamic rendering), local debugging, and full browser control.
Getting Started
- Sign up — Free tier: 100 requests/month, no credit card required
- Get your API key — Available immediately from the dashboard
- Make your first PDF — Copy the curl examples above and try them
- Integrate into your app — Use the JavaScript or Python examples to generate PDFs on-demand
- Monitor usage — Check your API usage in the dashboard; upgrade if needed
PDF generation doesn't require you to manage Chromium. Try PageBolt free — 100 requests/month, no credit card.
Generate PDFs from HTML without managing a browser — free
100 requests/month, no credit card. URL or HTML to PDF in one API call, no Chromium required.
Get API key free →