Ink & Order for Developers
Guide

HTML to PDF API in Node.js

Puppeteer works, but shipping and patching Chromium in every container is heavy. The Ink & Order API runs headless Chromium for you: post HTML, get a PDF. This sample uses only Node's built-in fetch, FormData and Blob (Node 18+).

1. Get a key

Get a free key (50 files/month), then export it:

export INKORDER_API_KEY=io_live_...

2. HTML string → PDF

// Render an HTML string (e.g. from your template engine) to a PDF buffer.
// Usage: INKORDER_API_KEY=io_live_... node guide_html_to_pdf.mjs   (Node 18+)
import { writeFile } from "node:fs/promises";

const BASE = process.env.INKORDER_API_URL ?? "https://api.inkandordertools.com";

export async function htmlToPdf(html) {
  const form = new FormData();
  // The filename must end in .html so the API routes it to headless Chromium.
  form.append("file", new Blob([html], { type: "text/html" }), "page.html");
  const res = await fetch(`${BASE}/v1/convert`, {
    method: "POST",
    headers: { Authorization: `Bearer ${process.env.INKORDER_API_KEY}` },
    body: form,
  });
  if (!res.ok) throw new Error(`Ink & Order API ${res.status}: ${await res.text()}`);
  return Buffer.from(await res.arrayBuffer());
}

const html = `<!doctype html><html><head><meta charset="utf-8">
<style>body{font-family:sans-serif;margin:48px} h1{color:#0f766e}</style></head>
<body><h1>Weekly report</h1><p>Generated ${new Date().toISOString().slice(0, 10)} with the Ink & Order API.</p></body></html>`;

await writeFile("report.pdf", await htmlToPdf(html));
console.log("saved report.pdf");
node guide_html_to_pdf.mjs
# saved report.pdf

Notes

← All guides