options, calculations, title_block, and so on) don’t apply here. The {{ }} syntax is the same.
Setting up a template
Admins pick order form templates in Admin > Contracts > Order Forms & E-signature. There is one template per deal type:
Connect Google Docs first, then use Pick from Drive to choose the template for each deal type. Order form templates are Google Docs; Microsoft Word templates are not available for order forms yet.
Template syntax
Loops repeat table rows, so place a loop inside a table: the rows between
#each and /each print once per item. Outside a loop, reach into a list by position, starting at 0: {{ phases.0.total }} is the first phase’s total.
A blank value reads as false in #if, so a conditional around a field hides its section when the field is empty.
“Term” means two different things on an order form.
contract_term is the length of the contract, in months. term.<key> is a legal clause from your Terms library. They are unrelated variables — see Contract length and Terms.Variable reference
A variable marked nullable can be blank. Dates print as words, for example “January 15, 2026”. Amounts print formatted in the order’s currency, for example “$12,000.00”.Order
Whole-contract totals
Terms
Billing
Owner
The user who owns the order. Empty when the order has no owner, so wrap it in{{ #if(owner) }} if that can happen.
Company
The customer company on the order. Empty when no company is linked.Option
The quote option the order was converted from.CRM
The CRM record (Salesforce or HubSpot) linked to the order’s opportunity. Every field prints blank when the opportunity has no CRM link.Phases
phases is the order’s list of phases, in sequence order. Loop it with {{ #each(phases) as phase }}, or reach one by position with phases.0, phases.1, and so on.
Lines
Each item inphase.lines, phase.one_time_lines, phase.recurring_lines, or a bundle’s lines. The examples loop them as line.
Contract length
{{ contract_term }} prints the contract length in months, as a number: write the unit in the template ({{ contract_term }} months).
It prints the same length the order page shows, worked out from the order’s start and end dates. A 12-month order from January 1, 2026 to December 31, 2026 prints 12; a partial month counts as a full one. When the order has a contract term stored on it, the stored term wins over the dates. It is blank only when the order has no stored term and is missing a start or end date.
contract_term has nothing to do with the Terms library. To print a legal clause, use term.<key>, below.
Terms
Each term in your Terms library has a variable,term.<key>, named by the term’s template variable key. It prints that term’s copy on its own, so you can place one term anywhere in the order form and show a whole section only when the term is on the order:
- The option’s terms, not the whole quote’s.
term.<key>on an order form covers the terms on the option the order was converted from. A term on another option of the same quote is blank. - Read from the published version. The terms come from the same published snapshot of the quote as the rest of the order. Editing the term’s copy in Admin, or editing the quote after the order is created, does not change what the order form prints.
- Give each term a paragraph of its own. A term’s copy is rich text, so place
{{ term.payment_terms }}in its own paragraph, outside a table row loop.
All terms at once
To print every term the option carries in one place, use{{ terms_html }}. Each term prints with its number and name as a bold heading, followed by its copy, in the same order the quote lists them:
term.<key>: it covers only the option the order was converted from, it reads from the published snapshot, and it needs a paragraph of its own. Use terms_html when the order form should carry whatever terms the rep chose; use term.<key> when the template places specific terms in specific sections.
special_terms is separate: it prints the order’s special terms field, as plain text.
Custom fields
Replace<key> with the custom field’s key, for example {{ company.custom_fields.region }}. Single and multi-select fields print their labels; multi-select labels are joined with ; . A field with no value prints blank, so {{ #if(company.custom_fields.region) }} … {{ /if }} hides a section when the field is unset.
Inside a line loop, write {{ line.custom_fields.po_line }} or {{ line.product.custom_fields.sku_family }}.
Product descriptions
To print what each product includes, loop the lines and print each product’s name and description:{{ #if(line.product.description) }} … {{ /if }} hides whatever sits between them for that product.
List price and discounts
An order line holds the price it sold at and the published quote line it was converted from. Its list price and discount are read from that quote line, so a products table can print them beside the price:list_price less the discount is unit_price. A line sold at its list price prints “0%” and a zero amount; a line sold above it prints a negative discount.
For totals, print phase.total_discount and total_savings rather than adding up line rows: they count a bundle once and follow the phase totals, so a partial year is prorated. A row with no quote line — an order not converted from a published quote — prints its list price and discount blank, and so do the totals when there is no quote year to read them from. {{ #if(line.list_price) }} … {{ /if }} hides whatever sits between them.
Bundles
Loopingphase.lines prints one row per bundle and per standalone line. To print a bundle’s components, loop its lines inside that loop. Standalone lines have no lines, so this rate list prints only components:
phase.annual_contract_value, phase.recurring_total, or phase.one_time_total rather than adding up line rows, and total_contract_value for the whole order.
One-time and recurring lines
To print one-time and recurring charges in separate tables, loopphase.one_time_lines and phase.recurring_lines instead of phase.lines. Together they hold the same top-level rows as phase.lines, each exactly once. A line is one-time when its billing type is one_time; every other line, usage included, is recurring. Only the top-level rows are split: a one-time bundle with a recurring component stays in one_time_lines, and the component stays in the bundle’s own lines.
unit_price and total_price print its per-unit rate (for example “$2.00 per API Call”), and phase.recurring_total does not include it.
Example
#each and /each in the rows it repeats.
What’s next
Document Generation
Quote templates, the full syntax reference, and placing individual terms.
Terms
Manage the legal clauses an order form can print by key.
Order Overview
Understand the order an order form is generated from.
Order Phase
How an order’s phases split the contract into periods.

