Developer API Docs
Programmatic HTML to PDF conversion. Free tier: 10 conversions. Premium: $5 AUD/year for unlimited.
Overview
The programmatic API converts HTML to PDF and returns hosted URLs to the generated files. It's designed for developers who need PDF generation embedded in their applications, scripts, or pipelines.
https://www.htmltopdfconverter.com.auBearer JWT (API key)
10 conversions, 1 API key
$5 AUD/year — unlimited
10 requests/minute per user
Free tier
Every new account includes 10 free API conversions and the ability to generate 1 API key — no payment required. This lets you evaluate the API in your own workflow before committing to a subscription.
| Free | Premium ($5 AUD/yr) | |
|---|---|---|
| API keys | 1 | Unlimited |
| Conversions | 10 total | Unlimited |
| Rate limit | 10 req/min | 10 req/min |
| Key generation | Dashboard or API | Dashboard or API |
Once you exhaust your free conversions, subscribe via the Dashboard to continue using the API.
Getting started
1. Sign up
Create a free account at htmltopdfconverter.com.au/auth/signup. You'll immediately receive 10 free API conversions.
Required: name, email, password (min 12 characters).
2. Generate an API key
You can generate a key in two ways:
- Dashboard: Click Generate New API Key on your Dashboard
- Programmatically:
POST /api/programmatic/api-key/generatewith your email and password (see below)
- Keys are valid for 7 days
- Free tier: 1 key. Premium: unlimited keys
- Old keys can be revoked from the Dashboard
Store your key securely. It cannot be retrieved after the page closes — if you lose it, generate a new one.
3. Convert HTML to PDF
Use your API key to call POST /api/programmatic/pdf/generate. See the endpoint docs and code examples below.
4. Upgrade to Premium (optional)
Once you've used your 10 free conversions, go to your Dashboard and click Subscribe Now. The annual plan is $5 AUD/year for unlimited conversions and unlimited API keys.
Authentication
All programmatic API requests require a valid API key passed as a Bearer token in the Authorization header:
Authorization: Bearer <your_api_key>Requests without this header, or with an expired or revoked key, return 401 Unauthorized.
POST /api/programmatic/api-key/generate
Generate an API key programmatically using your account credentials. This enables a fully scriptable two-step workflow: generate a key, then use it to convert PDFs.
Request
POST /api/programmatic/api-key/generate
Content-Type: application/json
{
"email": "you@example.com",
"password": "your_password"
}Response — 200 OK
{
"apiKey": "eyJhbGciOiJIUzI1NiIs...",
"expiresAt": "2026-03-15T12:00:00.000Z",
"expiresIn": "7 days",
"message": "JWT API key generated successfully"
}cURL example:
curl -X POST https://www.htmltopdfconverter.com.au/api/programmatic/api-key/generate \
-H "Content-Type: application/json" \
-d '{"email":"you@example.com","password":"your_password"}'| Status | Reason |
|---|---|
400 | Missing email or password |
401 | Invalid credentials |
403 | Free trial exhausted or free-tier key limit reached (1 key) |
500 | Internal server error |
POST /api/programmatic/pdf/generate
Converts one or more HTML files to PDF. Returns hosted URLs to the generated PDFs.
Option A — Multipart file upload
Send one or more .html or .htm files as multipart/form-data. Optionally include an options form field containing a JSON object to control the output (see PDF options).
POST /api/programmatic/pdf/generate
Authorization: Bearer <your_api_key>
Content-Type: multipart/form-data
files: invoice.html
files: report.html
options: {"format":"A4","orientation":"portrait","margins":"normal","scale":1}Constraints:
- Field name must be
files - HTML files only (
.html/.htm) - Maximum 10 files per request
- Maximum 50 MB per file
- The
optionsfield is optional; any omitted keys fall back to their defaults
cURL example:
curl -X POST https://www.htmltopdfconverter.com.au/api/programmatic/pdf/generate \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "files=@invoice.html" \
-F "files=@report.html" \
-F 'options={"format":"Letter","orientation":"landscape","margins":"wide","scale":1}'Option B — Raw HTML body
Send raw HTML as the request body with Content-Type: text/html. With this mode, pass output options as query-string parameters instead of a JSON field.
POST /api/programmatic/pdf/generate?format=Letter&orientation=landscape&margins=wide&scale=1
Authorization: Bearer <your_api_key>
Content-Type: text/html
<!DOCTYPE html>
<html><body><h1>Hello, PDF</h1></body></html>cURL example:
curl -X POST "https://www.htmltopdfconverter.com.au/api/programmatic/pdf/generate?format=Letter&orientation=landscape&margins=wide&scale=1" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: text/html" \
--data-binary @invoice.htmlPDF options
All options are optional. In multipart requests they go in the options JSON field; with a raw HTML body they go in the query string.
| Option | Values | Default |
|---|---|---|
format | A4 | Letter | Legal | A3 | A4 |
orientation | portrait | landscape | portrait |
margins | none (0) | tight (6mm) | normal (12mm) | wide (25mm) | normal (12mm) |
scale | 0.1 – 2 | 1 |
Responses
Success — 200 OK
{
"success": true,
"pdfs": [
{
"filename": "invoice_1234567890.pdf",
"url": "https://blob.vercel-storage.com/..."
},
{
"filename": "report_9876543210.pdf",
"url": "https://blob.vercel-storage.com/..."
}
]
}url points to the generated PDF hosted on Vercel Blob at an unguessable public URL. Download it promptly and store it in your own storage if you need long-term or guaranteed access — treat the returned URL as a delivery link rather than permanent hosting.
Error responses
| Status | Reason |
|---|---|
400 | Validation error — no files, empty HTML body, more than 10 files, a non-HTML file, or a file over 50 MB (message echoes the specific error) |
401 | Missing, invalid, expired or revoked API key; or subscription inactive and free trial exhausted |
403 | Free tier — requested more files than free conversions remaining |
415 | Unsupported Content-Type (must be multipart/form-data or text/html) |
429 | Rate limit exceeded (10 requests/minute) |
500 | Internal server error during PDF generation |
API key lifecycle
| Event | Detail |
|---|---|
| Generated | Via Dashboard or POST /api/programmatic/api-key/generate |
| Expiry | 7 days from creation (JWT exp claim) |
| Revocation | Delete from Dashboard at any time |
| Re-generation | Premium: generate unlimited keys. Free: 1 key at a time |
| Free tier limit | 10 total conversions; key still works until conversions are exhausted or key expires |
| Subscription lapse | Key validation fails when subscription becomes inactive and free conversions are exhausted |
PDF rendering details
| Property | Value |
|---|---|
| Engine | Puppeteer + Chromium |
| Page size | A4 (default), Letter, Legal or A3 — see PDF options |
| Orientation | Portrait (default) or landscape |
| Margins | none / tight / normal (default) / wide |
| Scale | 0.1–2 (default 1) |
| CSS support | Full — flexbox, grid, custom fonts, media queries, backgrounds |
| Images | Inline and base64 data URIs supported |
| JavaScript | Executed before capture — dynamic content renders |
Rate limits
- 10 requests/minute per user
- Limit is keyed to your user account, not IP address
- Exceeding the limit returns
429 Too Many Requests - The window resets every 60 seconds
Code examples
Two-step workflow (cURL)
Generate a key and convert a PDF in two commands — no browser needed.
# Step 1 — Generate an API key
API_KEY=$(curl -s -X POST https://www.htmltopdfconverter.com.au/api/programmatic/api-key/generate \
-H "Content-Type: application/json" \
-d '{"email":"you@example.com","password":"your_password"}' \
| jq -r '.apiKey')
# Step 2 — Convert HTML to PDF (with optional output options)
curl -X POST https://www.htmltopdfconverter.com.au/api/programmatic/pdf/generate \
-H "Authorization: Bearer $API_KEY" \
-F "files=@invoice.html" \
-F 'options={"format":"A4","orientation":"portrait","margins":"normal","scale":1}'Node.js (fetch)
Uses the native FormData and Blob globals available in Node 18+. Do not set Content-Type yourself — fetch adds the multipart boundary automatically.
const fs = require("fs/promises");
const html = await fs.readFile("invoice.html", "utf8");
const form = new FormData();
form.append("files", new Blob([html], { type: "text/html" }), "invoice.html");
// Optional: control the output. Omit to use defaults (A4, portrait, normal, scale 1).
form.append(
"options",
JSON.stringify({
format: "A4",
orientation: "portrait",
margins: "normal",
scale: 1,
})
);
const response = await fetch(
"https://www.htmltopdfconverter.com.au/api/programmatic/pdf/generate",
{
method: "POST",
headers: {
Authorization: "Bearer YOUR_API_KEY",
},
body: form,
}
);
const { pdfs } = await response.json();
console.log(pdfs[0].url); // publicly accessible PDF URLPython (requests)
import json
import requests
with open("invoice.html", "rb") as f:
response = requests.post(
"https://www.htmltopdfconverter.com.au/api/programmatic/pdf/generate",
headers={"Authorization": "Bearer YOUR_API_KEY"},
files={"files": ("invoice.html", f, "text/html")},
# Optional output options (omit to use defaults)
data={"options": json.dumps({
"format": "A4",
"orientation": "portrait",
"margins": "normal",
"scale": 1,
})},
)
data = response.json()
print(data["pdfs"][0]["url"])PHP (cURL)
<?php
$ch = curl_init("https://www.htmltopdfconverter.com.au/api/programmatic/pdf/generate");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Authorization: Bearer YOUR_API_KEY"]);
curl_setopt($ch, CURLOPT_POSTFIELDS, [
"files" => new CURLFile("invoice.html"),
// Optional output options (omit to use defaults)
"options" => json_encode([
"format" => "A4",
"orientation" => "portrait",
"margins" => "normal",
"scale" => 1,
]),
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
echo $response["pdfs"][0]["url"];Ready to start?
Try 10 free conversions — no credit card required. Then $5 AUD/year for unlimited.