Generate PDF
POST /api/pdf/external — Generate a PDF document
Generate a PDF document from an HTML template with optional CSS styling, dynamic data injection, and custom headers and footers.
Endpoint
POST https://api.docreate.io/api/pdf/external
Headers
| Header | Value | Required |
|---|---|---|
Authorization | Bearer YOUR_API_KEY | Yes |
Content-Type | application/json | Yes |
Request Body
The request body must be a JSON object with the following fields:
| Field | Type | Required | Description |
|---|---|---|---|
html | string | Yes | The main HTML template for the PDF document body. Supports standard HTML5 elements. |
css | string | No | CSS styles applied to the document. Injected as an inline <style> block within the HTML. |
data | object | No | A JSON object containing key-value pairs for template variable substitution. Variables in the HTML template are referenced using double curly braces, e.g. {{variableName}}. |
headerHtml | string | No | HTML template for the page header. Rendered at the top of every page. Supports the special CSS classes pageNumber and totalPages for automatic page numbering. |
footerHtml | string | No | HTML template for the page footer. Rendered at the bottom of every page. Supports the same special CSS classes as headerHtml. |
Response
On success, the API returns the generated PDF as a binary stream.
| Property | Value |
|---|---|
| Status Code | 200 OK |
| Content-Type | application/pdf |
| Body | Binary PDF data |
On failure, the API returns a JSON error object. See Error Handling for details.
Examples
Basic PDF Generation
A minimal request to generate a simple PDF document:
curl -X POST https://api.docreate.io/api/pdf/external \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"html": "<h1>Invoice #1042</h1><p>Thank you for your purchase.</p>"
}' \
--output invoice.pdf
With CSS Styling
Generate a styled PDF with custom fonts, colors, and layout:
curl -X POST https://api.docreate.io/api/pdf/external \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"html": "<div class=\"invoice\"><h1>Invoice #1042</h1><table><tr><th>Item</th><th>Amount</th></tr><tr><td>Design Services</td><td>$2,500.00</td></tr></table></div>",
"css": "body { font-family: Helvetica, sans-serif; padding: 40px; } .invoice { max-width: 800px; margin: 0 auto; } h1 { color: #1a1a1a; border-bottom: 2px solid #e5e5e5; padding-bottom: 10px; } table { width: 100%; border-collapse: collapse; margin-top: 20px; } th, td { padding: 12px; text-align: left; border-bottom: 1px solid #e5e5e5; } th { background-color: #f9f9f9; font-weight: 600; }"
}' \
--output styled-invoice.pdf
With Dynamic Data
Use template variables to inject dynamic data into your HTML template:
curl -X POST https://api.docreate.io/api/pdf/external \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"html": "<h1>Invoice #{{invoiceNumber}}</h1><p>Bill to: {{customerName}}</p><p>Amount: {{amount}}</p><p>Due date: {{dueDate}}</p>",
"css": "body { font-family: Helvetica, sans-serif; padding: 40px; }",
"data": {
"invoiceNumber": "1042",
"customerName": "Acme Corp",
"amount": "$2,500.00",
"dueDate": "2026-03-15"
}
}' \
--output dynamic-invoice.pdf
With Header and Footer
Add repeating headers and footers across all pages, including page numbers:
curl -X POST https://api.docreate.io/api/pdf/external \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"html": "<h1>Annual Report 2026</h1><p>Lorem ipsum dolor sit amet, consectetur adipiscing elit...</p>",
"css": "body { font-family: Helvetica, sans-serif; padding: 40px; }",
"headerHtml": "<div style=\"font-size: 10px; color: #999; text-align: center; width: 100%; padding: 10px 0;\">Acme Corp — Confidential</div>",
"footerHtml": "<div style=\"font-size: 10px; color: #999; text-align: center; width: 100%; padding: 10px 0;\">Page <span class=\"pageNumber\"></span> of <span class=\"totalPages\"></span></div>"
}' \
--output report.pdf
JavaScript (Node.js)
const response = await fetch('https://api.docreate.io/api/pdf/external', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json',
},
body: JSON.stringify({
html: '<h1>Invoice #{{invoiceNumber}}</h1><p>Amount: {{amount}}</p>',
css: 'body { font-family: Helvetica, sans-serif; padding: 40px; }',
data: {
invoiceNumber: '1042',
amount: '$2,500.00',
},
}),
});
if (!response.ok) {
const error = await response.json();
throw new Error(`PDF generation failed: ${error.error}`);
}
const pdfBuffer = Buffer.from(await response.arrayBuffer());
// Save to file
const fs = await import('fs/promises');
await fs.writeFile('invoice.pdf', pdfBuffer);
Python
import requests
response = requests.post(
'https://api.docreate.io/api/pdf/external',
headers={
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json',
},
json={
'html': '<h1>Invoice #{{invoiceNumber}}</h1><p>Amount: {{amount}}</p>',
'css': 'body { font-family: Helvetica, sans-serif; padding: 40px; }',
'data': {
'invoiceNumber': '1042',
'amount': '$2,500.00',
},
},
)
if response.status_code == 200:
with open('invoice.pdf', 'wb') as f:
f.write(response.content)
else:
print(f"Error: {response.json()}")
Notes
- The maximum request body size is 5 MB. For larger documents, consider splitting them into multiple requests.
- HTML rendering supports standard HTML5 and CSS3 properties. JavaScript embedded in HTML is not executed.
- External resources (images, fonts) referenced via URLs in your HTML must be publicly accessible.
- The generated PDF uses A4 page size by default.