Any event → the PDF, without a browser in your infrastructure
Your Puppeteer service breaks on a Chrome update, and one render blocks a worker for nine seconds.
Trigger → artefact
Your app needs a documentthe PDF, from an HTTP call instead of a browser you operate
Nobody chose to run a headless Chrome fleet. It arrived because a PDF was needed on a Thursday, and it stayed. Now it is a container that is 400MB, a font that is missing only in production, a memory leak that is really a page you forgot to close, and a Chrome release that changes how one CSS property paginates.
The HTML and CSS you already wrote is the part worth keeping. Paste it into the HTML editor, declare the fields, and it becomes an endpoint. What you stop owning is the browser: the patching, the concurrency limit, and the nine seconds of a worker that a synchronous render costs you today.
Built with the HTML API. Need a designed image or certificate instead? Use the Canvas API — same data, same free year.

The whole integration
One call. Named fields. No SDK to install.
# your HTML template, already uploaded — now it is an endpoint
curl https://api.pixldocs.com/v1/render \
-H "Authorization: Bearer $PIXLDOCS_KEY" \
-H "Content-Type: application/json" \
-d '{
"template_id": "001eb79f-5fcc-4c5d-bb1e-3fe0b891097a",
"format": "pdf",
"data": {
"seller_name": "Northwind Cloud Ltd",
"buyer_name": "Acme Retail",
"invoice_no": "INV-2026-0441",
"invoice_date": "2026-07-31",
"currency_code": "USD",
"tax_label": "Sales tax"
}
}' --output invoice.pdf
# and the field names are yours, not our internal ids
curl https://api.pixldocs.com/v1/templates/001eb79f-5fcc-4c5d-bb1e-3fe0b891097a/fields \
-H "Authorization: Bearer $PIXLDOCS_KEY"Run against our API before publishing: 200, application/pdf, 54,787 bytes, 1.2s. No SDK, no npm install, no browser.
Measured, not estimated
- in your infrastructure
- nothing — one HTTPS call
- a single document
- ~1.2s, PDF bytes in the response
- text in the PDF
- real vector text, selectable and searchable
- at capacity
- 503 with Retry-After, never a hung socket
- measured at 50 concurrent
- 0 bare 5xx across the whole sweep
The failure mode is the part worth comparing. A Puppeteer box under load gives you timeouts and OOM kills; we return a documented, retryable status with a header telling you when to come back.
The contract
Exactly what you send, exactly what you get.
The tax invoice template takes these named keys. Nothing about layout, fonts or page breaks appears in your code.
Tax invoice
001eb79f-5fcc-4c5d-bb1e-3fe0b891097aFields · 20
Rows · line_items[]
description · item_code · qty · unit · rate · tax_rate
Send as many as you have. Pagination, running totals and the carried-forward header are the renderer's problem, not yours.
What you would ask next.
Will my CSS render identically?
It is the same engine class — Chromium — so page-break, flex and grid behave as you expect. Fonts are the usual difference: we ship a font set that covers Latin, Cyrillic, Greek, Arabic, Hebrew, Devanagari and CJK, and we verify coverage on every deploy, so the "missing glyph only in production" failure is one we test for rather than one you discover.
What about the things I do in JS before printing?
This is the honest weak spot. If your script clicks, waits on an XHR or drives a chart library before printing, that logic does not come across as-is — you would compute those values and send them as data. Templates are HTML plus Liquid, not a browser session you script.
How fast can I find out whether it works?
The block above runs right now with no account. Getting your own document to that state was measured end to end at 33 seconds from having a key.
Your system already knows when the document is owed.
Free to start · No credit card required