Use this reference when creating or troubleshooting a reusable document template in Settings → Documents → Document Templates.
Template fields
| Field | What it controls | Values |
|---|---|---|
| Template Name | The name shown in the template list | Free text |
| Type | The kind of document the template produces | Engagement Letter, Consent Document, Add-on Document |
| Category | An optional label used to organize templates | Free text |
| Content | The document body | Rich text and merge tags inserted from the merge-field picker |
Engagement letter placeholder variables
Engagement letter content uses Mustache field paths, such as {{{client.name}}}, rather than labels such as {{ClientName}}. Insert variables from the Insert Variable picker whenever possible. Letter-content variables use three curly braces on each side so formatted content can render correctly. Engagement-name templates use two curly braces instead; they are a separate context.
The tables below cover the fields documented in the engagement letter data model. Availability depends on your firm's configuration and source data. A field in the data model is not a guarantee that it appears in every template's picker.
Primary client
| Picker label / field | Merge tag | Value inserted |
|---|---|---|
| Name | {{{client.name}}} | Primary client's name |
| Number | {{{client.number}}} | Client number |
| Type | {{{client.client_type}}} | Client type |
| Address | {{{client.address}}} | Client address on one line |
| Address Block | {{{client.address_block}}} | Formatted client address block |
| Signature Block | {{{client.signature_block}}} | Client signature area |
| Initial Block | {{{client.initial_block}}} | Client initials area |
| Notice Period | {{{client.notice_period}}} | Client notice period, or the configured default |
| Account Balance | {{{client.account_balance}}} | Client account balance |
| Fiscal Month | {{{client.fiscal_year_month}}} | Client's fiscal year-end month |
| Fiscal Day | {{{client.fiscal_year_day}}} | Client's fiscal year-end day |
| Created At | {{{client.created_at}}} | Client record creation value |
The Client Address placeholder populates from the primary contact’s address unless a different address contact is selected on the engagement.
Client address components and custom fields are listed separately below. Additional clients use the same client fields inside an additional_clients repeating section.
Engagement contacts
The same contact fields are available for three roles. Choose the prefix that matches the contact you want:
| Contact role | Prefix | Example merge tag |
|---|---|---|
| Primary contact | engagement_primary_contact | {{{engagement_primary_contact.name}}} |
| Secondary contact | engagement_secondary_contact | {{{engagement_secondary_contact.name}}} |
| Billing contact | engagement_billing_contact | {{{engagement_billing_contact.name}}} |
Append one of the following field paths to the role prefix, then enclose the complete path in triple braces.
| Picker label | Field path after the prefix | Value inserted |
|---|---|---|
| Name | name | Contact's full name |
email | Contact's email address | |
| First Name | firstName | Contact's first name; requires extended contact fields |
| Last Name | lastName | Contact's last name; requires extended contact fields |
| Job Title | jobTitle | Contact's job title; requires extended contact fields |
| Title | prefix | Contact's title or prefix; requires extended contact fields |
For example, {{{engagement_billing_contact.email}}} inserts the billing contact's email. Use the picker to preserve exact capitalization in firstName, lastName, and jobTitle.
Address components
Use these fields after client.address_details or a contact role's address_details. For example, {{{client.address_details.city}}} or {{{engagement_primary_contact.address_details.city}}}.
| Picker label | Field path after address_details | Value inserted |
|---|---|---|
| Address Line 1 | address_line_1 | Street address |
| Address Line 2 | address_line_2 | Second address line, when enabled |
| City | city | City |
| State | state | State |
| Zip | zip | Postal code |
| Country | country | Country |
Firm
| Picker label | Merge tag | Value inserted |
|---|---|---|
| Name | {{{firm.name}}} | Firm name |
| Address | {{{firm.address}}} | Firm address |
| Address Block | {{{firm.address_block}}} | Formatted firm address block |
{{{firm.email}}} | Firm email address | |
| Logo | {{{firm.logo}}} | Firm logo |
| Net Terms | {{{firm.net_terms}}} | Configured net payment terms |
| Notice Period | {{{firm.notice_period}}} | Configured default notice period |
Engagement partner
| Picker label | Merge tag | Value inserted |
|---|---|---|
| Name | {{{partner.name}}} | Engagement partner's name |
{{{partner.email}}} | Engagement partner's email address | |
| Job Title | {{{partner.jobTitle}}} | Partner's job title, when extended staff titles are enabled |
| Prefix | {{{partner.prefix}}} | Partner's prefix, when extended staff titles are enabled |
The job-level manager uses the same staff fields inside a jobs repeating section. The older variable reference also lists top-level manager.name and manager.email, but the newer top-level mapping does not; confirm availability before using those paths.
Dates and fiscal year
| Date | Long date merge tag | Short date merge tag | Year-only merge tag |
|---|---|---|---|
| Letter generation date | {{{letter_date.long}}} | {{{letter_date.short}}} | {{{letter_date.year}}} |
| Engagement start date | {{{start_date.long}}} | {{{start_date.short}}} | {{{start_date.year}}} |
| Client fiscal year end | {{{fiscal_year.long}}} | {{{fiscal_year.short}}} | {{{fiscal_year.year}}} |
| Engagement renewal/end date | {{{renewal_date.long}}} | {{{renewal_date.short}}} | {{{renewal_date.year}}} |
Long dates display like January 15, 2026; short dates display like 01/15/26; year-only values display like 2026. Fiscal-year dates combine the engagement's fiscal year with the client's fiscal year-end month and day.
Billing totals across the engagement
These top-level variables aggregate billing information across the engagement's jobs. They are different from billing fields inside a jobs repeating section.
| Picker label | Merge tag | Value inserted |
|---|---|---|
| Minimum Price | {{{billing.minimum_price}}} | Sum of the jobs' minimum prices |
| Prepayment | {{{billing.prepayment}}} | Sum of the jobs' prepayments |
| Minimum Amount | {{{billing.minimum_amount}}} | Aggregated minimum amount |
| Maximum Amount | {{{billing.maximum_amount}}} | Aggregated maximum amount; confirm the exact path in the picker before use because internal references disagree |
Ready-made scope and client lists
These variables generate formatted content rather than a single text value.
| Picker label / field | Merge tag | Value inserted |
|---|---|---|
| Table of Clients & Jobs | {{{scope_of_services.table_of_clients}}} | Formatted table of clients and associated jobs |
| List of Clients | {{{scope_of_services.list_of_clients}}} | Formatted list of clients on the engagement |
| List of Clients & Jobs | {{{scope_of_services.list_of_clients_and_jobs}}} | Formatted list of clients and associated jobs |
| Jobs With Short Description | {{{scope_of_services.jobs_with_short_description}}} | Formatted list of jobs using their short descriptions |
| Jobs With Short Description & Price | {{{scope_of_services.jobs_with_short_description_and_price}}} | Formatted list of jobs with short descriptions and prices |
| Client Table | {{{client_table}}} | Formatted table of client names and numbers |
Job / project fields
Job fields are evaluated inside a jobs repeating section. Do not insert a job field at the letter's top level and expect it to select a particular job.
For example:
{{#jobs}}
{{{short_description}}}: {{{billing.price}}}
{{/jobs}}
| Picker label | Field path inside jobs | Value inserted |
|---|---|---|
| Internal Description | internal_description | Internal job name |
| Short Description | short_description | Client-facing service description; falls back to the internal job name |
| Long Description | long_description | Extended service description |
| Service Lines | service_lines | Job's service lines |
| Start Date | start_date | Job start date |
| End Date | end_date | Job end date |
| Manager — Name | manager.name | Job manager's name |
| Manager — Email | manager.email | Job manager's email |
| Manager — Job Title | manager.jobTitle | Job manager's job title, when enabled |
| Manager — Prefix | manager.prefix | Job manager's prefix, when enabled |
Job billing
Use these paths inside the jobs repeating section, with triple braces; for example, {{{billing.fixed_amount}}}.
| Picker label | Field path inside jobs | Value inserted |
|---|---|---|
| Price | billing.price | Price computed from the job's fee structure |
| Fixed Amount | billing.fixed_amount | Fixed fee amount |
| Min Estimate | billing.min_estimate | Minimum fee estimate |
| Max Estimate | billing.max_estimate | Maximum fee estimate |
| Currency Symbol | billing.currency_symbol | Currency symbol |
| Prepayment | billing.prepayment | Prepayment formatted with the currency symbol |
| Prepayment Amount | billing.prepayment_amount | Prepayment amount without the symbol |
| Minimum Price | billing.minimum_price | Computed minimum price |
| Maximum Price | billing.maximum_price | Computed maximum price |
Job states
Use these paths inside the jobs repeating section, with triple braces; for example, {{{states.name_inline}}}.
| Picker label | Field path inside jobs | Value inserted |
|---|---|---|
| Abbreviated States Block | states.abbreviated_block | Ordered list of state abbreviations |
| Abbreviated States Inline | states.abbreviated_inline | Inline list of state abbreviations |
| Abbreviated State Name Block | states.name_block | Ordered list of full state names |
| Abbreviated State Name Inline | states.name_inline | Inline list of full state names |
Repeating sections
Repeating sections render their contents once for each related item. They use double-brace opening and closing tags; individual values inside them use triple braces.
| Collection | Opening and closing tags | Fields available inside |
|---|---|---|
| Jobs / projects | {{#jobs}} … {{/jobs}} | Job, job billing, state, manager, and job custom fields listed above |
| Additional clients | {{#additional_clients}} … {{/additional_clients}} | Client fields listed above, without the client. prefix |
| Signatories | {{#signatories}} … {{/signatories}} | name, email |
| People who initial | {{#initials}} … {{/initials}} | name, email |
For example, {{#additional_clients}}{{{name}}}{{/additional_clients}} renders each additional client's name. Signatory names and emails are data values, not substitutes for the signature or initial blocks.
Custom fields
Client, contact, and job custom fields are supported by the data model. The available field names depend on the firm's configured and populated custom fields; there is no universal list of custom field names.
| Record | Documented path pattern | Usage |
|---|---|---|
| Client | client.custom_fields.FIELD_NAME | At the letter's top level |
| Job / project | custom_fields.FIELD_NAME | Inside a jobs repeating section |
| Engagement contact | Contact role prefix plus the custom-field path | Select from the picker; internal references disagree on custom_fields versus customFields for contacts |
FIELD_NAME is a stand-in, not a literal variable. Use the actual configured field from the picker, with triple braces around the complete path.
Availability notes
- Extended contact first name, last name, job title, and prefix depend on your firm's extended contact configuration and available contact data.
- Address Line 2 and extended staff job title/prefix fields have separate configuration dependencies.
- Client and firm notice periods and firm net terms depend on configured values. Currency formatting can also depend on billing configuration.
- The older Mustache.js Variables page distinguishes picker-visible fields from data-model-only fields and labels its standalone Job Object Variable Model as proposed. Do not treat that proposed model as a confirmed current picker list.
- This reference follows the newer Engagement Letter Data Model Mapping for field names and supported structures. Generate a test document to confirm the fields available for your firm.
Insert tags from the merge-field picker instead of typing them. Preserve the exact field path, capitalization, and braces. If a value is blank or a placeholder does not resolve as expected, check the source record, the field's context, and your firm's configuration, then generate a test document.
Placeholders in dynamic letter templates: variants and expressions
In a dynamic letter template (DLT) placeholders do two jobs. They merge a value into the letter, as described above, and they are the fields an engagement admin tests when deciding whether a piece of content appears at all.
Blocks, snippets and variants
| Element | What it is | Can contain | Cannot contain |
|---|---|---|---|
| Block | A reusable paragraph-level piece of content built in Settings → Document Templates → Content and inserted into one or more letter templates. Can be locked. | Placeholders, flat text, variants, snippets, other blocks | — |
| Snippet | A reusable piece of inline wording inside a sentence, for example "company" versus "organization". | Placeholders, text, variants | Other snippets, blocks |
| Variant | One version of a block's or snippet's content, with an expression that decides whether it shows. A block or snippet can have any number of variants. | The content of that version | — |
| Flat text | Text placed directly on the letter template outside any block. Identical on every letter unless a preparer edits it. | Placeholders, text | — |
How an expression uses placeholders
Each variant carries an expression. When a letter is generated, Aiwyn evaluates the expression against the engagement's data and shows the variant only when the expression is true; the other variants of that block or snippet stay hidden. Expressions are built in the visual condition builder by choosing a field, an operator and a value, grouped with AND/OR, or written directly in JSONata. The fields on offer are the placeholder paths in this reference, including custom fields:
| Condition in plain language | Field tested | Typical use |
|---|---|---|
| Client type is Individual / Trust / other | client.client_type | Three variants of the same paragraph, one per entity type |
| Client address line 1 is not empty | client.address_details.address_line_1 | Show the address block only when there is an address to print |
| Project name contains "1120" and does not contain "1120S" | internal_description / short_description inside jobs | Corporation wording on a tax letter |
| Project type equals "Bookkeeping" | custom_fields.FIELD_NAME inside jobs | Add a bookkeeping clause when any project on the letter is a bookkeeping project |
| Price is greater than 0 | billing.price inside jobs, or billing.minimum_price at the letter level | Show a fee table variant rather than a no-fee variant |
| Supplemental schedules required, limited scope, non-attest service selected | client.custom_fields.FIELD_NAME or custom_fields.FIELD_NAME inside jobs | Audit letters, where the variations rarely exist as standard fields and have to be created as custom fields in the practice management system |
Because a variant can only test data that exists, every variation a firm wants in a letter has to be present somewhere in the practice management system or in Aiwyn custom fields before the template can express it. Tax letters can usually be driven by client type and project name alone; audit letters typically need a set of custom fields created for the purpose. A repeating section such as jobs can also be used inside a variant so that a fee table adds one row per project or per client on the letter.
Rules that follow from this
- A dynamic template needs exactly one primary client signature block placeholder. Aiwyn adds signature areas for additional signatories itself; do not add them by hand.
- Placeholders inside a flattened block keep merging. Flattening removes the variants from that one letter, not the variables.
- The Highlight dynamic content toggle in the letter editor marks placeholders and dynamic blocks so a preparer can see which parts of a letter were decided by data.
- Formatting available in a dynamic template: bold, italic, underline, bulleted and numbered lists, indentation, images and forced page breaks. Not available: page numbers, headers and footers, multi-column layouts, and font type or size changes.
How tags resolve
When Aiwyn generates a document, it replaces each merge tag with the value on the related client, contact, project, or firm record, or with computed content such as billing totals and scope lists. Fields with no source value can render blank. Review the underlying record and add missing data before generating the final document. For job and additional-client fields, also check that the variable is inside the correct repeating section.
Always generate and review a test document after creating or editing a template. Template edits apply to documents generated from that point forward; documents already generated are unchanged.
Template lifecycle
- Create: Choose a Type, name the template, optionally add a Category, write the Content, insert merge tags, and save.
- Edit: Update the content or merge tags, save, and generate a test document.
- Remove: Removing a template prevents future use. Check whether the template is selected as a default engagement template or collection notice template before removing it.