Generate a Invoice PDF via the API POST your data to /api/v1/generate and get a PDF back. Copy-paste an example, swap in your API key, and loop over a list to render thousands — one invoice per record.
cURL Node.js Python
curl -X POST https://pdfgen.com/api/v1/generate \
-H "Authorization: Bearer pdfg_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"html": "<div style=\"max-width:760px;margin:0 auto;padding:48px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif;color:#111827;\">\n <div style=\"display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:40px;\">\n <div>\n <h1 style=\"font-size:24px;font-weight:800;margin:0;\">{{company.name}}</h1>\n <p style=\"color:#6b7280;margin:6px 0 0;font-size:13px;white-space:pre-line;\">{{company.address}}</p>\n </div>\n <div style=\"text-align:right;\">\n <h2 style=\"font-size:30px;letter-spacing:3px;color:#4f46e5;margin:0;font-weight:800;\">INVOICE</h2>\n <p style=\"margin:8px 0 0;color:#6b7280;font-size:13px;\">#{{invoiceNumber}}</p>\n <p style=\"margin:2px 0 0;color:#6b7280;font-size:13px;\">{{formatDate issuedDate}}</p>\n </div>\n </div>\n <div style=\"display:flex;justify-content:space-between;margin-bottom:32px;\">\n <div>\n <p style=\"font-size:11px;text-transform:uppercase;letter-spacing:1px;color:#9ca3af;margin:0 0 6px;\">Billed to</p>\n <p style=\"margin:0;font-weight:600;\">{{client.name}}</p>\n <p style=\"margin:2px 0 0;color:#6b7280;font-size:13px;white-space:pre-line;\">{{client.address}}</p>\n </div>\n <div style=\"text-align:right;\">\n <p style=\"font-size:11px;text-transform:uppercase;letter-spacing:1px;color:#9ca3af;margin:0 0 6px;\">Due</p>\n <p style=\"margin:0;font-weight:600;\">{{formatDate dueDate}}</p>\n </div>\n </div>\n <table style=\"width:100%;border-collapse:collapse;font-size:14px;\">\n <thead>\n <tr style=\"background:#f9fafb;text-align:left;\">\n <th style=\"padding:12px;border-bottom:1px solid #e5e7eb;\">Description</th>\n <th style=\"padding:12px;border-bottom:1px solid #e5e7eb;text-align:center;\">Qty</th>\n <th style=\"padding:12px;border-bottom:1px solid #e5e7eb;text-align:right;\">Unit</th>\n <th style=\"padding:12px;border-bottom:1px solid #e5e7eb;text-align:right;\">Amount</th>\n </tr>\n </thead>\n <tbody>\n {{#each items}}\n <tr>\n <td style=\"padding:12px;border-bottom:1px solid #f3f4f6;\">{{description}}</td>\n <td style=\"padding:12px;border-bottom:1px solid #f3f4f6;text-align:center;\">{{quantity}}</td>\n <td style=\"padding:12px;border-bottom:1px solid #f3f4f6;text-align:right;\">{{formatCurrency unitPrice currency}}</td>\n <td style=\"padding:12px;border-bottom:1px solid #f3f4f6;text-align:right;\">{{formatCurrency amount currency}}</td>\n </tr>\n {{/each}}\n </tbody>\n </table>\n <div style=\"display:flex;justify-content:flex-end;margin-top:24px;\">\n <table style=\"font-size:14px;min-width:240px;\">\n <tr><td style=\"padding:4px 0;color:#6b7280;\">Subtotal</td><td style=\"padding:4px 0;text-align:right;\">{{formatCurrency subtotal currency}}</td></tr>\n <tr><td style=\"padding:4px 0;color:#6b7280;\">Tax ({{taxRate}}%)</td><td style=\"padding:4px 0;text-align:right;\">{{formatCurrency tax currency}}</td></tr>\n <tr><td style=\"padding:12px 0 0;font-weight:800;font-size:16px;\">Total</td><td style=\"padding:12px 0 0;text-align:right;font-weight:800;font-size:16px;color:#4f46e5;\">{{formatCurrency total currency}}</td></tr>\n </table>\n </div>\n <p style=\"margin-top:48px;font-size:12px;color:#9ca3af;border-top:1px solid #f3f4f6;padding-top:16px;\">{{notes}}</p>\n</div>",
"engine": "handlebars",
"format": "A4",
"data": {
"company": {
"name": "Northwind Studio",
"address": "120 Market St\nSan Francisco, CA 94103"
},
"client": {
"name": "Acme Corp",
"address": "88 Industrial Way\nAustin, TX 78701"
},
"invoiceNumber": "INV-2026-014",
"issuedDate": "2026-06-01",
"dueDate": "2026-06-15",
"currency": "USD",
"items": [
{
"description": "Brand design system",
"quantity": 1,
"unitPrice": 3200,
"amount": 3200
},
{
"description": "Landing page build",
"quantity": 1,
"unitPrice": 2400,
"amount": 2400
},
{
"description": "Revision rounds",
"quantity": 3,
"unitPrice": 150,
"amount": 450
}
],
"subtotal": 6050,
"taxRate": 8.5,
"tax": 514.25,
"total": 6564.25,
"notes": "Payment due within 14 days. Thank you for your business!"
}
}' --output invoice.pdf
import fs from "node:fs" ;
const template = "<div style=\"max-width:760px;margin:0 auto;padding:48px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif;color:#111827;\">\n <div style=\"display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:40px;\">\n <div>\n <h1 style=\"font-size:24px;font-weight:800;margin:0;\">{{company.name}}</h1>\n <p style=\"color:#6b7280;margin:6px 0 0;font-size:13px;white-space:pre-line;\">{{company.address}}</p>\n </div>\n <div style=\"text-align:right;\">\n <h2 style=\"font-size:30px;letter-spacing:3px;color:#4f46e5;margin:0;font-weight:800;\">INVOICE</h2>\n <p style=\"margin:8px 0 0;color:#6b7280;font-size:13px;\">#{{invoiceNumber}}</p>\n <p style=\"margin:2px 0 0;color:#6b7280;font-size:13px;\">{{formatDate issuedDate}}</p>\n </div>\n </div>\n <div style=\"display:flex;justify-content:space-between;margin-bottom:32px;\">\n <div>\n <p style=\"font-size:11px;text-transform:uppercase;letter-spacing:1px;color:#9ca3af;margin:0 0 6px;\">Billed to</p>\n <p style=\"margin:0;font-weight:600;\">{{client.name}}</p>\n <p style=\"margin:2px 0 0;color:#6b7280;font-size:13px;white-space:pre-line;\">{{client.address}}</p>\n </div>\n <div style=\"text-align:right;\">\n <p style=\"font-size:11px;text-transform:uppercase;letter-spacing:1px;color:#9ca3af;margin:0 0 6px;\">Due</p>\n <p style=\"margin:0;font-weight:600;\">{{formatDate dueDate}}</p>\n </div>\n </div>\n <table style=\"width:100%;border-collapse:collapse;font-size:14px;\">\n <thead>\n <tr style=\"background:#f9fafb;text-align:left;\">\n <th style=\"padding:12px;border-bottom:1px solid #e5e7eb;\">Description</th>\n <th style=\"padding:12px;border-bottom:1px solid #e5e7eb;text-align:center;\">Qty</th>\n <th style=\"padding:12px;border-bottom:1px solid #e5e7eb;text-align:right;\">Unit</th>\n <th style=\"padding:12px;border-bottom:1px solid #e5e7eb;text-align:right;\">Amount</th>\n </tr>\n </thead>\n <tbody>\n {{#each items}}\n <tr>\n <td style=\"padding:12px;border-bottom:1px solid #f3f4f6;\">{{description}}</td>\n <td style=\"padding:12px;border-bottom:1px solid #f3f4f6;text-align:center;\">{{quantity}}</td>\n <td style=\"padding:12px;border-bottom:1px solid #f3f4f6;text-align:right;\">{{formatCurrency unitPrice currency}}</td>\n <td style=\"padding:12px;border-bottom:1px solid #f3f4f6;text-align:right;\">{{formatCurrency amount currency}}</td>\n </tr>\n {{/each}}\n </tbody>\n </table>\n <div style=\"display:flex;justify-content:flex-end;margin-top:24px;\">\n <table style=\"font-size:14px;min-width:240px;\">\n <tr><td style=\"padding:4px 0;color:#6b7280;\">Subtotal</td><td style=\"padding:4px 0;text-align:right;\">{{formatCurrency subtotal currency}}</td></tr>\n <tr><td style=\"padding:4px 0;color:#6b7280;\">Tax ({{taxRate}}%)</td><td style=\"padding:4px 0;text-align:right;\">{{formatCurrency tax currency}}</td></tr>\n <tr><td style=\"padding:12px 0 0;font-weight:800;font-size:16px;\">Total</td><td style=\"padding:12px 0 0;text-align:right;font-weight:800;font-size:16px;color:#4f46e5;\">{{formatCurrency total currency}}</td></tr>\n </table>\n </div>\n <p style=\"margin-top:48px;font-size:12px;color:#9ca3af;border-top:1px solid #f3f4f6;padding-top:16px;\">{{notes}}</p>\n</div>" ;
const res = await fetch ( "https://pdfgen.com/api/v1/generate" , {
method : "POST" ,
headers : {
Authorization : "Bearer pdfg_live_xxx" ,
"Content-Type" : "application/json" ,
} ,
body : JSON . stringify ( {
html : template ,
engine : "handlebars" ,
format : "A4" ,
data : {
"company" : {
"name" : "Northwind Studio" ,
"address" : "120 Market St\nSan Francisco, CA 94103"
} ,
"client" : {
"name" : "Acme Corp" ,
"address" : "88 Industrial Way\nAustin, TX 78701"
} ,
"invoiceNumber" : "INV-2026-014" ,
"issuedDate" : "2026-06-01" ,
"dueDate" : "2026-06-15" ,
"currency" : "USD" ,
"items" : [
{
"description" : "Brand design system" ,
"quantity" : 1 ,
"unitPrice" : 3200 ,
"amount" : 3200
} ,
{
"description" : "Landing page build" ,
"quantity" : 1 ,
"unitPrice" : 2400 ,
"amount" : 2400
} ,
{
"description" : "Revision rounds" ,
"quantity" : 3 ,
"unitPrice" : 150 ,
"amount" : 450
}
] ,
"subtotal" : 6050 ,
"taxRate" : 8.5 ,
"tax" : 514.25 ,
"total" : 6564.25 ,
"notes" : "Payment due within 14 days. Thank you for your business!"
} ,
} ) ,
} ) ;
fs . writeFileSync ( "invoice.pdf" , Buffer . from ( await res . arrayBuffer ( ) ) ) ;
import requests
template = "<div style=\"max-width:760px;margin:0 auto;padding:48px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica,Arial,sans-serif;color:#111827;\">\n <div style=\"display:flex;justify-content:space-between;align-items:flex-start;margin-bottom:40px;\">\n <div>\n <h1 style=\"font-size:24px;font-weight:800;margin:0;\">{{company.name}}</h1>\n <p style=\"color:#6b7280;margin:6px 0 0;font-size:13px;white-space:pre-line;\">{{company.address}}</p>\n </div>\n <div style=\"text-align:right;\">\n <h2 style=\"font-size:30px;letter-spacing:3px;color:#4f46e5;margin:0;font-weight:800;\">INVOICE</h2>\n <p style=\"margin:8px 0 0;color:#6b7280;font-size:13px;\">#{{invoiceNumber}}</p>\n <p style=\"margin:2px 0 0;color:#6b7280;font-size:13px;\">{{formatDate issuedDate}}</p>\n </div>\n </div>\n <div style=\"display:flex;justify-content:space-between;margin-bottom:32px;\">\n <div>\n <p style=\"font-size:11px;text-transform:uppercase;letter-spacing:1px;color:#9ca3af;margin:0 0 6px;\">Billed to</p>\n <p style=\"margin:0;font-weight:600;\">{{client.name}}</p>\n <p style=\"margin:2px 0 0;color:#6b7280;font-size:13px;white-space:pre-line;\">{{client.address}}</p>\n </div>\n <div style=\"text-align:right;\">\n <p style=\"font-size:11px;text-transform:uppercase;letter-spacing:1px;color:#9ca3af;margin:0 0 6px;\">Due</p>\n <p style=\"margin:0;font-weight:600;\">{{formatDate dueDate}}</p>\n </div>\n </div>\n <table style=\"width:100%;border-collapse:collapse;font-size:14px;\">\n <thead>\n <tr style=\"background:#f9fafb;text-align:left;\">\n <th style=\"padding:12px;border-bottom:1px solid #e5e7eb;\">Description</th>\n <th style=\"padding:12px;border-bottom:1px solid #e5e7eb;text-align:center;\">Qty</th>\n <th style=\"padding:12px;border-bottom:1px solid #e5e7eb;text-align:right;\">Unit</th>\n <th style=\"padding:12px;border-bottom:1px solid #e5e7eb;text-align:right;\">Amount</th>\n </tr>\n </thead>\n <tbody>\n {{#each items}}\n <tr>\n <td style=\"padding:12px;border-bottom:1px solid #f3f4f6;\">{{description}}</td>\n <td style=\"padding:12px;border-bottom:1px solid #f3f4f6;text-align:center;\">{{quantity}}</td>\n <td style=\"padding:12px;border-bottom:1px solid #f3f4f6;text-align:right;\">{{formatCurrency unitPrice currency}}</td>\n <td style=\"padding:12px;border-bottom:1px solid #f3f4f6;text-align:right;\">{{formatCurrency amount currency}}</td>\n </tr>\n {{/each}}\n </tbody>\n </table>\n <div style=\"display:flex;justify-content:flex-end;margin-top:24px;\">\n <table style=\"font-size:14px;min-width:240px;\">\n <tr><td style=\"padding:4px 0;color:#6b7280;\">Subtotal</td><td style=\"padding:4px 0;text-align:right;\">{{formatCurrency subtotal currency}}</td></tr>\n <tr><td style=\"padding:4px 0;color:#6b7280;\">Tax ({{taxRate}}%)</td><td style=\"padding:4px 0;text-align:right;\">{{formatCurrency tax currency}}</td></tr>\n <tr><td style=\"padding:12px 0 0;font-weight:800;font-size:16px;\">Total</td><td style=\"padding:12px 0 0;text-align:right;font-weight:800;font-size:16px;color:#4f46e5;\">{{formatCurrency total currency}}</td></tr>\n </table>\n </div>\n <p style=\"margin-top:48px;font-size:12px;color:#9ca3af;border-top:1px solid #f3f4f6;padding-top:16px;\">{{notes}}</p>\n</div>"
res = requests . post (
"https://pdfgen.com/api/v1/generate" ,
headers = { "Authorization" : "Bearer pdfg_live_xxx" } ,
json = {
"html" : template ,
"engine" : "handlebars" ,
"format" : "A4" ,
"data" : {
"company" : {
"name" : "Northwind Studio" ,
"address" : "120 Market St\nSan Francisco, CA 94103"
} ,
"client" : {
"name" : "Acme Corp" ,
"address" : "88 Industrial Way\nAustin, TX 78701"
} ,
"invoiceNumber" : "INV-2026-014" ,
"issuedDate" : "2026-06-01" ,
"dueDate" : "2026-06-15" ,
"currency" : "USD" ,
"items" : [
{
"description" : "Brand design system" ,
"quantity" : 1 ,
"unitPrice" : 3200 ,
"amount" : 3200
} ,
{
"description" : "Landing page build" ,
"quantity" : 1 ,
"unitPrice" : 2400 ,
"amount" : 2400
} ,
{
"description" : "Revision rounds" ,
"quantity" : 3 ,
"unitPrice" : 150 ,
"amount" : 450
}
] ,
"subtotal" : 6050 ,
"taxRate" : 8.5 ,
"tax" : 514.25 ,
"total" : 6564.25 ,
"notes" : "Payment due within 14 days. Thank you for your business!"
} ,
} ,
)
with open ( "invoice.pdf" , "wb" ) as f :
f . write ( res . content )
Working in another language? Follow a full guide for your stack: