API Documentation

Generate deterministic PDFs with a simple REST API

Authentication

All API requests require authentication using an API key. Include your API key in the Authorization header:

Authorization: Bearer pm_live_xxxxxxxxxxxxxxxxxxxx

Or use the X-API-Key header:

X-API-Key: pm_live_xxxxxxxxxxxxxxxxxxxx

API keys starting with pm_test_ are for testing. Use pm_live_ keys in production.

Quick Start

Generate your first PDF in 3 steps:

1. Create a Template

curl -X POST https://pdfmodule.com/api/v1/templates \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Simple Invoice",
    "body_html": "<h1>Invoice #{{invoice.number}}</h1><p>Total: {{formatCurrency total \"USD\"}}</p>"
  }'

2. Render a PDF

curl -X POST https://pdfmodule.com/api/v1/render \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "template": "simple-invoice",
    "data": {
      "invoice": {"number": "INV-001"},
      "total": 299.99
    }
  }'

3. Download the PDF

curl https://pdfmodule.com/api/v1/documents/UUID/download \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -o invoice.pdf

Error Handling

The API returns standard HTTP status codes:

CodeDescription
200Success
201Created
400Bad Request - Invalid parameters
401Unauthorized - Invalid API key
404Not Found
422Validation Error
429Rate Limit Exceeded
500Server Error

Error responses include a JSON body:

{
  "error": "Template not found",
  "errors": {
    "field_name": ["Error message"]
  }
}

Render PDF

POST /api/v1/render
Generate a PDF from a template

Request Body

ParameterTypeDescription
template *stringTemplate slug
data *objectData to render in template
versionintegerSpecific template version (default: latest)
enginestringRendering engine: wkhtmltopdf, chromium, or auto. See Rendering Engines.
page_sizestringOverride page size: A4, Letter, Legal
orientationstringOverride orientation: portrait or landscape
margin_topintegerOverride top margin in mm
margin_rightintegerOverride right margin in mm
margin_bottomintegerOverride bottom margin in mm
margin_leftintegerOverride left margin in mm
line_heightnumberOverride line-height globally (e.g., 1.1, 1.5, 2.0). Applied with maximum specificity to override all CSS and inline styles.

Example with Chromium Engine

curl -X POST https://pdfmodule.com/api/v1/render \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "template": "chart-report",
    "data": {"values": [10, 20, 30]},
    "engine": "chromium"
  }'

Response

Returns the PDF file directly with Content-Type: application/pdf

Response headers include:

HeaderDescription
Content-DispositionFilename for the PDF
X-Document-UUIDUUID to retrieve document metadata
X-Render-EngineEngine used (wkhtmltopdf or chromium)

Validate

POST /api/v1/validate
Validate data against template schema without rendering

Request Body

ParameterTypeDescription
template *stringTemplate slug
data *objectData to validate

Response

{
  "valid": true,
  "errors": [],
  "warnings": [
    {
      "type": "large_table",
      "severity": "medium",
      "field": "items",
      "message": "Table 'items' has 75 rows - may split across pages"
    }
  ]
}

Rendering Engines

PDFModule supports multiple rendering engines to handle different template requirements. Choose the right engine based on your CSS complexity and performance needs.

Available Engines

EngineBest ForCSS Support
wkhtmltopdf Simple layouts, tables, basic styling CSS2, basic CSS3, no flexbox/grid
chromium Complex layouts, charts, modern CSS Full CSS3, flexbox, grid, canvas
auto Let PDFModule choose based on template Analyzes CSS and picks best engine

When to Use Each Engine

Use wkhtmltopdf (default)

  • Invoice tables
  • Simple reports
  • Text-heavy documents
  • Float-based layouts
  • Maximum speed needed

Use chromium

  • Chart.js / canvas charts
  • Flexbox layouts
  • CSS Grid layouts
  • CSS variables
  • Complex dashboards
GET /api/v1/engines
List available rendering engines and their capabilities

Response

{
  "default_engine": "wkhtmltopdf",
  "available_engines": [
    {
      "name": "wkhtmltopdf",
      "version": {"engine": "wkhtmltopdf", "wkhtmltopdf": "0.12.6"},
      "features": ["basic-css", "tables", "images", "headers-footers", "page-numbers"],
      "limitations": ["flexbox", "css-grid", "canvas", "modern-javascript"]
    },
    {
      "name": "chromium",
      "version": {"engine": "chromium", "node_version": "v20.0.0"},
      "features": ["flexbox", "css-grid", "canvas", "chart-js", "modern-css", "es6-javascript"],
      "limitations": []
    }
  ]
}
POST /api/v1/analyze
Analyze a template and get engine recommendation

Request Body

ParameterTypeDescription
template *stringTemplate slug to analyze

Response

