API Reference¶
Render a PDF — POST /v1/render¶
Renders an HTML document to PDF and returns the PDF bytes directly in the response body.
Request¶
Content-Type: application/json. The body has the following shape:
{
"html": "<html><body><h1>Invoice #1024</h1></body></html>",
"output": "pdf",
"options": {
"format": "A4",
"landscape": false,
"printBackground": true,
"scale": 1.0,
"margin": { "top": "20mm", "bottom": "20mm", "left": "15mm", "right": "15mm" },
"width": "210mm",
"height": "297mm"
}
}
| Field | Type | Required | Notes |
|---|---|---|---|
html |
string | Yes | The HTML document to render. Must be non-empty and at most 10 MB. |
output |
string | No | Output format. Only "pdf" is supported; may be omitted. |
options |
object | No | Rendering options (see Options reference). All fields optional. |
The request schema is strict. Unknown fields are rejected with an
INVALID_REQUESTerror. Send only the fields documented here.
Response¶
On success (200 OK), the response body is the raw PDF with these headers:
| Header | Description |
|---|---|
Content-Type |
application/pdf |
Content-Length |
Size of the PDF in bytes |
X-Render-ID |
Unique ID for this render (useful for support/debugging) |
The PDF is returned inline — there is no separate "fetch the file" step and no JSON envelope around it.
Example — minimal¶
curl -X POST https://api.zindle.com.au/v1/render \
-H "Authorization: Bearer $ZINDLE_KEY" \
-H "Content-Type: application/json" \
-d '{"html": "<h1>Hello</h1>"}' \
--output out.pdf
Example — with options (Node.js)¶
import fs from "node:fs";
const res = await fetch("https://api.zindle.com.au/v1/render", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.ZINDLE_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
html: "<h1>Invoice</h1><p>Thank you for your business.</p>",
options: {
format: "A4",
printBackground: true,
margin: { top: "20mm", bottom: "20mm", left: "15mm", right: "15mm" },
},
}),
});
if (!res.ok) {
const err = await res.json();
throw new Error(`Render failed (${res.status}): ${err.error?.code} — ${err.error?.message}`);
}
const pdf = Buffer.from(await res.arrayBuffer());
fs.writeFileSync("invoice.pdf", pdf);
Example — with options (Python)¶
import os
import requests
resp = requests.post(
"https://api.zindle.com.au/v1/render",
headers={"Authorization": f"Bearer {os.environ['ZINDLE_KEY']}"},
json={
"html": "<h1>Report</h1>",
"options": {"format": "Letter", "landscape": True, "scale": 0.9},
},
)
if resp.status_code != 200:
raise RuntimeError(f"Render failed ({resp.status_code}): {resp.json()}")
with open("report.pdf", "wb") as f:
f.write(resp.content)
Options reference¶
All options live under the options object and are optional. Anything you omit uses the default.
| Option | Type | Default | Allowed values |
|---|---|---|---|
format |
string | A4 |
A4, A3, A5, Letter, Legal, Tabloid |
landscape |
boolean | false |
true / false |
printBackground |
boolean | false |
true / false — render background colours/images |
scale |
number | 1.0 |
Between 0.1 and 2.0 |
margin.top |
string | none | A dimension (see below) |
margin.bottom |
string | none | A dimension |
margin.left |
string | none | A dimension |
margin.right |
string | none | A dimension |
width |
string | none | A dimension — custom page width (overrides format) |
height |
string | none | A dimension — custom page height (overrides format) |
Dimensions (margin.*, width, height) must be a number followed by a unit: mm, cm, in, or px. Examples: 20mm, 1in, 2.5cm, 800px. Values without a valid unit are rejected.
Notes:
scaleoutside0.1–2.0is rejected.- If you set
widthandheight, they define the page size directly;formatis the simpler choice for standard paper sizes.