Skip to content

Email template syntax

Team Forms email templates use Handlebars in the recipient, subject, body, and attachment-name fields. They do not execute JavaScript.

Use {{ data.requesterName }} rather than JavaScript forms such as ${data.requesterName}, data?.requesterName, or value = data.requesterName.

Email fieldDynamic syntax
To, Cc, BccHandlebars; the rendered result is split on commas, semicolons, or whitespace and invalid email addresses are discarded.
SubjectHandlebars; the final subject is limited to 255 characters when sent.
BodyHandlebars. Prefer readable plain text; line breaks are converted to HTML line breaks. Use HTML only where needed, such as links or tables.
Attachment nameHandlebars. Include the appropriate file extension.
FromA literal email address only. It is validated as a mailbox and is not a Handlebars template.
Save to Sent ItemsBoolean configuration, not a template.

Form answers are under data and use component keys, not labels:

Requester: {{ data.requesterName }}
Department: {{ data.department }}

Nested values follow their stored object shape:

Site: {{ data.site.SiteName }}
Manager: {{ data.manager.displayName }}

Use the form’s exact schema keys. Do not add JavaScript optional chaining inside a Handlebars path.

See Component response values for the stored shapes of User, Address, File, Data Grid, data-source, and other object-valued components.

Submission emails also receive these values:

ValueDescription
titleGenerated response title.
timestampSubmission timestamp. Use dateFormat to format it.
submissionNumberSequential submission number when available.
idResponse ID.
teamId, channelId, formId, versionCurrent Team Forms identifiers and form version when available.
viewUrl, editUrlLinks to view or edit the response.
createdBy.name, createdBy.emailOriginal response creator.
responder.name, responder.emailUser performing the current submission.
collaboratorsArray of response collaborators.
pdfReserved base64 content for the generated PDF attachment.

Approval email templates receive additional action-specific values documented in Approval component schema.

Double braces escape HTML and are the safe default for user-entered answers:

{{ data.comments }}

Triple braces preserve trusted HTML or URL content. Team Forms uses them for generated links, pre-rendered HTML, and the reserved PDF attachment value:

{{{ viewUrl }}}
{{{ data.preRenderedSummary }}}
{{{ pdf }}}

Do not use triple braces for ordinary untrusted form answers.

The standard truthy form is:

{{#if data.requiresFollowUp}}
Follow-up is required.
{{else}}
No follow-up is required.
{{/if}}

Team Forms extends #if with comparison and logical operators:

OperationOperatorExample
Equal==={{#if data.status "===" "approved"}}Approved{{/if}}
Not equal!=={{#if data.status "!==" "rejected"}}Open{{/if}}
Less/greater than<, >, <=, >={{#if data.total ">" 1000}}High value{{/if}}
And&&{{#if data.total ">" 1000 "&&" data.urgent "===" true}}Escalate{{/if}}
Or||{{#if data.priority ”===” “high” ”||” data.urgent ”===” true}}Escalate{{/if}}

Operators are string arguments and therefore remain inside quotes. Values being compared are normal Handlebars arguments: quote literal strings, but not numbers, booleans, or paths. Comparison operators run before &&, which runs before ||.

An else-if branch is also supported:

{{#if data.priority "===" "high"}}
High priority
{{else if data.priority "===" "medium"}}
Medium priority
{{else}}
Standard priority
{{/if}}

Use #each for arrays. Within the block, this is the current item and @index is its zero-based position:

{{#each data.lineItems}}
{{@index}}. {{ this.description }}{{ this.quantity }}
{{/each}}

For collaborators:

{{#each collaborators}}
{{ this.name }} ({{ this.email }})
{{/each}}

The dateFormat helper accepts a date value, a Day.js-compatible format, and an optional IANA timezone:

{{ dateFormat data.requiredBy "DD MMMM YYYY" }}
{{ dateFormat timestamp "YYYY-MM-DD HH:mm:ss" "Australia/Perth" }}

Common tokens include YYYY, MM, DD, HH, mm, ss, MMMM, and dddd.

The generated Team Forms PDF uses an exact reserved placeholder:

{
"name": "{{ title }}.pdf",
"contentType": "application/pdf",
"contentBytes": "{{{ pdf }}}"
}

Do not replace {{{ pdf }}} with JavaScript, a URL, or generated base64. Including files uploaded by respondents is controlled separately by includeResponseAttachments and the team’s subscription.

{
"from": null,
"to": "{{ data.requesterEmail }}",
"cc": "{{ responder.email }}",
"bcc": null,
"subject": "Request {{ title }} received",
"body": "Hi {{ data.requesterName }},\n\nYour request has been received.\n\n{{#if data.totalAmount \">\" 1000}}It requires additional review.{{/if}}\n\nView it here: {{{ viewUrl }}}",
"saveToSentItems": true,
"includeResponseAttachments": false,
"attachments": [
{
"name": "{{ title }}.pdf",
"contentType": "application/pdf",
"contentBytes": "{{{ pdf }}}"
}
]
}

The AI assistant prepares this as an unsaved draft. Preview it with representative data and select Apply in the Email tab before enabling or relying on the notification.