{
  "template": "dashboard-report",
  "version": 3,
  "current_engine": null,
  "analysis": {
    "detected_features": ["flexbox", "css-grid", "canvas"],
    "recommended_engine": "chromium",
    "reason": "Modern CSS features detected: flexbox, css-grid, canvas"
  }
}

Setting Default Engine per Template

You can set a default rendering engine for each template. This engine will be used unless overridden in the render request.

curl -X PUT https://pdfmodule.com/api/v1/templates/my-template \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "render_engine": "chromium"
  }'

Templates

GET /api/v1/templates
List all templates
POST /api/v1/templates
Create a new template

Create Template Request

ParameterTypeDescription
name *stringTemplate name
body_html *stringHTML body content
header_htmlstringHeader HTML (every page). Use {{page}} and {{pages}} for page numbers.
footer_htmlstringFooter HTML (every page). Use {{page}} and {{pages}} for page numbers.
styles_cssstringCSS styles
page_sizestringA4, Letter, Legal (default: A4)
orientationstringportrait, landscape
margin_topintegerTop margin in mm
margin_rightintegerRight margin in mm
margin_bottomintegerBottom margin in mm
margin_leftintegerLeft margin in mm
schemaobjectJSON schema for data validation
GET /api/v1/templates/{slug}
Get template details
PUT /api/v1/templates/{slug}
Update template settings
DELETE /api/v1/templates/{slug}
Delete a template
POST /api/v1/templates/{slug}/versions
Create a new template version
POST /api/v1/templates/{slug}/lock
Lock template (prevent edits)

Documents

GET /api/v1/documents
List generated documents

Query Parameters

ParameterTypeDescription
pageintegerPage number (default: 1)
per_pageintegerResults per page (default: 20, max: 100)
GET /api/v1/documents/{uuid}
Get document metadata
GET /api/v1/documents/{uuid}/download
Download PDF file

Account

GET /api/v1/auth/me
Get current user info
GET /api/v1/account/usage
Get usage statistics
GET /api/v1/account/api-keys
List API keys
POST /api/v1/account/api-keys
Create new API key

PDF Preflight - Overview

The Preflight API allows you to analyze and fix PDF files for print production. It checks for common issues like missing bleed, non-embedded fonts, RGB colors, and low-resolution images.

Key Features

Preflight Check
Analyze PDFs for print issues
Auto-Fix
Add bleed, convert colors, flatten
Custom Profiles
Define your own check rules

Available Checks

CheckDescription
geometryPage boxes (TrimBox, BleedBox), bleed margins, page dimensions
fontsFont embedding, subsetting, font types
colorsColor spaces (RGB, CMYK, spot colors), ICC profiles
imagesImage resolution (PPI), compression, color mode
transparencyTransparency usage, blend modes
cuttingCut contour / die line detection

Available Fixes

FixDescription
smart_bleedIntelligently extend content to create bleed
add_bleedAdd bleed by mirroring/extending edges
set_boxesSet TrimBox, BleedBox, and other PDF page boxes
crop_marksAdd trim marks, registration marks, color bars
resizeResize pages to standard sizes (A4, Letter, etc.)
convert_cmykConvert RGB colors to CMYK for print
convert_rgbConvert CMYK colors to RGB for screen
convert_grayConvert to grayscale
flattenFlatten transparency
embed_fontsEmbed all fonts in the PDF
optimizeOptimize PDF for size/quality
spot_to_processConvert spot colors to process (CMYK)
cut_contourGenerate cut contour / die line

Check PDF

POST /api/v1/preflight
Analyze a PDF file for print production issues

Request (multipart/form-data)

ParameterTypeDescription
file or pdffilePDF file to analyze (required unless pdf_url provided)
pdf_urlstringURL to PDF file (alternative to file upload)
checksstringComma-separated checks to run: geometry,fonts,colors,images,transparency,cutting. Default: all
profilestringProfile slug to use (system or custom). See Profiles
configJSON stringCustom configuration overrides

Example: Basic Preflight Check

curl -X POST https://pdfmodule.com/api/v1/preflight \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "file=@document.pdf"

Example: Check Specific Categories

curl -X POST https://pdfmodule.com/api/v1/preflight \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "file=@document.pdf" \
  -F "checks=geometry,colors,fonts"

Example: Check with Profile

curl -X POST https://pdfmodule.com/api/v1/preflight \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "file=@document.pdf" \
  -F "profile=print_strict"

Example: Check with Custom Config

curl -X POST https://pdfmodule.com/api/v1/preflight \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "file=@document.pdf" \
  -F 'config={"bleed_required_mm": 5, "min_resolution_ppi": 300}'

Example: Check PDF from URL

curl -X POST https://pdfmodule.com/api/v1/preflight \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "pdf_url=https://example.com/document.pdf"

Response

