Creating a document template
You may create and manage your own document templates in Pay Suite. This feature enhances the process of generating personalized PDF documents using configurable Word templates. It enables Compensation Administrators to streamline document production at scale while maintaining accuracy and consistency.
The Document Templates page includes summary tiles: Templates, with the total number of available templates, as well as Ready and Draft tiles, which represent the number of templates in each status.
Below the tiles, there is a list of templates with names, codes, owners, and statuses specified.
To see the details of a ready document template, click the three-dot icon located on the far-right side of the template row in the list, and then select View from the action menu. You can also click the name of the template to be redirected to the View document template page.
Step 1 - Document template details
To create a document template, proceed as follows:
-
Click Create document template in the upper-right part of the Document Templates page. The Create document template form is opened at the first step, Document template details, as shown in the figure below:
Create document template page
-
Fill in the basic details of the template:
Enter a name of the new template in the Name field.
Enter a unique code in the Code field.
Add a Description to explain the purpose or usage of the template.
Click Upload or drag and drop a base DOCX file from your device to upload it to the form. This file will be used for generating the final PDF output.
Select additional owners by entering their names in the search bar. If you decide not to add any other owners, you will be the only owner of this template.
Click Next in the progress widget to move to the next step of the creation process: Preview.
Step 2 - Preview
This step allows the Compensation Administrator to simulate the output of a document generated from the uploaded .docx template using test data entered as variables in JSON format.
This preview helps validate:
The layout and formatting of the document
The correct resolution of all merge variables
The completeness of the variable list before the template is published
In this step, the Compensation Administrator must provide a sample payload in JSON format to populate the merge variables embedded in the uploaded Word template.
For more on the correct use of variables and loops in document templates in the context of statement generation, go to the Variables and loops in document templates section of this article.
To begin editing the variables, proceed as follows:
Click the Edit button located in the upper-right corner of the JSON editor. You may also click Use example to see our template, as illustrated in the following picture:
Example of variables
Keep in mind that each key in the JSON corresponds to a placeholder in the document (e.g., {{EmployeeName}}, {{BonusAmount}}).
Click the Preview document button to generate a PDF document that can be previewed and downloaded, as shown in the following image:
Document preview
The system will generate a PDF preview at the bottom of the screen only if all variables are matched. If any variables are missing, the preview is blocked, and the system displays a warning message identifying the undefined variables. This missing variable validation is enforced for both Preview and Publish actions to prevent incomplete or incorrect templates from being used.
Once the document template has been successfully previewed with all required variables resolved, you may click Publish in the progress widget. Publishing a document template makes it Ready and available for use across the platform – for both individual and bulk document generation from compensation rounds.
Variables and loops in document templates
To prepare DOCX templates for the Statement Generation API during compensation rounds, you must use variables and loops correctly. This ensures that documents are generated successfully for each worker.
Syntax for variables
Variables must be written in double curly brackets inside your DOCX template, for example:
{{ModelData.WorkerFirstName}}{{ModelData.WorkerLastName}}
{{Round.CompensationRoundName}}
{{CalculationData.BQVP1001.Bonus.CalculatedBonus.Currency}}{{CalculationData.BQVP1001.Bonus.CalculatedBonus.ConvertedValue}}
Supported variable sources
| Section | Source | Examples |
|---|---|---|
| ModelData |
Latest comp round snapshot Exposing any model data with string format If there is no data available, it will be presented as null. |
ModelData.WorkerFirstName ModelData.WorkerLastName ModelData.EmploymentJobArchitectureExternalId ModelData.EmploymentOrganizationExternalId |
| Round | Comp round definition | CompensationRoundName, PlanStartDate, PlanEndDate |
| CalculationData |
CalculationData exposes calculations based on specific rules configured in the comp round.
|
Guidelines structure CalculationData.BQBP1001.Guidelines.Max.Value CalculationData.BQBP1001.Guidelines.Max.Currency CalculationData.BQBP1001.Guidelines.Max.ConvertedValue CalculationData.BQBP1001.Guidelines.Min.Value CalculationData.BQBP1001.Guidelines.Min.Currency CalculationData.BQBP1001.Guidelines.Min.ConvertedValue
Copy
Budget structure for the BQBP1001 element CalculationData.BQBP1001.Budget.Output.Value CalculationData.BQBP1001.Budget.Output.Currency CalculationData.BQBP1001.Budget.Output.ConvertedValue
Copy
Bonus structure CalculationData.BQVP1001.Bonus.TargetBonus.Value CalculationData.BQVP1001.Bonus.TargetBonus.Currency CalculationData.BQVP1001.Bonus.TargetBonus.ConvertedValue CalculationData.BQVP1001.Bonus.CalculatedBonus.Value CalculationData.BQVP1001.Bonus.CalculatedBonus.Currency CalculationData.BQVP1001.Bonus.CalculatedBonus.ConvertedValue CalculationData.BQVP1001.Bonus.SituationDetails (you can access child properties based on the same logic)
Copy
|
| RoundData | RoundData exposes all proposals of the comp round. It also includes calculated fields. |
Structure if an element has a reference model data
Copy
Structure if an element does not have reference model data
Copy
|
Accessing nested properties
In many cases, your data is structured in nested JSON objects. To access properties inside those objects, you can use dot notation: {{ParentObject.ChildObject.PropertyName}}
For example, given this part of the JSON:
"Bonus":
{
"TargetBonus":
{
"Currency": "CHF",
"ConvertedValue": "8000"
}
} You can access:
{{CalculationData.BQVP1001.Bonus.TargetBonus.Currency}} → will print CHF
{{CalculationData.BQVP1001.Bonus.TargetBonus.ConvertedValue}} → will print 8000
Syntax for loops
If the data is an array, such as Bonus.Situations or PayoutCurveResults, you must define a loop block.
Loop block inside tables:
{{loop PayoutCurveResults}}
... content ...
{{endloop}}Loop blocks outside of tables (please note that the property name must be mentioned while closing the loop here):
{{loop Bonus.SituationDetails}}
... content ...
{{endloop Bonus.SituationDetails}}Placement of loops
Each item in the array will generate corresponding rows or content in the document.
When working with array-type data (such as Bonus.Situations or PayoutCurveResults), you must use a loop block in your DOCX template.
Loop outside of table:
{{loop Bonus.SituationDetails}}
Situation Start Date: {{SituationStartDate}} Situation End Date: {{SituationEndDate}}
{{endloop Bonus.SituationDetails}} Inside the loop, you no longer use the full path Bonus.Situations.X. Instead, the current array item becomes the new “root context” so you can directly access its properties.
Table loop:
Goal ID: {{GoalAchievementGoalId}}
Result: {{PayoutResultPercentage}}
{{endloop}}Please note that the endloop does not have a repeated property of the loop again.
| Column1 | Column2 | Column3 |
|---|---|---|
|
{{loop PayoutCurveResults}} {{GoalAchievementGoalId}} |
{{PayoutResultPercentage}} |
{{MaxAchievementPercentage}} {{endloop}} |
Accessing custom compensation elements
Custom compensation elements are created in the Compensation Tree & Elements section of Compensation Management.
When an element is created, a comp element is auto-generated based on the parent element. The element code is significant – it must be used while accessing proposed data for that element.
If the element code is generated as BQBP2001, use the following to access the proposal:
RoundData.BQBP2001_NewValueElement code on the Edit comp element page
Accessing custom columns
Custom columns are added in the Team planner view step of the comp round creation process. The Code field is used while accessing the column's actual data from the document template.
If the custom column code is XYZ, you can access it using:
RoundData.XYZAccessing calculated columns
Calculated columns are added in the Team planner view step of the comp round creation process. The Code field is used while accessing the column's actual data from the document template.
If the calculated column code is ABC, you can access it using:
CalculationData.ABC.CalculatedValue
JSON variable structure
Structure for Bonus BQVP1001:
{
"CalculationData":{
"BQVP1001":{
"Bonus": {
"SituationDetails": [
{
"SituationEndDate": "31/06/2024",
"PayoutCurveResults": [
{
"MaxPayoutPercentage": "150",
"MinPayoutPercentage": "50",
"GoalAchievementGoalId": "GOAL-12345",
"PayoutResultPercentage": "120",
"MaxAchievementPercentage": "200",
"MinAchievementPercentage": "0",
"WeightedGoalResultPercentage": "110"
}
],
"SituationStartDate": "01/01/2024"
}
],
"TargetBonus": {
"Currency": "CHF",
"ConvertedValue": "8000"
},
"CalculatedBonus": {
"Currency": "CHF",
"ConvertedValue": "8000"
}
}}},
"Round": {
"PlanEndDate": "31/12/2024",
"PlanStartDate": "01/01/2024",
"CompensationRoundName": "Bonus Plan ABC Company 2024"
},
"ModelData": {
"WorkerLastName": "Test",
"WorkerFirstName": "Employee",
"EmploymentLineManagerIdLastName": "Test",
"EmploymentLineManagerIdFirstName": "Manager"
}
}Structure for Salary BQBP1001:
{
"Round": {
"PlanEndDate": "06/10/2025 00:00:00",
"PlanStartDate": "06/03/2025 00:00:00",
"CompensationRoundName": "compRoundName123"
},
"RoundData":{
"BQBP1001_NewValue": {
"Currency": "CHF",
"ConvertedValue": "100.000"
},
"BQBP1001_IncreaseAmount": {
"Currency": "CHF",
"ConvertedValue": "50.000"
},
"BQBP1001_IncreasePercentage":"100"
},
"ModelData": {
"WorkerLastName": "Test",
"WorkerFirstName": "Employee",
"EmploymentLineManagerIdLastName": "Test",
"EmploymentLineManagerIdFirstName": "Manager"
}
}Important notes
If you want to display CalculationData with Bonus, your document must follow the Bonus structure as shown above, including the SituationDetails array and CalculatedBonus / TargetBonus.
To display RoundData for Salary, the Salary structure must be followed correctly.
You can mix ModelData and Round fields in any template.
You must define correct loop blocks for any array-type data.
All values are converted to string using Invariant Culture (dates and numbers).
Important rules
For the same communication round, each generation overrides the previous generation files if the same file name is used.
If a variable is used in the DOCX template but is not included in the generation payload JSON, the document generation will fail with an error.
If a variable exists in the JSON payload but is not used in the DOCX template, no error will occur.
If an array-type field (like Bonus.SituationsDetails or PayoutCurveResults) is exposed in JSON but the DOCX template does not use a loop, this will cause a generation error.
If the result of CalculationData or RoundData for a specific element is null for a worker, document generation for that worker will fail.
Limitations
It is not possible to choose different locales (cultures) to case dates and numbers based on a worker’s culture.
It is not possible to configure decimal precision.
It is not possible to re-run statement generation only for failed workers; each time, generation will be performed for the whole distribution group.