A few months ago I got tired of paying $29/month to a PDF SaaS for the ~3,000 invoices my side project actually rendered. The math was infuriating — I was paying about 10× the real cost per document because of how their tier pricing worked, and there was no way to scale linearly. So I built my own and it's been running in production for a few weeks. Today I shipped the official Python and Node.js clients. Here's what's under the hood.
What it is
HTML2DocHub is an HTML-to-PDF API with one rule: you pay only for pages you render. ₹0.08 per page (~$0.001), ₹0.10 minimum per completed job. No subscription. No tier to overshoot. Failed renders are free.
A 2-page invoice costs ~$0.002. A 40-page report costs ~$0.04. The wallet ledger shows every charge with the job ID, so you can cross-reference with your own logs. That's the whole pitch — the why we show a clear total post has the longer version.
The stack, briefly
Boring tech, well-glued. FastAPI for the API, Playwright + Chromium for the rendering, Postgres for state, S3 for the rendered files. The interesting decisions are at the policy layer (per-page billing, idempotency, transparent fees), not the infra layer — and that's deliberate.
What shipped today
Two SDKs, both MIT-licensed.
Python — pip install html2dochub
from html2dochub import Client
pdf = Client(api_key="sk_live_...").render(
html="<h1>Hello</h1>",
options={"format": "A4"},
)
Both Client (sync) and AsyncClient (asyncio) with the same surface. Automatic retries on 429 and 5xx with exponential backoff. Typed exception hierarchy (AuthenticationError, RateLimitError with retry_after, InsufficientFundsError, ValidationError, APIError). Idempotency keys on every render. Python 3.9+. One dependency: httpx.
See the Python landing page for framework-specific examples (FastAPI, Django, Celery).
Node.js / TypeScript — npm install @html2dochub/client
import { Client } from "@html2dochub/client";
const pdf = await new Client({ apiKey: "sk_live_..." }).render({
html: "<h1>Hello</h1>",
options: { format: "A4" },
});
Zero runtime dependencies — uses native Node 18+ fetch. Dual ESM + CJS build (~14.8 KB packed). Full TypeScript declarations. Works on Vercel, Lambda, Cloud Run, Cloudflare Workers — anywhere you can make an HTTPS call.
See the Node.js landing page for Express, Next.js App Router, and BullMQ worker examples.
Three things I've learned running it
- Per-page billing changes user behaviour. With subscriptions, customers obsessively monitor whether they're "getting their money's worth." With pay-per-use, they just render PDFs. Two of my early users went from generating receipts only on demand to generating one for every transaction, because the cost was visible and small.
- Idempotency keys are non-negotiable for B2B. Every customer running renders inside a queue (BullMQ, Celery, Sidekiq) has at-least-once semantics. Without idempotency keys,retries double-bill. With them, retries are free. Both SDKs ship this from v0.1.0.
- Chromium beats every other engine I tried. I tested WeasyPrint, wkhtmltopdf, and PrinceXML before settling on Playwright + Chromium. Modern CSS — flexbox gaps, grid, custom properties, web fonts, dark mode — just works. The other engines need workarounds for things that have been standard CSS for 5+ years.
Things I deliberately did not build
- A free public playground. The dashboard already has one for signed-in users. A public version with rate limits sounds nice but gets abused via IP rotation.
- Analytics on the marketing site. The privacy policy promises no third-party analytics or fingerprinting. I use Search Console for traffic data and PostHog only on the authenticated dashboard.
-
Native binary distribution. Both SDKs are pure language wrappers around HTTPS. No Chromium in your
node_modules. No 200 MB Lambda layer. No ARM/x86 binary builds to maintain.
What's next
- Stripe + USD pricing (international launch)
- More SDKs (Go, Ruby, PHP) once there's measurable demand
- An MCP server so AI coding tools can call the API directly
If you have a backend somewhere that generates PDFs, you can probably swap your existing library for HTML2DocHub in 30 minutes. The PDFShift migration guide walks through the API differences if you're coming from there specifically.
New accounts get a starter credit (about 100 pages worth) — no card required. Try it, and if you hit a rough edge, email me at hello@html2dochub.com. Solo dev, real responses.
Top comments (1)
Curious - what HTML-to-PDF tool is your team using right now? Especially interested if you've hit pain points with existing options.