{
  "version": "1.0",
  "timestamp": "2024-01-15T10:30:00Z",
  "file": {
    "name": "document.pdf",
    "size_bytes": 1451136,
    "page_count": 4,
    "pdf_version": "1.4"
  },
  "summary": {
    "status": "FAIL",
    "total_issues": 12,
    "fail_count": 4,
    "warn_count": 6,
    "info_count": 2,
    "checks_run": ["geometry", "fonts", "colors", "images", "transparency"]
  },
  "checks": {
    "geometry": {
      "pages": [
        {
          "number": 1,
          "dimensions_mm": {"width": 210.0, "height": 297.0},
          "bleed_mm": {"top": 0, "right": 0, "bottom": 0, "left": 0},
          "boxes": {
            "mediabox": [0, 0, 595.28, 841.89],
            "trimbox": [0, 0, 595.28, 841.89],
            "bleedbox": [0, 0, 595.28, 841.89]
          }
        }
      ],
      "issues": [
        {
          "id": "GEOM_BLEED_INSUFFICIENT",
          "severity": "FAIL",
          "page": 1,
          "message": "Page 1: Insufficient bleed on all edges (0mm, need 3mm)",
          "details": {"found_mm": 0, "required_mm": 3}
        }
      ]
    },
    "fonts": {
      "fonts": {
        "Helvetica": {
          "embedded": false,
          "subset": false,
          "type": "Type1"
        }
      },
      "issues": [
        {
          "id": "FONT_NOT_EMBEDDED",
          "severity": "FAIL",
          "message": "Font \"Helvetica\" is not embedded",
          "details": {"font": "Helvetica", "recommendation": "Embed the font or convert to outlines"}
        }
      ]
    },
    "colors": {
      "color_spaces": ["DeviceRGB", "DeviceCMYK"],
      "has_rgb": true,
      "has_cmyk": true,
      "has_spot": false,
      "issues": [
        {
          "id": "COLOR_RGB_FOUND",
          "severity": "WARN",
          "message": "RGB colors found - may need conversion for print"
        }
      ]
    },
    "images": {
      "images": [
        {
          "page": 1,
          "width": 1200,
          "height": 800,
          "x_ppi": 150,
          "y_ppi": 150,
          "color": "rgb"
        }
      ],
      "issues": [
        {
          "id": "IMAGE_LOW_RES",
          "severity": "WARN",
          "page": 1,
          "message": "Image has low resolution (150 PPI, recommended 300+)"
        }
      ]
    }
  }
}

Issue Severity Levels

SeverityDescription
FAILCritical issue that must be fixed for print production
WARNPotential issue that should be reviewed
INFOInformational finding, usually acceptable

Fix PDF

POST /api/v1/preflight/fix
Apply fixes to a PDF file and return the corrected PDF

Request (multipart/form-data)

ParameterTypeDescription
file or pdf *filePDF file to fix
pdf_urlstringURL to PDF file (alternative to file upload)
fixes *stringComma-separated fixes to apply

Bleed Options

ParameterTypeDefaultDescription
bleed_mmnumber3.0Bleed size in millimeters
bleed_methodstringmirrorBleed method: mirror, extend, clone

Page Box Options (set_boxes fix)

ParameterTypeDescription
trim_inset_mmnumberInset from MediaBox for TrimBox
bleed_outset_mmnumberOutset from TrimBox for BleedBox

Crop Marks Options (crop_marks fix)

ParameterTypeDefaultDescription
add_trim_marksbooleantrueAdd trim/cut marks at corners
add_registrationbooleantrueAdd registration targets
add_color_barsbooleanfalseAdd CMYK color bars
mark_offset_mmnumber3.0Offset of marks from trim edge

Resize Options (resize fix)

ParameterTypeDescription
target_sizestringTarget size: A4, A3, A5, Letter, Legal, custom
custom_width_mmnumberCustom width (when target_size=custom)
custom_height_mmnumberCustom height (when target_size=custom)
fit_modestringFit mode: fit, fill, stretch
orientationstringForce orientation: portrait, landscape, auto

Color Options (convert_cmyk, convert_rgb, convert_gray fixes)

ParameterTypeDescription
target_colorspacestringTarget: cmyk, rgb, gray
icc_profilestringICC profile to use: fogra39, gracol, swop, srgb

Optimization Options (optimize fix)

ParameterTypeDescription
optimize_presetstringPreset: screen, ebook, printer, prepress

Cut Contour Options (cut_contour fix)

ParameterTypeDefaultDescription
cut_sourcestringcontentSource for contour: content, trimbox, shape
cut_shapestringrectangleShape when cut_source=shape: rectangle, rounded, circle, oval
cut_inset_mmnumber0Inset from detected edge
cut_corner_radius_mmnumber5Corner radius for rounded rectangles
cut_stroke_width_mmnumber0.25Stroke width of cut line
cut_spot_namestringCutContourSpot color name for the cut line
cut_output_modestringspotOutput mode: spot (spot color), layer (separate layer)

Response

