Template
A template is a versioned document blueprint inside a project, addressed by a URL-safe slug (unique per project). You render against a slug:POST /v1/templates/:slug/render.
Version
Publishing a template snapshots an immutable version (currentVersionNumber). Renders use
the current published version unless you pin one with options.versionNumber. A template with no
published version cannot be rendered (no_published_version).
Variable
A typed merge field. Each variable has a dot-pathkey (customer.name), a dataType, and a
required flag.
dataType | Accepts at render time |
|---|---|
text, longtext | any string |
number, currency | number (numeric strings are coerced) |
date, datetime | ISO string or Date |
boolean | boolean ("true"/"false" coerced) |
image, url | an http(s) URL (z.string().url() — data-URIs are rejected) |
email | a valid email |
Manifest
The variable manifest is the contract a render payload must satisfy:{ variables: VariableDefinition[], loops: LoopDefinition[] }. It is auto-extracted from the
template at publish time — you cannot POST a manifest directly. Read it with
GET /v1/templates/:slug.
Render
A single execution: input data + status + asset. Renders are asynchronous — enqueued on a queue, processed by a worker, uploaded to object storage. Status movesqueued → rendering → succeeded | failed. See Render lifecycle.
Render pipelines
Not every template renders the same way. The worker chooses one of three pipelines based on the published version’s content, and they differ in what they can do (loops, dynamic images). This choice drives whether arrays and signature images work — read Render pipelines before authoring a data-heavy template.Document mode
Block layout via
@react-pdf. No loops, static images.Canvas (Handlebars)
HTML → Puppeteer. Loops and dynamic images.
PDF overlay
Fields stamped onto an uploaded base PDF via pdfme.