惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

WordPress大学
WordPress大学
Vercel News
Vercel News
博客园_首页
Y
Y Combinator Blog
美团技术团队
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
阮一峰的网络日志
阮一峰的网络日志
aimingoo的专栏
aimingoo的专栏
H
Hackread – Cybersecurity News, Data Breaches, AI and More
MyScale Blog
MyScale Blog
GbyAI
GbyAI
人人都是产品经理
人人都是产品经理
T
Tailwind CSS Blog
MongoDB | Blog
MongoDB | Blog
D
DataBreaches.Net
博客园 - Franky
Engineering at Meta
Engineering at Meta
量子位
The GitHub Blog
The GitHub Blog
F
Fortinet All Blogs
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
酷 壳 – CoolShell
酷 壳 – CoolShell
N
Netflix TechBlog - Medium

DEV Community

Authentication Security Deep Dive: From Brute Force to Salted Hashing (With Java Examples) Why AI Systems Don’t Fail — They Drift Spilling beans for how i learn for exam😁"Reinforcement Learning Cheat Sheet" I Replaced Chrome with Safari for AI Browser Automation. Here's What Broke (and What Finally Worked) How Python Borrows Other People's Work The $40 Architecture: Processing 1 Billion API Requests with 99.99% Uptime Vibe Coding: A Workflow Guide (From Zero to SaaS) Most webhook security guides protect the wrong side. The scary part is delivery. Headless CMS for TanStack Start: Build a Blog with Cosmic EU Age Verification App "Hacked in 2 Minutes" — What Actually Happened Comfy Cloud’s delete function does not actually remove files Running AI Models on GPU Cloud Servers: A Beginner Guide Event-driven media intelligence with AWS Step Functions and Bedrock I scored 500 AI prompts across 8 quality dimensions — here's what broke How to Call Google Gemini API from Next.js (Free Tier, No Backend Needed) The Portal Protocol: Reclaiming Human Connection in the Age of AI How to Fix Your Team's Scattered Knowledge Problem With a Self-Hosted Forum Intro to tc Cloud Functors: A Graph-First Mental Model for the Modern Cloud Designing Multi-Tenant Backends With Both Ownership and Team Access I Built a Neumorphic CSS Library with 77+ Components — Here's What I Learned PostgreSQL Performance Optimization: Why Connection Pooling Is Critical at Scale Cómo construí un SaaS multi-rubro para gestionar expensas en Argentina con FastAPI + Vue 3 🚀 I Built an Ethical Hacking Scanner Tool – Open Source Project I Replaced /usage and /context in Claude Code With a Single Statusline A Pythonic Way to Handle Emails (IMAP/SMTP) with Auto-Discovery and AI-Ready Design I Collected 8.9 Million Polymarket Price Points — Here's What I Found About How Markets Really Move EcoTrack AI — Carbon Footprint Tracker & Dashboard Everyone's Using AI. No One Agrees How. 5 self-hosted ebook managers worth trying in 2026 Building Your First AI Agent with LangChain: From Chatbot to Autonomous Assistant
Generate invoice PDFs from JSON in one API call — no head...
TonyWang wa · 2026-06-22 · via DEV Community
Cover image for Generate invoice PDFs from JSON in one API call — no headless Chrome to babysit

TonyWang wa

Every billing feature eventually hits the same wall: "now turn this order into a PDF the customer can download."

The usual options all have a tax:

  • Headless Chrome / Puppeteer — you now run and patch a browser in production. Memory spikes, zombie processes, font issues in Docker.
  • wkhtmltopdf — unmaintained, CSS from 2015.
  • A LaTeX/HTML template engine — you own the templates, the rendering, and every edge case forever.

For a feature that's supposed to be a side-quest, that's a lot of infrastructure.

I got tired of re-solving this on every project, so I built DocForge — a stateless HTTP API. You POST structured JSON, you get back PDF bytes. That's the whole integration.

The one call

import requests

resp = requests.post(
    "https://pdf44.p.rapidapi.com/v1/documents/invoice",
    headers={
        "content-type": "application/json",
        "X-RapidAPI-Key": "YOUR_RAPIDAPI_KEY",
        "X-RapidAPI-Host": "pdf44.p.rapidapi.com",
    },
    json={
        "invoice_number": "2026-0001",
        "issue_date": "2026-06-17",
        "currency": "USD",
        "seller": {"name": "Rapid Labs", "email": "billing@rapidlabs.dev"},
        "client": {"name": "Acme Inc."},
        "items": [
            {"description": "Pro plan (annual)", "quantity": 1, "unit_price": 590.0},
            {"description": "Onboarding", "quantity": 2, "unit_price": 75.0},
        ],
        "tax_rate": 8.5,
    },
)
resp.raise_for_status()
open("invoice.pdf", "wb").write(resp.content)

That's it. No browser in your container, no template to host. The response is application/pdf bytes — stream it to the user, drop it in S3, or attach it to an email.

Node, same idea

import { writeFileSync } from "node:fs";

const res = await fetch("https://pdf44.p.rapidapi.com/v1/documents/invoice", {
  method: "POST",
  headers: {
    "content-type": "application/json",
    "X-RapidAPI-Key": process.env.RAPIDAPI_KEY,
    "X-RapidAPI-Host": "pdf44.p.rapidapi.com",
  },
  body: JSON.stringify({
    invoice_number: "2026-0001",
    issue_date: "2026-06-17",
    currency: "USD",
    seller: { name: "Rapid Labs" },
    client: { name: "Acme Inc." },
    items: [{ description: "Pro plan", quantity: 1, unit_price: 59 }],
  }),
});
writeFileSync("invoice.pdf", Buffer.from(await res.arrayBuffer()));

It's not just invoices

Same JSON-in / PDF-out shape, six document types:

Endpoint What you get
/v1/documents/invoice Line items, tax, discount, multi-currency
/v1/documents/receipt Compact, store-branded
/v1/documents/quote Estimates with validity dates
/v1/documents/packing-slip Fulfilment doc, no prices
/v1/documents/certificate Landscape, framed, signature lines
/v1/render/html Bring your own HTML → PDF

Currency formatting (USD, EUR, GBP, CNY, JPY) is built in, so you're not hand-rolling Intl.NumberFormat edge cases.

Why stateless matters

DocForge never stores your data — the request comes in, the PDF goes out, nothing is persisted. That means no data-retention policy to write, nothing to leak, and it scales horizontally by just running more containers. Under the hood it's Chromium for pixel-stable rendering, but you never have to operate that.

Try it

It's on RapidAPI with a free tier (50 PDFs/month) to kick the tires, and a paid plan when you need volume:

👉 https://rapidapi.com/tonypfwang-addP08RhJS3/api/pdf44

If you've been putting off the "generate the PDF" ticket, this is the version where it takes 15 minutes instead of a sprint. Happy to answer questions in the comments — what document type would you want next?