Returns the fixed PDF file directly with Content-Type: application/pdf

Example: Add 3mm Bleed

curl -X POST https://pdfmodule.com/api/v1/preflight/fix \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "file=@document.pdf" \
  -F "fixes=smart_bleed" \
  -F "bleed_mm=3" \
  -o fixed-document.pdf

Example: Convert to CMYK

curl -X POST https://pdfmodule.com/api/v1/preflight/fix \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "file=@document.pdf" \
  -F "fixes=convert_cmyk" \
  -F "icc_profile=fogra39" \
  -o cmyk-document.pdf

Example: Add Crop Marks with Bleed

curl -X POST https://pdfmodule.com/api/v1/preflight/fix \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "file=@document.pdf" \
  -F "fixes=smart_bleed,crop_marks" \
  -F "bleed_mm=3" \
  -F "add_trim_marks=true" \
  -F "add_registration=true" \
  -F "add_color_bars=false" \
  -o print-ready.pdf

Example: Resize to A4 and Convert to CMYK

curl -X POST https://pdfmodule.com/api/v1/preflight/fix \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "file=@document.pdf" \
  -F "fixes=resize,convert_cmyk" \
  -F "target_size=A4" \
  -F "fit_mode=fit" \
  -o resized-cmyk.pdf

Example: Add Cut Contour (Die Line)

curl -X POST https://pdfmodule.com/api/v1/preflight/fix \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "file=@sticker.pdf" \
  -F "fixes=cut_contour" \
  -F "cut_source=content" \
  -F "cut_inset_mm=0" \
  -F "cut_spot_name=CutContour" \
  -o sticker-with-dieline.pdf

Example: Rounded Rectangle Cut Contour

curl -X POST https://pdfmodule.com/api/v1/preflight/fix \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "file=@business-card.pdf" \
  -F "fixes=cut_contour" \
  -F "cut_source=shape" \
  -F "cut_shape=rounded" \
  -F "cut_corner_radius_mm=3" \
  -o card-with-dieline.pdf

Example: Full Print Preparation

curl -X POST https://pdfmodule.com/api/v1/preflight/fix \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "file=@document.pdf" \
  -F "fixes=smart_bleed,convert_cmyk,flatten,crop_marks" \
  -F "bleed_mm=3" \
  -F "icc_profile=fogra39" \
  -F "add_trim_marks=true" \
  -F "add_registration=true" \
  -o print-ready.pdf

Example: Optimize for Web

curl -X POST https://pdfmodule.com/api/v1/preflight/fix \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "file=@large-document.pdf" \
  -F "fixes=convert_rgb,optimize" \
  -F "optimize_preset=screen" \
  -o web-optimized.pdf

Preflight Profiles

Profiles define a set of rules and thresholds for preflight checks. Use system profiles or create your own custom profiles.

System Profiles

ProfileDescriptionUse Case
print_standardStandard print requirements (3mm bleed, 300 PPI, CMYK preferred)Commercial printing
print_strictStrict requirements (5mm bleed, 300 PPI required, CMYK only)High-quality printing
webWeb/screen requirements (no bleed, RGB allowed, 150 PPI)Digital distribution
archiveArchival requirements (PDF/A compliance, fonts embedded)Long-term storage
GET /api/v1/preflight/profiles
List all available profiles (system + custom)

Example: List Profiles

curl -X GET https://pdfmodule.com/api/v1/preflight/profiles \
  -H "Authorization: Bearer YOUR_API_KEY"

Response

{
  "profiles": [
    {
      "slug": "print_standard",
      "name": "Print Standard",
      "description": "Standard commercial print requirements",
      "is_system": true,
      "bleed_mm": 3.0,
      "bleed_required": true,
      "min_resolution_ppi": 300,
      "color_mode": "cmyk_preferred",
      "fonts_embedded_required": true
    },
    {
      "slug": "my-custom-profile",
      "name": "My Custom Profile",
      "is_system": false,
      "bleed_mm": 5.0,
      "min_resolution_ppi": 350
    }
  ]
}
GET /api/v1/preflight/profiles/{slug}
Get a specific profile

Example: Get Profile

curl -X GET https://pdfmodule.com/api/v1/preflight/profiles/print_standard \
  -H "Authorization: Bearer YOUR_API_KEY"
POST /api/v1/preflight/profiles
Create a custom profile

Request Body

ParameterTypeDefaultDescription
name *string-Profile name
descriptionstring-Profile description
is_defaultbooleanfalseSet as default profile
bleed_mmnumber3.0Required bleed in mm
bleed_requiredbooleantrueIs bleed required?
min_resolution_ppiinteger300Minimum image resolution (FAIL below this)
warn_resolution_ppiinteger150Warning threshold for resolution
color_modestringcmyk_preferredColor mode: cmyk_required, cmyk_preferred, rgb_allowed, any
allow_spot_colorsbooleantrueAllow spot/Pantone colors
allow_rgbbooleantrueAllow RGB colors
fonts_embedded_requiredbooleantrueRequire all fonts embedded
fonts_subset_allowedbooleantrueAllow font subsetting
allow_transparencybooleantrueAllow transparency
max_image_resolution_ppiinteger1200Maximum resolution (warn above this)

