Turn HTML into
pixel-perfect PDFs
One API call. Send HTML, a URL, or a React template — get back a perfect PDF.
$ curl -X POST https://api.pdfrelay.com/v1/convert \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{"source": "html", "content": "<h1>Invoice #1042</h1>"}' \
-o invoice.pdf
# invoice.pdf saved — 1 page, 29 msOne request. One PDF. 29 ms average.
< 100 ms
Typical conversion time
~12 MB
Engine memory usage
Batch
Multi-document endpoint
38x
Faster than Puppeteer
One endpoint. Any language.
Send HTML or a URL, get a PDF back. Works with any language — Node.js, Python, Ruby, Go, or a simple curl command. You'll be up and running in minutes.
- Pass an HTML string or any public URL
- Get back PDF bytes or a JSON response with a download link
- Full CSS support — Flexbox, Grid, print stylesheets all work
- Free test mode — unlimited watermarked PDFs while you build
{
"id": "conv_r8Kx2mNpQw",
"status": "completed",
"document_id": "doc_4f7a1b2c",
"page_count": 1,
"duration_ms": 94,
"download_url": "/v1/documents/doc_4f7a1b2c/download"
}Generate hundreds of PDFs in one request
Need to send 500 invoices at month-end? Submit them all in a single API call. We handle the queue — you just check back when they're done.
- Mix HTML pages and URLs in the same batch
- One status URL to track the whole batch
- Individual status for each document if anything fails
- Higher tiers get priority processing
{
"items": [
{ "source": "html", "content": "<h1>Invoice #1042</h1>..." },
{ "source": "html", "content": "<h1>Invoice #1043</h1>..." },
{ "source": "url", "url": "https://app.co/report/q4" }
]
}{
"batch_id": "batch_3pXn9kL",
"total": 3,
"status": "processing",
"poll_url": "/v1/batch/batch_3pXn9kL"
}Get notified the instant a PDF is ready
Give us a URL and we'll ping it whenever a PDF is generated or something goes wrong. No polling loops, no wasted requests. Failed deliveries are retried automatically.
- Events for completed, failed, and created documents
- Every webhook is signed so you can verify it came from us
- Automatic retries with backoff if your server is down
- Full delivery logs in the dashboard
{
"event": "conversion.completed",
"conversion_id": "conv_r8Kx2mNpQw",
"data": {
"status": "completed",
"document_id": "doc_4f7a1b2c",
"page_count": 3,
"duration_ms": 210
}
}Signature verification
X-PdfRelay-Signature: sha256=a1b2c3d4e5...
Host and share PDFs with a single link
Every PDF you create can be hosted on pdfRelay with its own private URL. Set it to expire, limit downloads, or require a password. Perfect for sending invoices, reports, or contracts.
- Private, unguessable links — no login needed to download
- Limit how many times a document can be downloaded
- Links expire automatically after a time you choose
- Optional password protection for sensitive documents
{
"source": "html",
"content": "<h1>Quarterly Report</h1>...",
"hosting": {
"enabled": true,
"download_limit": 25,
"expires_in": 2592000,
"password": "board-only"
}
}{
"document_id": "doc_9a3bc1e5",
"hosted_url": "https://pdfrelay.com/d/d_a8Kx2mNpQw",
"expires_at": "2026-04-21T00:00:00Z",
"download_limit": 25,
"has_password": true
}React components in. PDFs out.
Stop gluing HTML strings together in your backend. Design your PDF layout as a React component, then generate documents by passing in your data as JSON. Change the design anytime — no code deploy required.
export default function Invoice(props) {
const { company, client, items, total } = props;
return (
<div style={{ fontFamily: "sans-serif", padding: 40 }}>
<h1>{company.name}</h1>
<p>Bill to: {client.name}</p>
<table style={{ width: "100%" }}>
<tbody>
{items.map((item, i) => (
<tr key={i}>
<td>{item.description}</td>
<td style={{ textAlign: "right" }}>
{item.qty}
</td>
<td style={{ fontWeight: 500 }}>
${(item.qty * item.price).toFixed(2)}
</td>
</tr>
))}
</tbody>
</table>
<p style={{ fontSize: 20, fontWeight: "bold" }}>
Total: ${total.toFixed(2)}
</p>
</div>
);
}{
"company": { "name": "Acme Corp" },
"client": { "name": "Jane Smith" },
"items": [
{ "description": "Web Design", "qty": 1, "price": 2500.00 },
{ "description": "Hosting (Annual)", "qty": 1, "price": 199.99 },
{ "description": "SSL Certificate", "qty": 2, "price": 49.99 }
],
"total": 2799.97
}{
"id": "conv_kP3xNqWm",
"status": "completed",
"document_id": "doc_8c2ef1a3",
"page_count": 1,
"duration_ms": 29,
"template": "monthly-invoice",
"template_version": 3
}Real React components
Use props, loops, conditionals, and helper functions — if you know React, you already know how to build templates.
Built-in visual editor
Write your template, add sample data, and preview the result live — all from the dashboard.
Compose into one PDF
Combine multiple templates and raw HTML into a single document with one API call.
Update without deploying
Fix a typo, tweak the layout, add a field — your changes apply to the next render immediately.
Multiple templates.
One PDF.
Build complex documents by combining templates and raw HTML in a single API call. Each part renders independently, then gets stitched together with automatic page breaks.
Mix templates and HTML
Use saved templates for structured sections and inline HTML for one-off content — all in the same request.
One conversion, one PDF
Composing 10 parts counts as a single conversion. No need to generate and merge separate files.
Automatic page breaks
Each part starts on a fresh page. Cover page, body, appendix — cleanly separated.
{
"parts": [
{
"template": "cover-page",
"data": { "title": "Q1 Report", "date": "March 2026" }
},
{
"template": "financials",
"data": { "revenue": 128500, "expenses": 84200 }
},
{
"html": "<div style=\"text-align: center; padding: 60px\"><p style=\"color: #666\">Confidential — Internal Use Only</p></div>"
},
{
"template": "appendix",
"data": { "notes": ["Audit pending", "Q2 forecast TBD"] }
}
],
"options": { "page_size": "A4" }
}{
"id": "conv_mR9xLwQp",
"status": "completed",
"document_id": "doc_4f7ab2c1",
"page_count": 4,
"duration_ms": 87,
"parts_count": 4
}Built on a native Rust engine, not a browser
Most PDF services spin up a full Chrome browser for every document. That's slow, memory-hungry, and unpredictable. pdfRelay uses a purpose-built Rust engine that converts HTML/CSS to PDF directly — faster, lighter, and consistent every time.
Browser-based engines
Puppeteer, Playwright, wkhtmltopdf
Heavy and slow
Each PDF requires a 200–500 MB browser process. That limits how many documents you can generate at once.
Inconsistent output
Fonts and timing vary between runs, so the same HTML can produce slightly different PDFs each time.
Slow to start
Booting a browser adds up to 2 seconds of latency. Under heavy load, requests start queuing up or timing out.
Large security footprint
A full browser can execute JavaScript, access the network, and read files — all of which need careful sandboxing.
pdfRelay's Rust engine
Purpose-built for PDF generation
38x faster than Puppeteer
29 ms per document vs 1,109 ms with Chromium. Benchmarked across 400+ real-world test fixtures.
Pixel-perfect consistency
Same input, same output, every time. No font surprises, no timing quirks. Your PDFs look identical across every render.
No cold starts
No browser to boot. The engine is ready in milliseconds and stays fast even under heavy load.
Secure by design
No JavaScript execution, no network access, no file system. Just HTML and CSS in, PDF out — built in memory-safe Rust.
29 ms
Avg render time
38x
Faster than Puppeteer
0
Browser dependencies
1 call
HTML in, PDF out
Everything you need, nothing you don't
Page layout, encryption, accessibility, and more — all configurable per request.
Custom Headers & Footers
Add HTML headers and footers to every page — with page numbers, dates, and your document title built in.
Page Size & Layout
A4, Letter, Legal, Tabloid, or any custom width/height. Portrait or landscape. Independent margin control per side.
PDF Encryption
Lock PDFs with passwords and control who can print, copy, or edit. AES-256 encryption keeps your documents secure.
Full CSS Support
Flexbox, Grid, print media queries, page breaks — your existing stylesheets just work.
PDF/UA & Tagged PDFs
Generate accessible, tagged PDFs that work with screen readers. Structure is derived automatically from your HTML.
PDF/A Archival
Create archival-grade PDFs for long-term storage. Fonts are embedded and metadata is preserved automatically.
Test Mode
Unlimited watermarked test PDFs on every plan. Build and test without worrying about your quota.
Structured Error Reporting
Clear error messages that tell you exactly what went wrong and how to fix it. No more guessing.
Priority Queuing
Higher plans get faster processing. Your most important jobs jump to the front of the queue.
Raw Binary or JSON
Get the PDF file directly as a download, or get a JSON response with metadata and a download link. Your choice.
URL-to-PDF
Pass any public URL and get a PDF back. Great for capturing dashboards, reports, or any live web page.
Async + Sync Modes
Simple documents return instantly. Longer jobs run in the background and notify you when they're done.
Up and running in three steps
Create an API key
Sign up for free and generate your first API key from the dashboard. Test keys are unlimited.
sk_test_eb1d75fab9a4beb0...Send your HTML
POST your HTML content or a URL to /v1/convert. Add options for page size, margins, headers, and more.
POST /v1/convertGet your PDF
Receive the PDF inline, as a download URL, or host it on pdfRelay with access controls.
invoice.pdf — 29 msStart generating PDFs in minutes
Free tier with 10 conversions per month. No credit card required. Upgrade when you're ready.