How to Automate Invoice PDF Generation with a REST API
Still creating invoices manually in Excel? Copying data between spreadsheets and praying you didn't mistype an amount? There's a better way.
With a PDF generation API, you can turn invoice data into professionally formatted PDFs — and email them to customers — with a single API call. This guide walks you through the implementation with real code examples.
Why Automate with an API?
The Manual Process Problem
- Slow: Create in Excel → export to PDF → attach to email → send
- Error-prone: Manual data entry leads to typos in amounts and addresses
- Doesn't scale: 10 invoices per month is fine. 1,000 is a nightmare.
The API Approach
- Seconds, not hours: Generate from database values instantly
- Zero errors: Code handles calculations and formatting
- Scales infinitely: Same code handles 10 or 10,000 invoices
Architecture Overview
Order data → HTML template → PDF Generation API → Email delivery
You need three things:
- An HTML template — the invoice layout
- Data — customer name, line items, amounts
- One API call — generates the PDF and sends the email
Step 1: Create an HTML Template
Create an invoice template using HTML and CSS. With FUNBREW PDF's template engine, use {{variable_name}} placeholders for dynamic values.
<div style="font-family: -apple-system, sans-serif; max-width: 800px; margin: 0 auto; padding: 40px;">
<div style="display: flex; justify-content: space-between; margin-bottom: 40px;">
<div>
<h1 style="font-size: 28px; margin: 0;">Invoice</h1>
<p style="color: #6b7280;">Invoice #: {{invoice_number}}</p>
<p style="color: #6b7280;">Date: {{issue_date}}</p>
</div>
<div style="text-align: right;">
<p style="font-weight: 700;">Your Company Inc.</p>
<p style="color: #6b7280; font-size: 13px;">123 Business St, Suite 100</p>
</div>
</div>
<div style="margin-bottom: 32px;">
<p style="font-size: 18px; font-weight: 700;">Bill to: {{customer_name}}</p>
</div>
<table style="width: 100%; border-collapse: collapse; margin-bottom: 32px;">
<thead>
<tr style="background: #f8fafc;">
<th style="text-align: left; padding: 12px; border-bottom: 2px solid #e5e7eb;">Item</th>
<th style="text-align: right; padding: 12px; border-bottom: 2px solid #e5e7eb;">Qty</th>
<th style="text-align: right; padding: 12px; border-bottom: 2px solid #e5e7eb;">Price</th>
<th style="text-align: right; padding: 12px; border-bottom: 2px solid #e5e7eb;">Total</th>
</tr>
</thead>
<tbody>{{line_items}}</tbody>
</table>
<div style="text-align: right; margin-bottom: 32px;">
<p>Subtotal: ${{subtotal}}</p>
<p>Tax: ${{tax}}</p>
<p style="font-size: 20px; font-weight: 700;">Total: ${{total}}</p>
</div>
<div style="border-top: 1px solid #e5e7eb; padding-top: 16px; color: #9ca3af; font-size: 12px;">
<p>Due date: {{due_date}}</p>
<p>Payment: Wire transfer to Account #1234567</p>
</div>
</div>
Register this template in the FUNBREW PDF dashboard.
Step 2: Generate an Invoice PDF via API
JavaScript (Node.js)
const response = await fetch("https://pdf.funbrew.cloud/api/pdf/generate-from-template", {
method: "POST",
headers: {
"Authorization": "Bearer sk-your-api-key",
"Content-Type": "application/json",
},
body: JSON.stringify({
template: "invoice",
variables: {
invoice_number: "INV-2026-0042",
issue_date: "March 26, 2026",
customer_name: "Acme Corp",
line_items: buildLineItemsHtml(items),
subtotal: "1,500.00",
tax: "150.00",
total: "1,650.00",
due_date: "April 30, 2026",
},
email: {
to: "billing@acme.com",
subject: "Invoice INV-2026-0042 from Your Company",
},
options: { engine: "quality" },
}),
});
const result = await response.json();
console.log("PDF URL:", result.data.download_url);
Python
import requests
response = requests.post(
"https://pdf.funbrew.cloud/api/pdf/generate-from-template",
headers={"Authorization": "Bearer sk-your-api-key"},
json={
"template": "invoice",
"variables": {
"invoice_number": "INV-2026-0042",
"issue_date": "March 26, 2026",
"customer_name": "Acme Corp",
"line_items": build_line_items_html(items),
"subtotal": "1,500.00",
"tax": "150.00",
"total": "1,650.00",
"due_date": "April 30, 2026",
},
"email": {
"to": "billing@acme.com",
"subject": "Invoice INV-2026-0042 from Your Company",
},
"options": {"engine": "quality"},
},
)
print("PDF URL:", response.json()["data"]["download_url"])
PHP (Laravel)
$response = Http::withToken('sk-your-api-key')
->post('https://pdf.funbrew.cloud/api/pdf/generate-from-template', [
'template' => 'invoice',
'variables' => [
'invoice_number' => 'INV-2026-0042',
'issue_date' => 'March 26, 2026',
'customer_name' => 'Acme Corp',
'line_items' => $this->buildLineItemsHtml($items),
'subtotal' => '1,500.00',
'tax' => '150.00',
'total' => '1,650.00',
'due_date' => 'April 30, 2026',
],
'email' => [
'to' => 'billing@acme.com',
'subject' => 'Invoice INV-2026-0042 from Your Company',
],
'options' => ['engine' => 'quality'],
]);
$downloadUrl = $response->json('data.download_url');
Step 3: Tax Calculation Logic
Accurate tax calculation is essential for invoice automation. Here's a pattern for handling multiple tax rates and rounding correctly.
Multi-Rate Tax Calculation
function calculateInvoice(items) {
// Group by tax rate
const grouped = {};
for (const item of items) {
const rate = item.taxRate || 10;
if (!grouped[rate]) grouped[rate] = [];
grouped[rate].push(item);
}
let grandTotal = 0;
const breakdown = [];
for (const [rate, groupItems] of Object.entries(grouped)) {
const subtotal = groupItems.reduce((sum, i) => sum + i.price * i.qty, 0);
const tax = Math.floor(subtotal * (rate / 100)); // Round down per rate
grandTotal += subtotal + tax;
breakdown.push({ rate: Number(rate), subtotal, tax });
}
return { breakdown, grandTotal };
}
Template Integration
<div style="margin-top: 24px; border-top: 1px solid #e5e7eb; padding-top: 16px;">
<table style="width: 100%; margin-top: 8px;">
<tr>
<td>Subtotal (10% tax)</td>
<td style="text-align: right;">${{standard_subtotal}}</td>
</tr>
<tr>
<td>Tax (10%)</td>
<td style="text-align: right;">${{standard_tax}}</td>
</tr>
</table>
</div>
Always apply rounding once per tax rate per invoice, not per line item. Rounding per line item can cause discrepancies between the sum of line totals and the invoice total.
Step 4: Schedule Monthly Invoice Runs
Automate your billing cycle with cron jobs or task schedulers instead of running batch processing manually.
Node.js (node-cron)
const cron = require('node-cron');
// Run on the last day of each month at 9:00 AM
cron.schedule('0 9 28-31 * *', async () => {
const today = new Date();
const lastDay = new Date(today.getFullYear(), today.getMonth() + 1, 0).getDate();
if (today.getDate() !== lastDay) return;
const customers = await fetchBillableCustomers();
const result = await generateInvoiceBatch(customers);
console.log(`Done: ${result.success} succeeded, ${result.failed} failed`);
});
GitHub Actions
name: Monthly Invoice Generation
on:
schedule:
- cron: '0 0 28 * *'
jobs:
generate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: node scripts/generate-invoices.js
env:
FUNBREW_PDF_API_KEY: ${{ secrets.FUNBREW_PDF_API_KEY }}
Step 5: Batch Processing for Monthly Billing
For end-of-month billing runs, use the batch API to generate all invoices at once. For advanced patterns, see the PDF API Batch Processing Guide.
const response = await fetch("https://pdf.funbrew.cloud/api/pdf/batch", {
method: "POST",
headers: {
"Authorization": "Bearer sk-your-api-key",
"Content-Type": "application/json",
},
body: JSON.stringify({
items: customers.map(c => ({
type: "template",
template: "invoice",
variables: buildInvoiceVars(c),
filename: `invoice-${c.id}-202603.pdf`,
email: {
to: c.email,
subject: `Invoice for ${c.name} - March 2026`,
},
})),
}),
});
const { data } = await response.json();
console.log(`Generated ${data.results.length} invoices`);
Get Notified with Webhooks
Want a Slack notification when invoices are generated? Set up a webhook URL in the dashboard. You'll receive a POST request like this:
{
"event": "pdf.generated",
"data": {
"filename": "invoice-42-202603.pdf",
"file_size": 48210,
"download_url": "https://pdf.funbrew.cloud/dl/abc123..."
}
}
Frequently Asked Questions
How do I manage templates?
Create and edit templates in the FUNBREW PDF dashboard using HTML and CSS. Use {{variable_name}} placeholders for dynamic values. For advanced techniques like loops and conditionals, see the PDF Template Engine Guide.
Does it support CJK fonts?
Yes. Noto Sans JP and other CJK fonts are pre-installed — no additional configuration needed. See our HTML to PDF API comparison for how this compares to other tools.
Is it secure for financial documents?
Invoices contain sensitive business data. FUNBREW PDF uses SSL/TLS encryption, API key authentication, and automatic file expiration to keep your data safe.
What's the typical file size of an invoice PDF?
A standard invoice (text and tables, no images) is typically 30–80 KB. With a company logo, expect 100–200 KB. Well within email attachment limits.
Can I integrate with accounting software?
Yes. Since it's API-based, you can use exported data from QuickBooks, Xero, FreshBooks, or any accounting system. Read the CSV or JSON export, map fields to template variables, and generate PDFs.
Error Handling and Retry
Batch processing at month-end may encounter transient failures. Implement retry logic with exponential backoff.
async function generateWithRetry(customer, maxRetries = 3) {
for (let attempt = 1; attempt <= maxRetries; attempt++) {
try {
return await generateInvoice(customer);
} catch (error) {
if (attempt === maxRetries) throw error;
const delay = error.status === 429 ? 5000 * attempt : 1000 * attempt;
await new Promise(r => setTimeout(r, delay));
}
}
}
For comprehensive error handling patterns, see the PDF API Error Handling Guide.
Summary
Automating invoice PDF generation with an API eliminates manual work and errors:
- Create a template once, reuse forever
- One API call = PDF + email delivery
- Batch API for monthly billing runs
- Webhooks for completion notifications
Get started with the free plan (30 PDFs/month). Build your invoice template in the editor and test it in the Playground.
Related
- Invoice Automation Use Case — More invoice generation patterns
- PDF Template Engine Guide — Variables, loops, and conditional logic
- PDF API Batch Processing Guide — Efficient bulk invoice generation
- PDF API Error Handling Guide — Retry strategies for failed generations
- PDF API Production Checklist — Production readiness for invoice automation
- HTML to PDF API Comparison 2026 — How we compare to alternatives
- PDF API Quickstart — Node.js, Python, and PHP code examples
- PDF API Security Guide — Secure handling of invoice data
- Monthly Report PDF Generation Guide — Combine with report automation
- API Reference — Full endpoint documentation