Example: Create Custom Profile

curl -X POST https://pdfmodule.com/api/v1/preflight/profiles \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Magazine Print",
    "description": "Requirements for magazine printing",
    "bleed_mm": 5.0,
    "bleed_required": true,
    "min_resolution_ppi": 300,
    "warn_resolution_ppi": 250,
    "color_mode": "cmyk_required",
    "allow_rgb": false,
    "allow_spot_colors": true,
    "fonts_embedded_required": true,
    "allow_transparency": false
  }'
PUT /api/v1/preflight/profiles/{slug}
Update a custom profile (cannot modify system profiles)

Example: Update Profile

curl -X PUT https://pdfmodule.com/api/v1/preflight/profiles/magazine-print \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "bleed_mm": 4.0,
    "min_resolution_ppi": 350
  }'
DELETE /api/v1/preflight/profiles/{slug}
Delete a custom profile (cannot delete system profiles)

Example: Delete Profile

curl -X DELETE https://pdfmodule.com/api/v1/preflight/profiles/magazine-print \
  -H "Authorization: Bearer YOUR_API_KEY"
GET /api/v1/preflight/health
Check preflight service health

Example: Health Check

curl -X GET https://pdfmodule.com/api/v1/preflight/health \
  -H "Authorization: Bearer YOUR_API_KEY"

Response

{
  "status": "healthy",
  "service": {
    "status": "ok"
  }
}

Page Layout & Margins

Understanding how margins, headers, and footers work together is essential for creating well-formatted PDFs. This section explains exactly how your content is positioned on the page.

How the Page is Structured

Every PDF page has distinct areas. Here's a visual representation:

┌─────────────────────────────────────────────────┐
│                   margin_top                    │
│  ┌───────────────────────────────────────────┐  │
│  │              HEADER AREA                  │  │
│  │   (header_html renders here)              │  │
│  └───────────────────────────────────────────┘  │
│                                                 │
│  ┌───────────────────────────────────────────┐  │
│  │                                           │  │
│  │                                           │  │
│m │           BODY CONTENT AREA               │m │
│a │                                           │a │
│r │        (body_html renders here)           │r │
│g │                                           │g │
│i │                                           │i │
│n │                                           │n │
│_ │                                           │_ │
│l │                                           │r │
│e │                                           │i │
│f │                                           │g │
│t │                                           │h │
│  │                                           │t │
│  └───────────────────────────────────────────┘  │
│                                                 │
│  ┌───────────────────────────────────────────┐  │
│  │              FOOTER AREA                  │  │
│  │   (footer_html renders here)              │  │
│  └───────────────────────────────────────────┘  │
│                  margin_bottom                  │
└─────────────────────────────────────────────────┘

Margin Parameters

ParameterDefaultDescription
margin_top10mmSpace from top edge to header/content. Increase this when using headers.
margin_bottom10mmSpace from bottom edge to footer/content. Increase this when using footers.
margin_left10mmSpace from left edge. Applied to body, header, and footer.
margin_right10mmSpace from right edge. Applied to body, header, and footer.
Key Concept: Headers and footers are positioned within the top and bottom margins. If your margins are too small, headers/footers will overlap with your body content.

Recommended Margin Values

Scenariomargin_topmargin_bottomleft/right
No header/footer 10mm 10mm 10-15mm
Simple footer only (page numbers) 10mm 20mm 10-15mm
Header and footer 25mm 25mm 15mm
Large header (logo + multi-line) 35-40mm 20-25mm 15mm

Common Mistake: Overlapping Content

The most common issue is content overlapping with headers or footers. This happens when margins are too small:

❌ Wrong - Margins too small

{
  "header_html": "<div>My Header</div>",
  "footer_html": "<div>Page {{page}}</div>",
  "margin_top": 10,
  "margin_bottom": 10
}

Header overlaps body content!

✓ Correct - Adequate margins

{
  "header_html": "<div>My Header</div>",
  "footer_html": "<div>Page {{page}}</div>",
  "margin_top": 25,
  "margin_bottom": 25
}

Clean separation between areas.

Complete Example

curl -X POST https://pdfmodule.com/api/v1/templates \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Professional Report",
    "body_html": "<h1>{{title}}</h1><p>{{content}}</p>",
    "header_html": "<div style=\"font-size: 10px; color: #666; border-bottom: 1px solid #ddd; padding-bottom: 5px;\">{{company}} - Confidential</div>",
    "footer_html": "<div style=\"font-size: 9px; color: #999; text-align: center;\">Page {{page}} of {{pages}}</div>",
    "page_size": "A4",
    "orientation": "portrait",
    "margin_top": 25,
    "margin_bottom": 20,
    "margin_left": 15,
    "margin_right": 15
  }'

