PDF Document
Generate a branded PDF document (invoice, report, letter) from content only. Branding comes from the project PDF Layout. Returns a stored document with a signed download URL.
Endpoints (3)
Render a branded PDF from content and store it. The author supplies only content; layout/branding is applied automatically from the project PDF Layout.
| Field | Type | Required | Description |
|---|---|---|---|
title |
string | ✓ Yes | Document title (heading). |
subtitle |
string | No | Optional subtitle under the title. |
image_url |
string | No | Optional hero/figure image URL shown at the top of the body. |
blocks |
array | No | Content blocks in order. Each: {"type":"text","content":"..."} or {"type":"table","headers":["A","B"],"rows":[["1","2"]]} or {"type":"image","url":"...","caption":"..."}. |
filename |
string | No | Optional file name / slug for the stored document (without .pdf). Defaults to a generated name. |
return_base64 |
boolean | No | If true, also return the PDF as base64 in the response (for inline download/preview). |
letterhead |
boolean | No | If true, strip all branding chrome (logo/company header, colored rule, note, footer) so the PDF prints on PRE-PRINTED stationery. A top margin is left blank for the pre-printed letterhead. |
letterhead_top_mm |
integer | No | Top margin in mm to reserve for the pre-printed letterhead (only used when letterhead=true). Default 45. |
store |
boolean | No | Whether to archive the PDF to the documents bucket (do-private). Default true. Set false to render in-memory and return ONLY base64 without persisting anything (e.g. for an email attachment). |
Render a project-defined HTML template (PAPI asset) to PDF with full data-binding via the platform template engine: {{var}} (HTML-escaped), {{#if}}/{{#else}}, nested {{#each}}, filter chains incl. money_eur (cents → "€ 1.234,56"), vat_incl:21 (VAT from a VAT-inclusive amount), date (default d-m-Y), number, currency, divide. The template controls 100% of the layout (own CSS and @page margins) — no platform branding is applied. Use for invoices, packing slips, quotes on custom or pre-printed stationery. In an order_events iapi_chain, pass prior-step data raw, e.g. "data": {"order": "{{steps.0.result.order}}"}. External resources: relative URLs resolve to the project's own CDN; only data: URIs and https://cdn.websitepublisher.ai assets are fetched, other URLs are stripped. Blocked external URLs are reported back in the response as data.blocked_assets so the template author can fix them.
| Field | Type | Required | Description |
|---|---|---|---|
template_slug |
string | ✓ Yes | PAPI asset path of the HTML template, e.g. "templates/factuur-briefpapier.html". Must end in .html. |
data |
array | No | Root context object for the template. Keys become top-level template variables ({{order.total_cents}}, {{#each order.lines}}). Default {}. |
report |
string | No | Optional server-side data source: a report_builder identifier ([a-z0-9_-], max 64). The platform loads report_row for that report itself (sorted on sort_order), so private report data never passes through a page or chain tokens. Template context: {{report.key}}, {{report.title}}, {{report.generated_at}} (ISO 8601, Europe/Amsterdam), {{report.generated_time}} (H:i) and {{#each report.rows}} with grp, sort_order, kind, label, cnt, tone, side, col1, col2, col3, flag. Merged with data; data.report is then reserved. Owner authority only (dashboard, MCP, scheduled task, chain), never a visitor session. Errors: REPORT_INVALID, REPORT_FORBIDDEN, REPORT_NOT_FOUND, REPORT_EMPTY, REPORT_LOAD_FAILED, REPORT_KEY_CONFLICT. Response data adds report_rows. |
filename |
string | No | Optional file name / slug for the stored document (without .pdf). Defaults to the template name. |
return_base64 |
boolean | No | If true, also return the PDF as base64 in the response (for chain steps / email attachments). |
store |
boolean | No | Whether to archive the PDF to the documents bucket (do-private). Default true. Set false to render in-memory and return ONLY base64 without persisting anything. |
letterhead_top_mm |
integer | No | Optional convenience: reserve a top margin in mm for pre-printed stationery via an injected @page rule. The template's own @page CSS overrides this; defining @page in the template is preferred. |
Render a published project page to PDF, server-side. Runs the same pipeline the visitor sees for fragments (<!--#wps-include -->), i18n tokens and MAPI SSR (wps-mapi), so the PDF contains exactly the server-rendered data of the live page. NO JavaScript is executed: anything the page builds client-side will not appear in the PDF. Analytics, tracking pixels, the powered-by badge and SEO tags are deliberately not injected. Use for scheduled reports and page-as-PDF exports.
| Field | Type | Required | Description |
|---|---|---|---|
page_slug |
string | ✓ Yes | Page path as used on the site, e.g. "rapport" or "admin/overzicht". Leading slash optional. Clean URL — do NOT append .html. |
margin_mm |
integer | No | Paper margin in mm via an injected @page rule. Default 0 (borderless). The page's own @page CSS overrides it. |
lang |
string | No | Language for i18n token replacement. Default "en" (no-op). |
filename |
string | No | Optional file name / slug for the stored document (without .pdf). Defaults to the page slug. |
return_base64 |
boolean | No | If true, also return the PDF as base64 in the response (for chain steps / email attachments). |
store |
boolean | No | Whether to archive the PDF to the documents bucket (do-private). Default true. Set false to render in-memory and return ONLY base64 without persisting anything. |
MCP Tool Names
When using this integration through an AI assistant (Claude, ChatGPT, Cursor, etc.), the endpoints are available as MCP tools:
| Endpoint | MCP Tool Name |
|---|---|
| generate | pdf_document_generate |
| render-template | pdf_document_render_template |
| render-page | pdf_document_render_page |
Website