Appearance
Template and Payload
Press supports splitting a document into two parts: a template that defines the design, and a payload that provides the content. This separation is the key to using Press at scale -- store a template once and generate thousands of documents by sending different payloads.
How It Works
A template contains the layout, styles, components, and page definitions:
xml
<!-- Template: stored on the platform -->
<press>
<document format="A4" page-margin="2cm">
<page>
<frame direction="row" space-after-desired="24pt">
<frame width="fill">
<frame font-size="10pt">To: {{ data.recipient }}</frame>
<frame font-size="10pt">Date: {{ data.date }}</frame>
</frame>
<img src="logo" max-height="40pt" />
</frame>
<flow name="body" />
<frame space-before-desired="24pt">
<p>Yours sincerely,</p>
<p font-style="bold">{{ data.sender }}</p>
</frame>
</page>
</document>
<assets>
<images>
<logo>https://examples.papermill.io/papermill_logo.png</logo>
</images>
</assets>
<styles>
<document>
<font>Inter</font>
<font-size>10pt</font-size>
<line-height>1.5</line-height>
</document>
</styles>
</press>A payload provides just the parts that change:
xml
<!-- Payload: sent via API -->
<press>
<flows>
<body type="markdown">
Thank you for your application to the Graduate Programme.
I'm delighted to confirm that you have been accepted. Your start
date is 1 September 2026. Please find enclosed the onboarding
documents for your review.
We look forward to welcoming you to the team.
</body>
</flows>
<data type="json">
{
"recipient": "Dr. A. Patel",
"sender": "R. Whitfield, HR Director",
"date": "15 January 2026"
}
</data>
</press>Merging Rules
When Press receives both a template and a payload, it merges them:
| Top-Level Element | Merge Behaviour |
|---|---|
<flows> | Payload flows replace template flows with the same name. New flows are added. |
<data> | Merged shallowly. Payload fields override template fields with the same key. |
<components> | Merged. Payload components are added to or override template components. |
<styles> | Template styles are used. Payload styles are merged in. |
<assets> | Template assets are used. Not presently overridden by payloads. |
<document> | Template document structure is used. Not overridden. |
<pages> | Template page definitions are used. Not overridden. |
Data Merging in Detail
Template:
json
{ "currency": "£", "tax_rate": 20, "company": "Default Corp" }Payload:
json
{ "company": "Meridian Consulting", "client": "Helena Torres" }Result:
json
{ "currency": "£", "tax_rate": 20, "company": "Meridian Consulting", "client": "Helena Torres" }The payload's company wins, template-only fields (currency, tax_rate) are preserved, and new fields (client) are added.
Using Template and Payload via the API
- Create your template on the Papermill platform
- Copy the template ID from the editor URL
- Send a payload via the API with the template ID:
javascript
const payload = `
<press>
<flows>
<body>Thank you for your application...</body>
</flows>
<data>
<recipient>Dr. A. Patel</recipient>
<sender>R. Whitfield</sender>
<date>15 January 2026</date>
</data>
</press>
`
const response = await fetch(`https://api.papermill.io/v2/pdf?template_id=${templateId}`, {
method: 'POST',
headers: {
'Content-Type': 'text/xml',
'X-API-Key': apiKey,
},
body: payload,
})Benefits
- Designers control the template: layout, fonts, colours, page structure
- Developers control the payload: content, data, conditional sections
- AI models can generate markdown payloads without needing to understand the template structure
- One template generates unlimited variations by changing the payload
Best Practices
Put defaults in the template. If most invoices use GBP, set "currency": "£" in the template's <data>. Payloads only need to override it when the currency differs.
Use asset data for constants. Values that should never change (company logos, legal text) go in <assets><data>. These aren't affected by payload merging.
Keep payloads minimal. Only send the data and flows that change. The template handles everything else.
Use markdown flows for AI-generated content. AI models produce clean markdown. The template handles all formatting and layout.