Page Sizes

SizeDimensionsCommon Use
A4 (default)210 × 297 mmInternational standard, most documents
Letter216 × 279 mmUS standard
Legal216 × 356 mmLegal documents (US)

Headers & Footers

Headers appear at the top of every page; footers appear at the bottom. They're perfect for page numbers, company logos, document titles, and confidentiality notices.

Quick Start

Add a simple footer with page numbers:

{
  "footer_html": "<div style=\"text-align: center; font-size: 10px;\">Page {{page}} of {{pages}}</div>",
  "margin_bottom": 20
}

Available Placeholders

PlaceholderDescriptionExample Output
{{page}}Current page number1, 2, 3...
{{pages}}Total number of pages5
Note: {{page}} and {{pages}} are special placeholders that only work in header_html and footer_html. They don't work in the body.

Alignment Shortcuts

Use these directives at the start of your header/footer for quick alignment:

DirectiveResult
{{left}}Left-align content
{{center}}Center content
{{right}}Right-align content
// Right-aligned page numbers
"footer_html": "{{right}}Page {{page}} of {{pages}}"

// Centered company name
"header_html": "{{center}}ACME Corporation"

Header/Footer Styling Examples

Simple Centered Footer

"footer_html": "<div style=\"text-align: center; font-size: 10px; color: #666;\">Page {{page}} of {{pages}}</div>"

Header with Border

"header_html": "<div style=\"font-size: 11px; color: #333; border-bottom: 1px solid #ddd; padding-bottom: 5px;\">Document Title</div>"

Left + Right Content (Two Columns)

"footer_html": "<div style=\"display: flex; justify-content: space-between; font-size: 9px; color: #666;\"><span>Confidential</span><span>Page {{page}} of {{pages}}</span></div>"

Header with Logo Placeholder

"header_html": "<div style=\"display: flex; justify-content: space-between; align-items: center;\"><span style=\"font-weight: bold;\">{{company}}</span><span style=\"font-size: 10px; color: #666;\">{{formatDate date 'M j, Y'}}</span></div>"

Automatic Margin Alignment

Headers and footers automatically inherit margin_left and margin_right from your page settings. This ensures your header/footer text aligns perfectly with your body content.

Page with margin_left: 15mm and margin_right: 15mm:

│←15mm→│                                    │←15mm→│
       ┌────────────────────────────────────┐
       │ Header text aligns here            │  ← header
       ├────────────────────────────────────┤
       │ Body content starts here           │  ← body
       │ ...                                │
       ├────────────────────────────────────┤
       │ Footer text aligns here            │  ← footer
       └────────────────────────────────────┘
Tip: You don't need to add padding to your header/footer HTML for margin alignment - it's handled automatically. Just focus on the content and text-align styling.

Complete Example with Header & Footer

curl -X POST https://pdfmodule.com/api/v1/templates \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Invoice",
    "body_html": "<h1>Invoice #{{invoice.number}}</h1><p>Customer: {{customer.name}}</p>",
    "header_html": "<div style=\"display: flex; justify-content: space-between; font-size: 10px; color: #666; border-bottom: 1px solid #eee; padding-bottom: 5px;\"><span>{{company}}</span><span>Invoice #{{invoice.number}}</span></div>",
    "footer_html": "<div style=\"display: flex; justify-content: space-between; font-size: 9px; color: #999;\"><span>Generated {{currentDate \"M j, Y\"}}</span><span>Page {{page}} of {{pages}}</span></div>",
    "margin_top": 25,
    "margin_bottom": 20,
    "margin_left": 15,
    "margin_right": 15
  }'

Troubleshooting

ProblemSolution
Header/footer overlaps body content Increase margin_top / margin_bottom (try 25mm)
Header/footer text is cut off Reduce font size or increase margins
{{page}} shows literally Make sure it's in header_html or footer_html, not body_html
Flexbox not working in header/footer Use "engine": "chromium" for flexbox support
Header/footer not aligned with body Check margin_left/margin_right values match expectations

Template Syntax

Templates use a Handlebars-like syntax for dynamic content:

Variables

<p>Hello, {{customer.name}}</p>
<p>Order #{{order.id}}</p>

Loops

