Skip to main content

PDF Generator

The PDF Generator turns a template plus data into a PDF and hands your flow a link to the finished file. Use it for invoices, receipts, quotes, certificates, agreements and reports — anything your flow then sends by WhatsApp or email.

Templates live in your workspace and are edited inside this node. Changing how a document looks is something you do in the flow, not something that needs a release.

Use it inside an Agent node so the agent produces a document when it makes sense, or as a standalone Tool node for a fixed, deterministic document.

Adding it to a flow​

In the Tool node's tool picker choose PDF Generator, pick where the document comes from, and provide the data to fill it.

Choosing the document​

DocumentWhen to use it
Saved TemplateAlmost always. A reusable template stored in your workspace, with version history.
Inline HTMLA one-off document, or a first draft you intend to save as a template.

Only your own workspace's templates appear in the list.

The template editor​

Next to Preview PDF you will find Edit Template (when a saved template is selected) or Save as Template (when you are writing HTML inline). Both open the same editor, which has four tabs:

TabWhat goes in it
HTMLThe document body, written in Handlebars. {{placeholders}} are filled from Data.
CSSYour stylesheet. Fonts are embedded for you, so the PDF looks the same everywhere.
DefaultsThe template's own constants — wording, legal paragraphs, signature roles. Your flow's Data is merged over these.
Preview DataSample values used by Preview and by the check that runs when you save.

Preview before you save. The editor's Preview button renders exactly what is in the tabs right now, saved or not — your Preview Data merged over your Defaults, through the same renderer the flow uses. Nothing is written to the template, so you can iterate on wording and layout and only save once it looks right.

Saving validates. The server renders the template for real before storing it. If it cannot produce a PDF, the save is refused and you are told exactly why — the parse error and its line, or the key your HTML reads that Defaults never declares. A template that does not work can never reach a live document. Two other refusals you may meet: a name another template in the workspace already uses, and "too many template renders" if you save or preview more than 30 times in a minute.

Every save is a version. The editor lists previous versions; selecting one restores it. Restoring writes the old content forward as a new version, so nothing in the history is ever overwritten.

Defaults vs Data

Put anything that is the same on every document in Defaults — company wording, standard clauses, rating definitions. Put what changes per document in Data. The merge is deep, so sending meta: { address } from your flow does not erase the other meta values the template supplies.

Inputs​

ParameterDescriptionRequired
DocumentSaved Template or Inline HTML.Yes
TemplateThe saved template to render.When using a template
HTMLHandlebars HTML/CSS written here, using {{variables}} filled from Data.When using HTML
Report DataNone, or Inspection (see below).No
DataHow you supply values: Form (key → value rows) or JSON.Yes
FieldsThe key → value rows that build the data object (Form mode).When Data is Form
JSONA JSON object — best for nested or list data.When Data is JSON
Show Page NumbersTurn off for a one-page document.No
StorageTemporary (removed after a day) or Permanent.No
File NameName for the stored document. Accepts variables.No
Session IDAdvanced. Leave empty — the flow's own session is used. Set it only to report on a different one.No

There is no paper-size input: the template decides its own size (see below). The render always waits for the link, so the next node always has something to send.

The signature page​

A fillable signature page is not part of your HTML — it is a real PDF form appended after the document, so a recipient can type into it and sign. The page footer note is likewise drawn by the page printer rather than by your CSS.

Neither is a node input. Both are part of the document's design, so you author them once in the template editor's Defaults tab, under these keys:

KeyWhat it does
signaturePartiesA row per signer: [{ "role": "Tenant", "name": "" }]. Omit it and no signature page is produced.
declarationTextThe paragraph printed above the signature blocks.
signatureExtraRowsExtra fillable lines — meter readings, an initials line — optionally with a date field, above or below the signatures.
footerNoteText at the bottom-left of every page, beside the page numbers.
pageSizeThe paper this document is printed on: a4 (default), letter, legal, a5, a3… An American invoice is Letter every time it is produced, so it is set here and not on every render.

Because your flow's Data is merged over the template's Defaults, a document that genuinely differs from one render to the next can still set any of these keys in Data (JSON mode). That is the exception; the template is the normal place.

Report Data​

Leave this as None for almost every document: your flow supplies the data, in Data below.

Choose Inspection when the report is built from evidence collected during an inspection. The data is not in your flow — dozens of photographs, captions and ratings live in the inspection record — so the server assembles the report itself and your template lays it out. See Inspection Reports for the fields a template can use.

Choosing Inspection also changes what Data means: those fields become the report's cover (address, tenant, inspector, company, logo), because the body is assembled by the server.

Preview PDF is switched off while Report Data is Inspection. The preview can only build a document from Data, and in this mode the body comes from the inspection session during a real run — so a preview would show you an empty document and look like a broken template. Preview the layout with Report Data on None and sample values, then switch it back.

You do not have to say which inspection: the node is already running inside that session and uses it. Session ID, under Advanced, is there only for the unusual flow that reports on a different session. If neither is available the node stops with a clear message rather than producing an empty report.

Delivery records itself. There is no second node to add. Flowera notices when the document is actually fetched over its link — which is exactly what happens when WhatsApp attaches it to a message, or when the Gmail tool downloads it to attach the file — and records the delivery then. Asking for the same report again still returns the same document; a second PDF is never produced.

Outputs​

A signed URL to the document. Save it in flow state so the next node can send it.

If the render takes unusually long the node returns a render id and pending instead, meaning the document is still being produced — not that it failed. A render that genuinely fails returns failed with a reason, and one that found nothing to report on returns noop, so your flow can tell "wait" from "this is never coming".

Asking for the same inspection report twice returns the same document, with alreadyDelivered. A second PDF is never produced from the same evidence.

Sending the document​

On WhatsApp — feed the URL into a WhatsApp document message.

By email — put the URL in the Gmail tool's Attachment URL field. It downloads the file and attaches it properly, so the recipient gets a real PDF rather than a link. Give it an Attachment File Name so the attachment is named something the recipient recognises.

The attachment URL must be an http(s) address that is either public or Flowera's own — a PDF Generator link is both. Any other private, loopback or internal address is refused, at every redirect it follows (at most five), and the file itself is capped at 18 MB.

Links are short-lived

The returned link is a temporary access token, not a permanent address. Send the document in the same flow run. If you need the file to exist long-term, set Storage to Permanent — that keeps the stored document, not the link.

Example​

Send an order receipt as a PDF

  1. Add a Tool node with PDF Generator.
  2. Set Document to Inline HTML and write a small receipt using {{customerName}}, {{orderNumber}} and {{total}}.
  3. In Data (Form mode) map those keys to the collected order values.
  4. Press Preview PDF to see it, then Save as Template so the next flow can reuse it.
  5. Feed the returned URL into a WhatsApp document message, or into Gmail's Attachment URL.

Tips​

  • Preview early. The preview renders the same way the real document does, including the signature page and the template's paper size.
  • Use JSON mode for lists. If your template loops over items, supply the data as JSON.
  • Keep the returned URL in flow state so the send step can reference it.
  • Bind the Chatflow API credential only if your setup requires the render call to be authenticated.