---
title: "Email notification templates"
slug: "email-notification-templates"
description: "Learn how to configure and send email notifications about quote changes in Zilliant CPQ."
tags: ["Email templates"]
updated: 2026-07-22T14:14:23Z
published: 2026-07-31T10:00:05Z
canonical: "docs.zilliant.com/email-notification-templates"
---
> ## Documentation Index
> Fetch the complete documentation index at: https://docs.zilliant.com/llms.txt
> Use this file to discover all available pages before exploring further.
# Email notification templates
Zilliant CPQ sends email notifications about changes in opportunities, quotes, and agreements under negotiation, or when a manager approves a quote or an agreement.
## Configure email notification templates
There is a pre-delivered notification message for each email notification. This key-value pair is mapped to a specific CPQ operation. Maintain key-value pairs in the **messages.properties** file.
1. From the application left navigation area:
- In the classic view, select **Administration**.
- In the new UI, select **Settings** > **Administration**.
2. From the top navigation bar, select **Operation Settings**, then select **System Settings** subtab.
3. In the **General** section, under **Download Email Template Start,** select **Start**.
4. Make changes to the email title and content without changing the keys.
5. Upload the file:
1. From the application left navigation area, select **Administration**.
2. From the top navigation bar, select **Content Management**.
3. Select **conf** > **email**.
4. Select .png?sv=2026-02-06&spr=https&st=2026-11-11T12%3A16%3A54Z&se=2026-11-11T13%3A16%3A54Z&sr=c&sp=r&sig=xNmA6sGayWeKL3ac0t3ESxPASyKVyOprm6ryh4%2Fw1hI%3D), then select a file to upload.
### Default email text
**Email subject**
`workItem.approval.needed.title=Approval needed for ${doc.type} "${doc.objectName}"`
**Email body**
```plaintext
workItem.approval.needed.content=Dear ${user.firstName},
${sender.firstName} ${sender.lastName} just submitted a quote which requires your review and approval. The quote’s expires on ${doc.salesDocumentDateOfExpiry} and therefore immediate attention is needed!
Quote ID:${doc.quoteId}
Name:${doc.objectName}
Quote Value:${doc.includesDocumentHeaderPriceItem.documentHeaderPrice}
Account${doc.quoteContainedBy.objectName}
You can review the quote here or approve / reject using the below buttons:
${approvalButtons}
Powered by
This email was automatically sent from Zilliant CPQ.
```
### Email template examples
**Email to the order creator when a business admin approves the order**
```plaintext
portal.order.approved.title = Your Order ${doc.orderId} Has Been Approved
portal.order.approved.content =
Dear ${user.firstName} ${user.lastName},
Order ID "${doc.orderId}" - for amount "${doc.orderTotal}" that you submitted has been approved and submitted by ${sender.firstName} ${sender.lastName}
| PO ID: |
${doc.poID} |
| Order: |
${doc.objectName} |
| Order Value: |
${doc.hasCurrency.objectName} ${doc.orderTotal} |
| Address: |
|
| Bill To: |
${doc.orderBillTo.address1StreetPrefixName} ${doc.orderBillTo.address2AdditionalStreetPrefixName} ${doc.orderBillTo.addressStreet} ${doc.orderBillTo.addressCity} |
| Ship To To: |
${doc.orderShipTo.address1StreetPrefixName} ${doc.orderShipTo.addressStreet} ${doc.orderShipTo.addressCity} |
Access Portal Application
This is a system-generated message. Please do not reply to this email.
In Mind Cloud Digital Sales Platform
This email was auto-generated. Please do not reply.
```
**Email to the order creator when a business admin rejects the order**
```plaintext
portal.order.rejected.title = Your Order ${doc.orderId} Has Been Rejected
portal.order.rejected.content = Dear ${user.firstName} ${user.lastName},
Order "${doc.orderId}" that you submitted has been rejected by ${sender.firstName} ${sender.lastName}
PO ID: ${doc.poId}
Order: ${doc.objectName}
Order Value: ${doc.hasCurrency.objectName} ${doc.orderTotal}
Address: Bill To: ${doc.orderBillTo.address1StreetPrefixName} ${doc.orderBillTo.address2AdditionalStreetPrefixName} ${doc.orderBillTo.addressStreet} ${doc.orderBillTo.addressCity}
Ship To: ${doc.orderShipTo.address1StreetPrefixName} ${doc.orderBillTo.addressStreet} ${doc.orderBillTo.addressCity}
Access Portal Application
This is a system generated message. Please do not reply to this email.
```
**Email to business admins when a user cancels an order that is submitted for review**
```plaintext
portal.order.cancelled.title = Order ${doc.orderId} Has Been Cancelled
portal.order.cancelled.content =
Dear ${user.firstName},
Order "${doc.orderId}" was submitted for your review, but has been cancelled by the submitter.
In Mind Cloud Digital Sales Platform
This email was auto-generated. Please do not reply. You can access your application
here
```
**Email to business admins when a user submits an order for review**
```plaintext
portal.order.reviewRequest.title = Order ${doc.orderId} (PO: ${doc.poId}) Has Been Submitted For Your Review
portal.order.reviewRequest.content =
Dear ${user.firstName},
The following order has been submitted for your review:
| PO ID: |
${doc.poID} |
| Order: |
${doc.objectName} |
| Order Value: |
${doc.hasCurrency.objectName} ${doc.orderTotal} |
| Address: |
|
| Bill To: |
${doc.orderBillTo.address1StreetPrefixName} ${doc.orderBillTo.address2AdditionalStreetPrefixName} ${doc.orderBillTo.addressStreet} ${doc.orderBillTo.addressCity} |
| Ship To To: |
${doc.orderShipTo.address1StreetPrefixName} ${doc.orderShipTo.addressStreet} ${doc.orderShipTo.addressCity} |
You can review the details and place the order here
In Mind Cloud Digital Sales Platform
This email was auto-generated. Please do not reply. You can access your application
here
```
**Email the order approver when a business admin approves the order, amends it and places the order, or places their own order**
```plaintext
portal.order.approved.bizadmin.title = Your Order ${doc.orderId} (PO: ${doc.poId}) Has Been Submitted
portal.order.approved.bizadmin.content = Dear ${user.firstName} ${user.lastName},
Order "${doc.orderId}" (PO: ${doc.poId}) has been placed by you.
PO ID: ${doc.poId}
Order: ${doc.objectName}
Order Value: ${doc.hasCurrency.objectName} ${doc.orderTotal}
Address: Bill To: ${doc.orderBillTo.address1StreetPrefixName} ${doc.orderBillTo.address2AdditionalStreetPrefixName} ${doc.orderBillTo.addressStreet} ${doc.orderBillTo.addressCity}
Ship To: ${doc.orderShipTo.address1StreetPrefixName} ${doc.orderBillTo.addressStreet} ${doc.orderBillTo.addressCity}
```
**eCommerce user or business admin submits an order inquiry**
```plaintext
portal.inquiry.title = Inquiry ${doc.quoteId} Has Been Submitted
portal.inquiry.content = Dear ${user.firstName} ${user.lastName},
The following Inquiry has been submitted by you.
Inquiry ID: ${doc.quoteId}
Account: ${doc.quoteContainedBy.objectName}
This email was auto-generated. Please do not reply.
```
---
## Configure email notifications for each gate of the quote and agreement approval process
Configure email notifications to inform all relevant stakeholders at each [approval process](/v1/docs/about-approvals) stage. By sending email notifications to all parties, you minimize the risk of oversights or miscommunication and ensure a smoother approval process.
### Enable email notifications for each approval gate
1. From the application left navigation area:
- In the classic view, select **Administration**.
- In the new UI, select **Settings** > **Administration**.
2. From the top navigation bar, select **Master Data Management**.
3. Scroll or search to locate **Setting Boolean** and select it from the list.
4. Scroll or search to locate one of the following Boolean settings, then set the value to **YES**:
| Label | Description |
| --- | --- |
| SettingNotificationsToPreviousGatesRolesOnQuoteApproval | Sends approval notification emails to all users or roles involved in previous gates when the current gate approves the quote or agreement under negotiation. |
| SettingNotificationsToPreviousGatesRolesOnQuoteRejection | Enables sending rejection notification emails to all users or roles involved in previous gates when the current gate rejects the quote or agreement under negotiation. |
| SettingNotificationsToUsersInvolvedInPreviousGates | Sends approval or rejection notification emails only to the users involved in previous gates. |
| SettingNotificationsToSameGateUsersOnQuoteApproval | Sends approval notification emails to other users at the same gate when someone approves the quote or agreement under negotiation. |
| SettingNotificationsToSubmitteronEveryGatesofQuoteApproval | Sends notification emails to the submitter for each quote or agreement under negotiation approval gate. |
5. Select **Save**.
### Provide a new email template for each specific approval action
Tip
Customers can modify the template's content (only its value, the key remains the same) according to their business needs and add additional information to the approval email.
### Email notification templates
**Quotes**
**Notify users at the next approval gate about the quote approval request**
```xml
workItem.approval.needed.title = Approval required for ${doc.type} "${doc.objectName}"
workItem.approval.needed.content = Dear ${user.firstName},
${sender.firstName} ${sender.lastName} just submitted a quote which requires your review and approval. The quote expires on ${doc.salesDocumentDateOfExpiry} and therefore immediate attention is needed!
| Quote ID: | ${doc.quoteId} |
| Name: | ${doc.objectName} |
| Quote Value: | ${doc.hasCurrency.objectERPId} ${doc.includesDocumentHeaderPriceItem.documentHeaderPrice} |
| Account: | ${doc.quoteContainedBy.objectName} |
| Effective Date: | ${doc.quoteEffectiveDate} |
| | |
| | |
| Approval Rule: | ${approval.rule} |
| Approval Reason: | ${approval.reason} |
You can review the quote here or approve / reject using the below buttons:
${approvalButtons}
In Mind Cloud Digital Sales Platform
This email was auto-generated. Please do not reply. You can access your application
here
```
**Notify that the quote has been approved**
```xml
workItem.approval.approved.title = ${doc.type} "${doc.objectName}" is approved
workItem.approval.approved.content = Dear ${user.firstName},
Your quote "${doc.objectName}" was approved. Please review the document here.
In Mind Cloud Digital Sales Platform
This email was auto-generated. Please do not reply. You can access your application
here
```
**Notify users at the next approval gate that the approval request has been canceled**
```xml
workItem.approval.cancelled.title = Approval request cancelled for ${doc.type} "${doc.objectName}"
workItem.approval.cancelled.content = Dear ${user.firstName},
The request for your approval of ${doc.type} "${doc.objectName}" was cancelled.
In Mind Cloud Digital Sales Platform
This email was auto-generated. Please do not reply. You can access your application
here
```
**Notify that the quote has been rejected**
```xml
workItem.approval.rejected.content = Dear ${user.firstName},
Your quote "${doc.objectName}" was rejected. Please review the document here.
In Mind Cloud Digital Sales Platform
This email was auto-generated. Please do not reply. You can access your application
here
```
**Notify the submitter that the quote has passed the approval gate**
The submitter receives an email for each successful gate of the quote approval.
```xml
workItem.approval.approved.title.submitter = Quote Approval Update : Gate ${doc.gateName} Completed for Quote ${doc.quoteId}
workItem.approval.approved.content.submitter = Dear ${user.firstName},
We wanted to inform you that your quote ${doc.quoteId} has successfully passed the approval gate. ${doc.gateName}.
Details:
Quote ID : ${doc.quoteId}
Current Gate : ${doc.gateName}
Approved By : ${sender.firstName} ${sender.lastName}
Please be aware that the quote will proceed to the next gate of approval.
Thank you for your patience.
Best regards,
In Mind Cloud Digital Sales Platform
This email was auto-generated. Please do not reply. You can access your application
here
```
**Notify users at previous gates that the quote has been approved**
```xml
workItem.approval.approved.title.previous = Quote ${doc.quoteId} Approved at Gate ${doc.gateName}
workItem.approval.approved.content.previous = Dear ${user.firstName},
We are pleased to inform you that the quote ${doc.quoteId} has been approved at the gate ${doc.gateName}.
Details:
Quote ID : ${doc.quoteId}
Gate : ${doc.gateName}
Approved By : ${sender.firstName} ${sender.lastName}
Thank you for your contribution to this process.
Best regards,
In Mind Cloud Digital Sales Platform
This email was auto-generated. Please do not reply. You can access your application
here
```
**Notify users at previous gates that the quote has been rejected**
```xml
workItem.approval.rejected.title.previous = Quote ${doc.quoteId} Rejected at Gate ${doc.gateName}
workItem.approval.rejected.content.previous = Dear ${user.firstName},
We regret to inform you that the quote ${doc.quoteId} has been rejected at the gate ${doc.gateName}.
Details:
Quote ID : ${doc.quoteId}
Gate : ${doc.gateName}
Rejected By : ${sender.firstName} ${sender.lastName}
Rejected Reason : ${doc.rejectReason}
The quote will not proceed further unless resubmitted for review. Please review the notes for further details.
Best regards,
In Mind Cloud Digital Sales Platform
This email was auto-generated. Please do not reply. You can access your application
here
```
**Notify users at the same gate that the quote has been approved**
```xml
workItem.approval.approved.title.sameGate = Update on Quote ${doc.quoteId} Approved at Gate ${doc.gateName}
workItem.approval.approved.content.sameGate = Dear ${user.firstName},
This is to notify you that the quote ${doc.quoteId} has been approved ${doc.gateName}.
Details:
Quote ID: ${doc.quoteId}
Gate : ${doc.gateName}
Approved By : ${sender.firstName} ${sender.lastName}
Please review the quote details and take any necessary actions as required for your role.
Best regards,
In Mind Cloud Digital Sales Platform
This email was auto-generated. Please do not reply. You can access your application
here
```
**Notify users at the same gate that the quote has been rejected**
```xml
workItem.approval.rejected.title.sameGate = Update on Quote ${doc.quoteId} Rejected at Gate ${doc.gateName}
workItem.approval.rejected.content.sameGate = Dear ${user.firstName},
This is to notify you that the quote ${doc.quoteId} has been rejected at the gate ${doc.gateName}.
Details:
Quote ID : ${doc.quoteId}
Gate : ${doc.gateName}
Rejected By : ${sender.firstName} ${sender.lastName}
Rejected Reason : ${doc.rejectReason}
Please review the quote details and take any necessary actions as required for your role.
Best regards,
In Mind Cloud Digital Sales Platform
This email was auto-generated. Please do not reply. You can access your application
here
```
**Agreements under negotiation**
**Notify users at the next approval gate about the agreement approval request**
```xml
workItem.approval.agreement.negotiation.needed.title = Approval required for Agreement "${doc.objectName}"
workItem.approval.agreement.negotiation.needed.content = Dear ${user.firstName},
${sender.firstName} ${sender.lastName} just submitted an agreement which requires your review and approval. The agreement expires on ${doc.salesDocumentDateOfExpiry} and therefore immediate attention is needed!
| ID: | ${doc.quoteId} |
| Name: | ${doc.objectName} |
| Value: | ${doc.hasCurrency.objectERPId} ${doc.includesDocumentHeaderPriceItem.documentHeaderPrice} |
| Account: | ${doc.quoteContainedBy.objectName} |
| Effective Date: | ${doc.quoteEffectiveDate} |
| | |
| | |
| Approval Rule: | ${approval.rule} |
| Approval Reason: | ${approval.reason} |
You can review the agreement here or approve / reject using the below buttons:
${approvalButtons}
In Mind Cloud Digital Sales Platform
This email was auto-generated. Please do not reply. You can access your application
here
```
**Notify that the agreement has been approved**
```xml
workItem.approval.agreement.negotiation.approved.title = Agreement "${doc.objectName}" is approved
workItem.approval.agreement.negotiation.approved.content = Dear ${user.firstName},
Your Agreement "${doc.objectName}" was approved. Please review the document here.
In Mind Cloud Digital Sales Platform
This email was auto-generated. Please do not reply. You can access your application
here
```
**Notify users at the next approval gate that the approval request has been canceled**
```xml
workItem.approval.agreement.negotiation.cancelled.title = Approval request cancelled for Agreement "${doc.objectName}"
workItem.approval.agreement.negotiation.cancelled.content = Dear ${user.firstName},
The request for your approval of Agreement "${doc.objectName}" was cancelled.
In Mind Cloud Digital Sales Platform
This email was auto-generated. Please do not reply. You can access your application
here
```
**Notify that the agreement has been rejected**
```xml
workItem.approval.agreement.negotiation.rejected.content = Dear ${user.firstName},
Your agreement "${doc.objectName}" was rejected. Please review the document here.
In Mind Cloud Digital Sales Platform
This email was auto-generated. Please do not reply. You can access your application
here
```
**Notify the submitter that the agreement has passed the approval gate**
The submitter receives an email for each successful gate of the agreement approval.
```xml
workItem.approval.agreement.negotiation.approved.title.submitter = Agreement Approval Update : Gate ${doc.gateName} Completed for Agreement ${doc.quoteId}
workItem.approval.agreement.negotiation.approved.content.submitter = Dear ${user.firstName},
We wanted to inform you that your agreement ${doc.quoteId} has successfully passed the approval gate. ${doc.gateName}.
Details:
ID : ${doc.quoteId}
Current Gate : ${doc.gateName}
Approved By : ${sender.firstName} ${sender.lastName}
Please be aware that the agreement will proceed to the next gate of approval.
Thank you for your patience.
Best regards,
In Mind Cloud Digital Sales Platform
This email was auto-generated. Please do not reply. You can access your application
here
```
**Notify users at previous gates that the agreement has been approved**
```xml
workItem.approval.agreement.negotiation.approved.title.previous = Agreement ${doc.quoteId} Approved at Gate ${doc.gateName}
workItem.approval.agreement.negotiation.approved.content.previous = Dear ${user.firstName},
We are pleased to inform you that the agreement ${doc.quoteId} has been approved at the gate ${doc.gateName}.
Details:
ID : ${doc.quoteId}
Gate : ${doc.gateName}
Approved By : ${sender.firstName} ${sender.lastName}
Thank you for your contribution to this process.
Best regards,
In Mind Cloud Digital Sales Platform
This email was auto-generated. Please do not reply. You can access your application
here
```
**Notify users at previous gates that the agreement has been rejected**
```xml
workItem.approval.agreement.negotiation.rejected.title.previous = Agreement ${doc.quoteId} Rejected at Gate ${doc.gateName}
workItem.approval.agreement.negotiation.rejected.content.previous = Dear ${user.firstName},
We regret to inform you that the agreement ${doc.quoteId} has been rejected at the gate ${doc.gateName}.
Details:
ID : ${doc.quoteId}
Gate : ${doc.gateName}
Rejected By : ${sender.firstName} ${sender.lastName}
Rejected Reason : ${doc.rejectReason}
The agreement will not proceed further unless resubmitted for review. Please review the notes for further details.
Best regards,
In Mind Cloud Digital Sales Platform
This email was auto-generated. Please do not reply. You can access your application
here
```
**Notify users at the same gate that the agreement has been approved**
```xml
workItem.approval.agreement.negotiation.approved.title.sameGate = Update on Agreement ${doc.quoteId} Approved at Gate ${doc.gateName}
workItem.approval.agreement.negotiation.approved.content.sameGate = Dear ${user.firstName},
This is to notify you that the agreement ${doc.quoteId} has been approved ${doc.gateName}.
Details:
ID: ${doc.quoteId}
Gate : ${doc.gateName}
Approved By : ${sender.firstName} ${sender.lastName}
Please review the agreement details and take any necessary actions as required for your role.
Best regards,
In Mind Cloud Digital Sales Platform
This email was auto-generated. Please do not reply. You can access your application
here
```
**Notify users at the same gate that the agreement has been rejected**
```xml
workItem.approval.agreement.negotiation.rejected.title.sameGate = Update on Agreement ${doc.quoteId} Rejected at Gate ${doc.gateName}
workItem.approval.agreement.negotiation.rejected.content.sameGate = Dear ${user.firstName},
This is to notify you that the agreement ${doc.quoteId} has been rejected at the gate ${doc.gateName}.
Details:
ID : ${doc.quoteId}
Gate : ${doc.gateName}
Rejected By : ${sender.firstName} ${sender.lastName}
Rejected Reason : ${doc.rejectReason}
Please review the agreement details and take any necessary actions as required for your role.
Best regards,
In Mind Cloud Digital Sales Platform
This email was auto-generated. Please do not reply. You can access your application
here
```
---
## Configure custom email notifications through a Groovy script
You may need to send email notifications based on a specific business case. For example, if a quote's net value exceeds a particular amount, you can send a custom email notification to a specific manager. By running a Groovy script, you can tailor your notification to include quote details, a link to access the quote, and supporting attachments.
### Create a Groovy script
Create a Groovy script that lists all characteristics needed in the notification email. Indicate the email recipient details and the attachments that the email notification should include.
This script supports the [common binding variables](/docs/binding-variables) and must call the following methods:
| Method | Class | Description |
| --- | --- | --- |
| createMimeMessage | [mailSender](https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/mail/javamail/JavaMailSender.html)  | Creates a message for this sender. |
| getAttachmentFiles() | [salesItemsTree](https://in-mind-cloud.github.io/content/groovy-doc/2405/com/imc/iss/groovy/salesitem/SalesItemsTree.html)  | Gets an attachment file by file name. |
**Groovy script example with comments**
```groovy
// Import necessary classes and libraries
import java.util.Locale
import java.text.DecimalFormat
import java.text.DecimalFormatSymbols
import java.text.NumberFormat
import com.imc.vocabulary.Schema
import com.imc.iss.groovy.salesitem.*
import com.imc.iss.groovy.configitem.*
import com.imc.datamodel.BusinessObject
import com.imc.datamodel.transferobjects.BusinessDataAttributeDTO
import com.imc.datamodel.transferobjects.BusinessObjectDTO
import com.imc.datamodel.transferobjects.BusinessRelationAttributeDTO
import com.imc.datamodel.transferobjects.LocaleDTO
import java.text.SimpleDateFormat
import com.imc.util.NullUtil
import java.util.GregorianCalendar
import com.imc.context.IMCException
import org.apache.jena.ext.com.google.common.collect.Lists
import javax.activation.DataHandler
import javax.activation.DataSource
import javax.activation.FileDataSource
import javax.mail.BodyPart
import javax.mail.Message
import javax.mail.MessagingException
import javax.mail.Multipart
import javax.mail.internet.MimeBodyPart
import javax.mail.internet.MimeMessage
import javax.mail.internet.MimeMultipart
import javax.mail.util.ByteArrayDataSource
import java.io.File
import java.nio.file.Files
import javax.activation.DataHandler
import javax.activation.DataSource
import javax.activation.FileDataSource
// Call the createMimeMessage() method to create the email
def message = mailSender.createMimeMessage()
message.setSubject("Groovy Test")
// Specify the email recipient
message.addRecipient(javax.mail.Message.RecipientType.TO, new javax.mail.internet.InternetAddress("xyz@abc.com"))
message.addRecipient(javax.mail.Message.RecipientType.CC, new javax.mail.internet.InternetAddress("xyz@abc.com"))
// List attachment characteristics
def attachmentFilesSize = salesItemsTree.getAttachmentFiles().size()
def tempFiles = []
def tempFile = null
if (attachmentFilesSize == 0) {
message.setText("Hello,\n\nThis is the Testing mail of Groovy Script.")
} else {
def multipart = new MimeMultipart()
def messageBodyPart = new MimeBodyPart()
String emailText = "Hello
This is a test email.
"
messageBodyPart.setText(emailText, "utf-8", "html");
multipart.addBodyPart(messageBodyPart)
attachmentBodyPart = new MimeBodyPart()
def attachmentFiles = salesItemsTree.getAttachmentFiles()
attachmentFiles.each { attachment ->
tempFile = File.createTempFile("attachment", ".txt")
Files.write(tempFile.toPath(), attachment.getFileContent())
tempFiles << tempFile
def attachmentBodyPart = new MimeBodyPart()
def source = new FileDataSource(tempFile)
attachmentBodyPart.setDataHandler(new DataHandler(source))
attachmentBodyPart.setFileName(attachment.getFileName())
multipart.addBodyPart(attachmentBodyPart)
}
message.setContent(multipart)
}
mailSender.send(message)
tempFiles.each { file ->
if (file.exists()) {
file.delete()
}
}
// Call the notifyInfo method to send the email
groovyLogger.notifyInfo("Mail sent successfully")
return true;
```