{{#each items}}
  <tr>
    <td>{{description}}</td>
    <td>{{quantity}}</td>
    <td>{{formatCurrency unit_price "USD"}}</td>
  </tr>
{{/each}}

Conditionals

{{#if discount}}
  <p>Discount: {{formatCurrency discount "USD"}}</p>
{{/if}}

{{#if premium}}
  <p>Premium member</p>
{{else}}
  <p>Standard member</p>
{{/if}}

Loop Variables

VariableDescription
@indexCurrent iteration index (0-based)
@firstTrue if first iteration
@lastTrue if last iteration

Built-in Helpers

HelperExampleOutput
formatCurrency{{formatCurrency 99.99 "USD"}}$99.99
formatDate{{formatDate date "M j, Y"}}Jan 15, 2024
formatNumber{{formatNumber 1234.5 2}}1,234.50
uppercase{{uppercase text}}TEXT
lowercase{{lowercase text}}text
multiply{{multiply qty price}}150
add{{add a b}}Sum
subtract{{subtract a b}}Difference
pageBreak{{pageBreak}}Forces page break after
pageBreakBefore{{pageBreakBefore}}Forces page break before
currentDate{{currentDate "Y-m-d"}}2024-01-15

Page Breaks

Control where page breaks occur in your PDF documents using the page break helpers. This is essential for multi-page reports, sections, or any document where you want content to start on a new page.

Available Helpers

HelperDescription
{{pageBreak}}Forces content after this point to start on a new page
{{pageBreakBefore}}Forces a new page before this point

Basic Example

Split your document into separate pages:

<h1>Section 1: Introduction</h1>
<p>Content for the first section...</p>

{{pageBreak}}

<h1>Section 2: Analysis</h1>
<p>This content will start on a new page...</p>

{{pageBreak}}

<h1>Section 3: Conclusion</h1>
<p>This content will also start on a new page...</p>

Page Breaks in Loops

Add page breaks between items in a loop, but not after the last item:

{{#each sections}}
  <div class="section">
    <h1>{{title}}</h1>
    <p>{{content}}</p>
  </div>
  {{#unless @last}}{{pageBreak}}{{/unless}}
{{/each}}

Conditional Page Breaks

Only add a page break when a condition is met:

{{#if appendix}}
  {{pageBreak}}
  <h1>Appendix</h1>
  <p>{{appendix}}</p>
{{/if}}

Multi-Part Reports

Example of a structured report with page breaks:

<!-- Cover Page -->
<div class="cover-page">
  <h1>{{report.title}}</h1>
  <p>Prepared for: {{client.name}}</p>
  <p>Date: {{formatDate report.date "F j, Y"}}</p>
</div>

{{pageBreak}}

<!-- Executive Summary -->
<h2>Executive Summary</h2>
<p>{{report.summary}}</p>

{{pageBreak}}

<!-- Detailed Findings -->
{{#each report.findings}}
  <h2>{{title}}</h2>
  <p>{{description}}</p>
  {{#unless @last}}{{pageBreak}}{{/unless}}
{{/each}}

{{pageBreak}}

<!-- Recommendations -->
<h2>Recommendations</h2>
{{#each report.recommendations}}
  <p>{{@index}}. {{this}}</p>
{{/each}}

CSS Alternative

You can also use CSS for page break control in your styles_css:

/* Force page break after an element */
.section {
  page-break-after: always;
}

/* Force page break before an element */
.new-chapter {
  page-break-before: always;
}

/* Prevent page break inside an element */
.keep-together {
  page-break-inside: avoid;
}
Tip: Use page-break-inside: avoid on elements like tables or cards to prevent them from being split across pages.

CSS Support by Engine

Different rendering engines support different CSS features. Use this reference to choose the right engine for your template.

Layout

CSS Featurewkhtmltopdfchromium
display: block/inlineYesYes
display: flexLimited/BrokenYes
display: gridNoYes
float / clearYesYes
position: absolute/relativeYesYes
gap (flexbox/grid)NoYes

Visual

CSS Featurewkhtmltopdfchromium
border-radiusYesYes
box-shadowYesYes
linear-gradientPartialYes
var(--custom) CSS variablesNoYes
calc()BasicYes
aspect-ratioNoYes

Content

Featurewkhtmltopdfchromium
TablesYesYes
Images (PNG, JPG, SVG)YesYes
<canvas> elementNoYes
Chart.js chartsNoYes
Web fonts (@font-face)YesYes
JavaScript (ES6+)ES5 onlyYes

Example: Chart.js with Chromium

To render Chart.js charts, use the chromium engine:

<!-- Template body_html -->
<canvas id="myChart" width="400" height="200"></canvas>
<script src="https://cdn.jsdelivr.net/npm/chart.js"></script>
<script>
  new Chart(document.getElementById('myChart'), {
    type: 'bar',
    data: {
      labels: {{json labels}},
      datasets: [{
        label: 'Sales',
        data: {{json values}},
        backgroundColor: '#3b82f6'
      }]
    }
  });
</script>
// API request
{
  "template": "sales-chart",
  "data": {
    "labels": ["Jan", "Feb", "Mar"],
    "values": [12, 19, 8]
  },
  "engine": "chromium"
}

Performance Comparison

Metricwkhtmltopdfchromium
Simple 1-page PDF~200ms~800ms
Complex 10-page PDF~500ms~1500ms
Memory usage~50MB~200MB
Cold startFastSlower (browser init)

Times are approximate and vary based on content complexity.

Advanced PDF Template

The Advanced PDF template is a powerful, flexible template that uses the Chromium rendering engine. It's designed to handle complex layouts that aren't possible with basic PDF generators.

Key Features

Flexbox Layouts
Complex alignment, centering, spacing
CSS Grid
Multi-column layouts, dashboards
Chart.js Charts
Bar, line, pie, doughnut, radar

Use Cases

The Advanced PDF template can be customized for many different applications:

Use CaseDescriptionKey Features Used
Business Dashboards Executive summaries, KPI reports, quarterly reviews Charts, metrics grid, progress bars
Analytics Reports Website analytics, marketing reports, sales funnels Charts, data tables, timeline
Assessment Results Personality profiles, skill assessments, evaluations Progress bars, radar charts, sections
Financial Statements Profit/loss, balance sheets, investment reports Tables, charts, metrics grid
Project Status Sprint reports, milestone tracking, team updates Timeline, progress bars, tables
Product Catalogs Image galleries, spec sheets, lookbooks Grid layouts, flexbox, modern CSS

Example: Dashboard Report

curl -X POST https://pdfmodule.com/api/v1/render \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "template": "advanced-pdf",
    "engine": "chromium",
    "data": {
      "title": "Sales Dashboard",
      "subtitle": "Q4 2024 Performance Overview",
      "primary_color": "#3b82f6",
      "secondary_color": "#8b5cf6",
      "metrics": [
        {"value": "$1.2M", "label": "Revenue", "change": "+15%", "change_type": "positive"},
        {"value": "847", "label": "New Customers", "change": "+23%", "change_type": "positive"}
      ],
      "chart": {
        "title": "Monthly Sales",
        "type": "bar",
        "labels": ["Jan", "Feb", "Mar", "Apr"],
        "data": [45, 62, 78, 91]
      }
    }
  }'

Example: Assessment Report

{
  "template": "advanced-pdf",
  "engine": "chromium",
  "data": {
    "title": "Leadership Assessment",
    "subtitle": "Comprehensive skill evaluation for Jane Smith",
    "icon": "👤",
    "primary_color": "#10b981",
    "secondary_color": "#059669",
    "metrics": [
      {"value": "92", "label": "Overall Score"},
      {"value": "A+", "label": "Rating"},
      {"value": "Top 5%", "label": "Percentile"}
    ],
    "progress": {
      "title": "Competency Scores",
      "items": [
        {"label": "Communication", "value": 95},
        {"label": "Problem Solving", "value": 88},
        {"label": "Leadership", "value": 92},
        {"label": "Teamwork", "value": 85}
      ]
    },
    "chart": {
      "type": "radar",
      "title": "Skill Profile",
      "labels": ["Strategy", "Execution", "Innovation", "People", "Results"],
      "data": [90, 85, 78, 92, 88]
    }
  }
}

Example: Analytics Report

{
  "template": "advanced-pdf",
  "engine": "chromium",
  "data": {
    "title": "Website Analytics",
    "subtitle": "Traffic and conversion analysis for December 2024",
    "icon": "📈",
    "primary_color": "#f59e0b",
    "secondary_color": "#d97706",
    "metrics": [
      {"value": "124K", "label": "Visitors"},
      {"value": "3.2%", "label": "Conversion Rate"},
      {"value": "2:34", "label": "Avg. Session"},
      {"value": "42%", "label": "Bounce Rate"}
    ],
    "chart": {
      "type": "line",
      "title": "Daily Traffic",
      "labels": ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"],
      "data": [4200, 4800, 5100, 4900, 5500, 3200, 2800],
      "fill": true
    },
    "table": {
      "title": "Top Pages",
      "headers": ["Page", "Views", "Bounce Rate", "Conversions"],
      "rows": [
        ["/pricing", "12,450", "28%", "892"],
        ["/features", "9,823", "35%", "456"],
        ["/demo", "7,234", "22%", "678"]
      ]
    }
  }
}

Customization Options

ParameterDescriptionExample
primary_colorMain brand color (hex)#3b82f6
secondary_colorAccent color for gradients#8b5cf6
iconEmoji or icon for hero section📊, 🎯, 📈
chart.typeChart.js chart typebar, line, pie, doughnut, radar
chart.fillFill area under line chartstrue / false

Chart Types

The Advanced PDF template supports all Chart.js chart types:

  • bar - Compare values across categories
  • line - Show trends over time
  • pie / doughnut - Show proportions of a whole
  • radar - Compare multiple variables (great for assessments)
  • polarArea - Similar to pie but with equal angles
Important: Always use "engine": "chromium" when rendering the Advanced PDF template. The default wkhtmltopdf engine cannot render flexbox, CSS grid, or canvas charts.