Skip to main content Link Search Menu Expand Document Toggle dark mode Copy Code (external link)
paperwork.help

Templates and generating

Authoring a template

Ask for the document you want:

Create an invoice template with fields for date and reference number, and a line items data source

The agent works out the document type, a short name for it, the fields (single values you supply each time) and the data sources (JSON it loops over), and asks where to keep the template. It then creates three files:

templates/
└── invoice/
    ├── invoice.json   the template config
    ├── invoice.html   the layout, with {{ }} bindings
    └── invoice.css    the styles

The config follows the Config file format. Layouts, styles and data are referenced by relative path as Source items, so each file stays readable and editable on its own, and the agent validates the result with paperwork validate.

Where templates are kept

Scope Path Use for
Project ./templates/<name>/ Templates for one project, which travel with its repository.
Global ~/.paperwork/templates/<name>/ Templates shared by every project on this machine.

Generating a document

Ask for it with your values:

Generate my invoice for Acme Corp using acme-order.json and save it to ~/Documents/Invoices

The agent finds the template and runs the CLI:

paperwork generate --config templates/invoice/invoice.json \
  --data customer=acme-order.json \
  --field date=2026-03-30 \
  --output ~/Documents/Invoices/acme-march-2026.pdf

Sending the output on

Without --output the PDF goes to standard output, so it can be piped to anything that accepts a file:

Generate the monthly report and upload it to SharePoint

paperwork generate --config templates/monthly-report/monthly-report.json \
  --field month=March --field year=2026 \
  | <your-upload-command> "Finance/Reports/March 2026.pdf"

Binding reference

These are the expressions the agent writes into a layout. The full language is in Paperwork.Reference.

<!-- a field value -->
<p>{{$fields["date"]}}</p>

<!-- a property of a data source -->
<p>{{customer.name}}</p>

<!-- loop over an array -->
{{#each items}}
<tr>
  <td>{{this.description}}</td>
  <td>{{format(this.amount, 'C2')}}</td>
</tr>
{{/each}}

<!-- a condition -->
{{#if customer.isPremium}}
<p>Premium discount applied.</p>
{{/if}}

<!-- a filtered loop -->
<template data-bind="{{selectWhere(items, .type == 'taxable')}}">
  <tr><td>{{.description}}</td></tr>
</template>