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:
| Code | Description |
|---|---|
200 | Success |
201 | Created |
400 | Bad Request - Invalid parameters |
401 | Unauthorized - Invalid API key |
404 | Not Found |
422 | Validation Error |
429 | Rate Limit Exceeded |
500 | Server Error |
Error responses include a JSON body:
{
"error": "Template not found",
"errors": {
"field_name": ["Error message"]
}
}
Render PDF
Request Body
| Parameter | Type | Description |
|---|---|---|
template * | string | Template slug |
data * | object | Data to render in template |
version | integer | Specific template version (default: latest) |
engine | string | Rendering engine: wkhtmltopdf, chromium, or auto. See Rendering Engines. |
page_size | string | Override page size: A4, Letter, Legal |
orientation | string | Override orientation: portrait or landscape |
margin_top | integer | Override top margin in mm |
margin_right | integer | Override right margin in mm |
margin_bottom | integer | Override bottom margin in mm |
margin_left | integer | Override left margin in mm |
line_height | number | Override 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:
| Header | Description |
|---|---|
Content-Disposition | Filename for the PDF |
X-Document-UUID | UUID to retrieve document metadata |
X-Render-Engine | Engine used (wkhtmltopdf or chromium) |
Validate
Request Body
| Parameter | Type | Description |
|---|---|---|
template * | string | Template slug |
data * | object | Data 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
| Engine | Best For | CSS 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
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": []
}
]
}
Request Body
| Parameter | Type | Description |
|---|---|---|
template * | string | Template 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
Create Template Request
| Parameter | Type | Description |
|---|---|---|
name * | string | Template name |
body_html * | string | HTML body content |
header_html | string | Header HTML (every page). Use {{page}} and {{pages}} for page numbers. |
footer_html | string | Footer HTML (every page). Use {{page}} and {{pages}} for page numbers. |
styles_css | string | CSS styles |
page_size | string | A4, Letter, Legal (default: A4) |
orientation | string | portrait, landscape |
margin_top | integer | Top margin in mm |
margin_right | integer | Right margin in mm |
margin_bottom | integer | Bottom margin in mm |
margin_left | integer | Left margin in mm |
schema | object | JSON schema for data validation |
Documents
Query Parameters
| Parameter | Type | Description |
|---|---|---|
page | integer | Page number (default: 1) |
per_page | integer | Results per page (default: 20, max: 100) |
Account
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
Analyze PDFs for print issues
Add bleed, convert colors, flatten
Define your own check rules
Available Checks
| Check | Description |
|---|---|
geometry | Page boxes (TrimBox, BleedBox), bleed margins, page dimensions |
fonts | Font embedding, subsetting, font types |
colors | Color spaces (RGB, CMYK, spot colors), ICC profiles |
images | Image resolution (PPI), compression, color mode |
transparency | Transparency usage, blend modes |
cutting | Cut contour / die line detection |
Available Fixes
| Fix | Description |
|---|---|
smart_bleed | Intelligently extend content to create bleed |
add_bleed | Add bleed by mirroring/extending edges |
set_boxes | Set TrimBox, BleedBox, and other PDF page boxes |
crop_marks | Add trim marks, registration marks, color bars |
resize | Resize pages to standard sizes (A4, Letter, etc.) |
convert_cmyk | Convert RGB colors to CMYK for print |
convert_rgb | Convert CMYK colors to RGB for screen |
convert_gray | Convert to grayscale |
flatten | Flatten transparency |
embed_fonts | Embed all fonts in the PDF |
optimize | Optimize PDF for size/quality |
spot_to_process | Convert spot colors to process (CMYK) |
cut_contour | Generate cut contour / die line |
Check PDF
Request (multipart/form-data)
| Parameter | Type | Description |
|---|---|---|
file or pdf | file | PDF file to analyze (required unless pdf_url provided) |
pdf_url | string | URL to PDF file (alternative to file upload) |
checks | string | Comma-separated checks to run: geometry,fonts,colors,images,transparency,cutting. Default: all |
profile | string | Profile slug to use (system or custom). See Profiles |
config | JSON string | Custom 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
| Severity | Description |
|---|---|
FAIL | Critical issue that must be fixed for print production |
WARN | Potential issue that should be reviewed |
INFO | Informational finding, usually acceptable |
Fix PDF
Request (multipart/form-data)
| Parameter | Type | Description |
|---|---|---|
file or pdf * | file | PDF file to fix |
pdf_url | string | URL to PDF file (alternative to file upload) |
fixes * | string | Comma-separated fixes to apply |
Bleed Options
| Parameter | Type | Default | Description |
|---|---|---|---|
bleed_mm | number | 3.0 | Bleed size in millimeters |
bleed_method | string | mirror | Bleed method: mirror, extend, clone |
Page Box Options (set_boxes fix)
| Parameter | Type | Description |
|---|---|---|
trim_inset_mm | number | Inset from MediaBox for TrimBox |
bleed_outset_mm | number | Outset from TrimBox for BleedBox |
Crop Marks Options (crop_marks fix)
| Parameter | Type | Default | Description |
|---|---|---|---|
add_trim_marks | boolean | true | Add trim/cut marks at corners |
add_registration | boolean | true | Add registration targets |
add_color_bars | boolean | false | Add CMYK color bars |
mark_offset_mm | number | 3.0 | Offset of marks from trim edge |
Resize Options (resize fix)
| Parameter | Type | Description |
|---|---|---|
target_size | string | Target size: A4, A3, A5, Letter, Legal, custom |
custom_width_mm | number | Custom width (when target_size=custom) |
custom_height_mm | number | Custom height (when target_size=custom) |
fit_mode | string | Fit mode: fit, fill, stretch |
orientation | string | Force orientation: portrait, landscape, auto |
Color Options (convert_cmyk, convert_rgb, convert_gray fixes)
| Parameter | Type | Description |
|---|---|---|
target_colorspace | string | Target: cmyk, rgb, gray |
icc_profile | string | ICC profile to use: fogra39, gracol, swop, srgb |
Optimization Options (optimize fix)
| Parameter | Type | Description |
|---|---|---|
optimize_preset | string | Preset: screen, ebook, printer, prepress |
Cut Contour Options (cut_contour fix)
| Parameter | Type | Default | Description |
|---|---|---|---|
cut_source | string | content | Source for contour: content, trimbox, shape |
cut_shape | string | rectangle | Shape when cut_source=shape: rectangle, rounded, circle, oval |
cut_inset_mm | number | 0 | Inset from detected edge |
cut_corner_radius_mm | number | 5 | Corner radius for rounded rectangles |
cut_stroke_width_mm | number | 0.25 | Stroke width of cut line |
cut_spot_name | string | CutContour | Spot color name for the cut line |
cut_output_mode | string | spot | Output 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
| Profile | Description | Use Case |
|---|---|---|
print_standard | Standard print requirements (3mm bleed, 300 PPI, CMYK preferred) | Commercial printing |
print_strict | Strict requirements (5mm bleed, 300 PPI required, CMYK only) | High-quality printing |
web | Web/screen requirements (no bleed, RGB allowed, 150 PPI) | Digital distribution |
archive | Archival requirements (PDF/A compliance, fonts embedded) | Long-term storage |
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
}
]
}
Example: Get Profile
curl -X GET https://pdfmodule.com/api/v1/preflight/profiles/print_standard \
-H "Authorization: Bearer YOUR_API_KEY"
Request Body
| Parameter | Type | Default | Description |
|---|---|---|---|
name * | string | - | Profile name |
description | string | - | Profile description |
is_default | boolean | false | Set as default profile |
bleed_mm | number | 3.0 | Required bleed in mm |
bleed_required | boolean | true | Is bleed required? |
min_resolution_ppi | integer | 300 | Minimum image resolution (FAIL below this) |
warn_resolution_ppi | integer | 150 | Warning threshold for resolution |
color_mode | string | cmyk_preferred | Color mode: cmyk_required, cmyk_preferred, rgb_allowed, any |
allow_spot_colors | boolean | true | Allow spot/Pantone colors |
allow_rgb | boolean | true | Allow RGB colors |
fonts_embedded_required | boolean | true | Require all fonts embedded |
fonts_subset_allowed | boolean | true | Allow font subsetting |
allow_transparency | boolean | true | Allow transparency |
max_image_resolution_ppi | integer | 1200 | Maximum 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
}'
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
}'
Example: Delete Profile
curl -X DELETE https://pdfmodule.com/api/v1/preflight/profiles/magazine-print \
-H "Authorization: Bearer YOUR_API_KEY"
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
| Parameter | Default | Description |
|---|---|---|
margin_top | 10mm | Space from top edge to header/content. Increase this when using headers. |
margin_bottom | 10mm | Space from bottom edge to footer/content. Increase this when using footers. |
margin_left | 10mm | Space from left edge. Applied to body, header, and footer. |
margin_right | 10mm | Space from right edge. Applied to body, header, and footer. |
Recommended Margin Values
| Scenario | margin_top | margin_bottom | left/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
| Size | Dimensions | Common Use |
|---|---|---|
A4 (default) | 210 × 297 mm | International standard, most documents |
Letter | 216 × 279 mm | US standard |
Legal | 216 × 356 mm | Legal documents (US) |
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
| Variable | Description |
|---|---|
@index | Current iteration index (0-based) |
@first | True if first iteration |
@last | True if last iteration |
Built-in Helpers
| Helper | Example | Output |
|---|---|---|
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
| Helper | Description |
|---|---|
{{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;
}
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 Feature | wkhtmltopdf | chromium |
|---|---|---|
display: block/inline | Yes | Yes |
display: flex | Limited/Broken | Yes |
display: grid | No | Yes |
float / clear | Yes | Yes |
position: absolute/relative | Yes | Yes |
gap (flexbox/grid) | No | Yes |
Visual
| CSS Feature | wkhtmltopdf | chromium |
|---|---|---|
border-radius | Yes | Yes |
box-shadow | Yes | Yes |
linear-gradient | Partial | Yes |
var(--custom) CSS variables | No | Yes |
calc() | Basic | Yes |
aspect-ratio | No | Yes |
Content
| Feature | wkhtmltopdf | chromium |
|---|---|---|
| Tables | Yes | Yes |
| Images (PNG, JPG, SVG) | Yes | Yes |
<canvas> element | No | Yes |
| Chart.js charts | No | Yes |
| Web fonts (@font-face) | Yes | Yes |
| JavaScript (ES6+) | ES5 only | Yes |
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
| Metric | wkhtmltopdf | chromium |
|---|---|---|
| Simple 1-page PDF | ~200ms | ~800ms |
| Complex 10-page PDF | ~500ms | ~1500ms |
| Memory usage | ~50MB | ~200MB |
| Cold start | Fast | Slower (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
Complex alignment, centering, spacing
Multi-column layouts, dashboards
Bar, line, pie, doughnut, radar
Use Cases
The Advanced PDF template can be customized for many different applications:
| Use Case | Description | Key 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
| Parameter | Description | Example |
|---|---|---|
primary_color | Main brand color (hex) | #3b82f6 |
secondary_color | Accent color for gradients | #8b5cf6 |
icon | Emoji or icon for hero section | 📊, 🎯, 📈 |
chart.type | Chart.js chart type | bar, line, pie, doughnut, radar |
chart.fill | Fill area under line charts | true / 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
"engine": "chromium" when rendering the Advanced PDF template. The default wkhtmltopdf engine cannot render flexbox, CSS grid, or canvas charts.