blueport Integration guide · v1 · Sep 2026
Integration guide

HTML2PDF

HTML in. Pixel-perfect PDF out.

One endpoint renders your HTML and CSS into a print-ready PDF through a real browser engine. Three flavours, one integration: raw HTML, inline template + data, or a stored template you manage through the API.

Endpoint

POST https://api.blueport.io/v1/html2pdf
alias: pdf.blueport.io/html2pdf auth: x-api-key header max 2 MB per request typical render 2–5 s 1 render = one PDF, up to 20 pages merge language: Handlebars

Authentication

The same organisation key as PDF2JSON, in the x-api-key header — one key covers both products. Owners and admins view (masked) and rotate it at app.blueport.io. Keep it server-side; never ship it in a browser or mobile app.

Three flavours, one endpoint

1. Static HTML — send the markup raw, get the PDF back in the response body:

curl -X POST https://api.blueport.io/v1/html2pdf \
  -H "x-api-key: YOUR_API_KEY" \
  -H "content-type: text/html" \
  --data-binary @invoice.html --output invoice.pdf

2. Inline template + data — Handlebars fields merged in the same call:

{
  "html": "<h1>{{supplier.name}}</h1><p>Total {{formatCurrency totals.total \"AUD\"}}</p>",
  "data": { "supplier": { "name": "Coastline Powersports" }, "totals": { "total": 508.48 } },
  "options": { "size": "A4", "footer": "Page {{page}} of {{pages}}" }
}

3. Stored template + data — the production pattern. Store the template once, then every render is just data. Graduating from flavour 2 is a one-field change: replace html with template_id.

{
  "template_id": "tpl_9f2c41ab",
  "data": { "customer": { "name": "Jordan Avery" },  },
  "options": { "filename": "invoice-20841.pdf" }
}
Exactly one of html or template_id per request. data is optional — without it the template renders as-is. Merge language is Handlebars: {{field}}, {{#each}}, {{#if}}, plus two helpers: formatCurrency and formatDate.

Managing templates

CallDoes
POST /v1/html2pdf/templatesCreate — {"name", "html"}tpl_… (max 512 KB, 100 templates)
GET /v1/html2pdf/templatesList your templates
GET /v1/html2pdf/templates/{id}Fetch — ?version=n for an older version
PUT /v1/html2pdf/templates/{id}Update — a changed html creates a new version; renders pinned to old versions keep working
DELETE /v1/html2pdf/templates/{id}Retire (soft — history survives)
POST /v1/html2pdf/templates/{id}/previewRender with sample data — free, bills nothing

Renders use the latest version unless the request pins template_version. Template management is free — only renders count against your plan.

Options

OptionValues
size"A4" (default), A3, A5, Letter, Legal, Tabloid, or {"width":"210mm","height":"99mm"}
marginOne value for all sides ("14mm") or {top, right, bottom, left}
landscapetrue / false (default)
header / footerPlain HTML; {{page}} and {{pages}} become live page numbers
printBackgroundtrue (default) — CSS backgrounds print
filenameSets the download filename in the response headers
outputOmit for binary PDF; "base64" for the JSON envelope (Salesforce-friendly)

Response

By default the PDF itself streams back — content-type: application/pdf with x-request-id, x-pages and x-billed-units headers. With output: "base64" you get the standard envelope instead:

{
  "ok": true,
  "data": { "pdf": "JVBERi0xLjc…", "pages": 2, "filename": "invoice-20841.pdf" },
  "meta": { "request_id": "req_a1b2c3", "duration_ms": 3200, "pages": 2, "billed_units": 1 }
}

Errors

StatusMeaningWhat to do
401Missing or invalid API keyCheck the header; confirm the key wasn't rotated
400Bad input / template merge failedThe error message names the field or the Handlebars problem
404No such template (or version)List your templates; deleted templates fail loudly by design
413Request over 2 MB / template over 512 KBHost large images by URL instead of inlining them
500Render failedRetry once; persistent failures → support with the request_id

Good to know

Metering: one render = one PDF of up to 20 pages; longer documents count one render per started block of 20. The exact charge comes back as x-billed-units / meta.billed_units. Failed renders and previews bill nothing.
Fonts & assets: link web fonts and images by URL exactly as a browser would load them — the renderer fetches them during the render.
Privacy: stored templates are your saved assets; data payloads and rendered PDFs are never stored — only usage counts and timings are recorded.
Usage: your render count and history are on your dashboard at app.blueport.io.