# Certificate generator API: bulk PDF certificates from HTML Certificate generator API: create PDF certificates in bulk from one HTML template, with one API call per attendee, A4 landscape and custom fonts. **Quick answer.** Fill an HTML template with each attendee's name and send it to the API. One certificate is one page, so it costs one credit. ```bash curl -X POST https://html-pdf.com/v1/pdf \ -H "Authorization: Bearer $HTML_PDF_KEY" \ -H "Content-Type: application/json" \ -d '{"html": "

Certificate of Completion

Jane Doe

"}' \ -o certificate.pdf ``` Courses, workshops, conferences and internal trainings all end the same way. Someone needs a certificate with their name on it. Exporting by hand from a slide tool works for ten people, but not for five hundred. With an HTML template and an HTML-to-PDF API, you write the design once. Then you generate every certificate from your attendee list. ## How bulk certificate generation works The whole process takes four steps. 1. Design one certificate as HTML and CSS, with placeholders for name, course and date. 2. Read your attendee list from a CSV export or a JSON file. 3. For each person, fill the template and send it to `POST https://html-pdf.com/v1/pdf`. 4. Save each PDF with a predictable filename, or get a download link back. Each certificate is one page, so each costs one credit. You can also start from the free [certificate template](https://html-pdf.com/templates/certificate) instead of designing from scratch. ## The certificate template (A4 landscape) This template gives you a ready-to-use A4 landscape design. Set the page size in CSS with `@page` and pass `prefer_css_page_size: true` so the PDF uses it. You can load fonts from Google Fonts over https. The renderer fetches them like a normal browser. ```html

Certificate of Completion

This certifies that

__NAME__

has completed __COURSE__

__DATE__ ยท Certificate ID __ID__
``` Keep the content inside one fixed-height page (`height: 210mm` for A4 landscape). That way a long name never spills onto a second page. ## Generate certificates from a CSV (Node.js) This script turns a CSV of attendees into one PDF each. It reads `attendees.csv` (columns `name,email,course`), escapes the values, and runs a few requests in parallel. ```js import fs from "node:fs"; const tpl = fs.readFileSync("certificate.html", "utf8"); const esc = s => String(s).replace(/[&<>"']/g, c => ({ "&": "&", "<": "<", ">": ">", '"': """, "'": "'" }[c])); const [, ...lines] = fs.readFileSync("attendees.csv", "utf8").trim().split("\n"); const people = lines.map(l => { const [name, email, course] = l.split(","); return { name, email, course }; }); const slug = s => s.toLowerCase().normalize("NFKD").replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, ""); fs.mkdirSync("out", { recursive: true }); async function render(p, i) { const id = `C-2026-${String(i + 1).padStart(4, "0")}`; const html = tpl.replace("__NAME__", esc(p.name)).replace("__COURSE__", esc(p.course)) .replace("__DATE__", "10 October 2026").replace("__ID__", id); const res = await fetch("https://html-pdf.com/v1/pdf", { method: "POST", headers: { Authorization: `Bearer ${process.env.HTML_PDF_KEY}`, "Content-Type": "application/json" }, body: JSON.stringify({ html, prefer_css_page_size: true, wait_delay: 1, max_pages: 1 }), }); if (!res.ok) throw new Error(`${p.name}: ${(await res.json()).error.message}`); fs.writeFileSync(`out/certificate-${slug(p.name)}-${id}.pdf`, Buffer.from(await res.arrayBuffer())); } // 4 workers pulling from a shared queue const queue = people.map((p, i) => [p, i]); await Promise.all(Array.from({ length: 4 }, async () => { while (queue.length) { const [p, i] = queue.shift(); await render(p, i); } })); ``` A few things to know about this script. - **Simple CSV only.** If names contain commas, use a CSV parser such as `csv-parse` instead of `split(",")`. - **Fonts.** `wait_delay: 1` gives web fonts a moment to load. You can also self-host fonts or inline them as base64 `@font-face` sources. - **`max_pages: 1`** stops a broken layout from producing (and billing) extra pages. - **Filenames.** Include a slug of the name plus a unique ID, so two people with the same name never overwrite each other. ## Concurrency and rate limits Here is how to run large batches quickly without errors. The API allows 120 requests per minute, and a handful of parallel workers (3 to 5) is usually enough to stay fast without hitting the limit. For very large batches, add a retry with backoff when you get an HTTP 429. Each request must also finish within the 30-second render limit, which a single-page certificate easily does. ## Python version The same batch job in Python uses the standard `csv` module, so names with commas are handled correctly. ```python import csv, os, html, requests tpl = open("certificate.html", encoding="utf-8").read() with open("attendees.csv", newline="", encoding="utf-8") as f: for i, row in enumerate(csv.DictReader(f), start=1): cid = f"C-2026-{i:04d}" page = (tpl.replace("__NAME__", html.escape(row["name"])) .replace("__COURSE__", html.escape(row["course"])) .replace("__DATE__", "10 October 2026").replace("__ID__", cid)) r = requests.post("https://html-pdf.com/v1/pdf", headers={"Authorization": f"Bearer {os.environ['HTML_PDF_KEY']}"}, json={"html": page, "prefer_css_page_size": True, "wait_delay": 1, "max_pages": 1}, timeout=60) r.raise_for_status() open(f"certificate-{cid}.pdf", "wb").write(r.content) ``` Want links to email instead of files? Add `"response": "url"` and each call returns a download URL valid for 24 hours. ## Generate certificates with html-pdf.com This is what you get with html-pdf.com. It renders your HTML in Chromium, so Google Fonts, flexbox and background colors work as they do in the browser. Pricing is per page. You get 100 free credits once you confirm your email, then pay from $0.005 per page, and purchased credits never expire. Your HTML is not stored. [Get an API key](https://html-pdf.com/login) or read the [docs](https://html-pdf.com/docs). With the [html-pdf.com MCP server](https://html-pdf.com/pdf-mcp-server) connected, an AI agent can do the whole batch for you. > *"Here is a spreadsheet of 40 workshop attendees. Using the certificate template at https://html-pdf.com/templates/certificate, create one A4 landscape PDF certificate per row with their name, the course 'Intro to Data Analysis' and today's date, and give me the download links."* ## FAQ ### Is there a free certificate generator API? Yes. html-pdf.com gives you 100 free credits once you confirm your email, with no card required. Each one-page certificate uses one credit, so you can create 100 certificates for free. ### How much does it cost to generate certificates in bulk? Each certificate page costs one credit. Packs range from $10 for 1,000 credits to $250 for 50,000, which is $0.01 to $0.005 per certificate. Purchased credits never expire, and failed renders cost nothing. ### Can I use custom fonts in my certificates? Yes. Load fonts from Google Fonts over https, self-host them, or inline them as base64 `@font-face` sources. Add `wait_delay: 1` to give web fonts time to load. ### How many certificates can I generate at once? The API allows 120 requests per minute. Run 3 to 5 parallel workers and retry with backoff on HTTP 429 for very large batches.