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

HeaderValueRequired
AuthorizationBearer YOUR_API_KEYYes
Content-Typeapplication/jsonYes

Request Body

The request body must be a JSON object with the following fields:

FieldTypeRequiredDescription
htmlstringYesThe main HTML template for the PDF document body. Supports standard HTML5 elements.
cssstringNoCSS styles applied to the document. Injected as an inline <style> block within the HTML.
dataobjectNoA JSON object containing key-value pairs for template variable substitution. Variables in the HTML template are referenced using double curly braces, e.g. {{variableName}}.
headerHtmlstringNoHTML template for the page header. Rendered at the top of every page. Supports the special CSS classes pageNumber and totalPages for automatic page numbering.
footerHtmlstringNoHTML 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.

PropertyValue
Status Code200 OK
Content-Typeapplication/pdf
BodyBinary 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

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.