close

DEV Community

Jack
Jack

Posted on

How I Built a PDF Invoice Generation API (and What I Learned About PDF Rendering)

PDF generation is one of those problem spaces where the tooling is surprisingly rough for how common the use case is. I built DocuMint — a REST API for generating PDF invoices — partly out of frustration and partly because I kept solving the same problem across different projects.

The Problem

Generating a PDF invoice sounds trivial. It's not.

If you've tried to do it in production, you've probably hit:

  • PDF library hell: jsPDF, PDFKit, ReportLab, WeasyPrint, iText — each with different coordinate systems, different layout models, and different bugs
  • Headless browser approaches: Puppeteer or wkhtmltopdf generating PDFs from HTML, which works until it doesn't — broken fonts in Docker, inconsistent page breaks, slow cold starts
  • Page break logic: What happens when someone has 40 line items? Does your library handle that, or do you?
  • Currency formatting: This one alone has eaten hours of my life

What DocuMint Does

DocuMint is a REST API. You POST a JSON payload, you get a PDF back.

curl -X POST https://documint.anethoth.com/api/v1/invoices \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d @invoice.json \
  --output invoice.pdf
Enter fullscreen mode Exit fullscreen mode

It now comes with 3 professional templates: classic, modern, and minimal. You choose via a template field in your JSON payload.

The Hard Parts

Currency Formatting

More complex than expected. The formatting rules differ by locale:

  • US: $1,234.56
  • Germany: €1.234,56
  • Japan: ¥1,234 (no decimals)
  • Switzerland: CHF 1'234.56

I ended up implementing locale-aware formatting and testing against a matrix of currencies × locales.

Page Break Logic

Long invoices need correct pagination. I implemented a pre-calculation pass that measures expected height of each element before rendering, then plans the page layout before committing to the PDF.

Custom Logos

Accepting logo URLs means fetching external images at generation time. Added URL validation, short fetch timeout with fallback to no-logo, and a blocklist for private IP ranges to prevent SSRF.

Try It

DocuMint is live at documint.anethoth.com. Free tier: 10 invoices/month, no credit card. Live demo on the site.

Feedback welcome — especially if you've solved PDF generation differently.

Top comments (0)