Endorsement steps decide which schedules, forms and clauses go on a policy. A Mustache or Handlebars template then reads the quote response to choose which sections appear and to fill them in, for any line of business.
Ptally does not hold your document layouts. It gives you a response with every decision already made, so your template only has to display it.
Each item is a rule with a form code as its value. Rules that fire are listed in the response's endorsements array, with the step key, the rule name, the code and its description.
{
"id": "policy_forms",
"key": "policy_forms",
"step": "endorsements",
"name": "Policy forms",
"def": [],
"items": [
{
"id": "telematics",
"name": "Telematics fitted",
"exp": "{{telematics}} == true",
"value": "END_TELEMATICS",
"description": "Telematics data condition applies."
},
{
"id": "hazardous_goods",
"name": "Carries hazardous goods",
"exp": "{{hazardous_goods}} == true",
"value": "END_HAZ_GOODS",
"description": "ADR hazardous goods extension applies."
},
{
"id": "young_drivers",
"name": "Drivers under 25",
"exp": "{{drivers_under_25}} > 0",
"value": "END_YOUNG_DRIVER",
"description": "Young driver excess and named-driver condition apply."
},
{
"id": "vehicle_schedule",
"name": "More than 20 vehicles",
"exp": "{{vehicle_count}} > 20",
"value": "SCHED_VEHICLES",
"description": "Vehicles listed in a separate schedule."
}
]
}{
"quote_reference": "<uuid>",
"version_reference": "<uuid>",
"result": 18420.64,
"valid": true,
"input": {
"vehicle_count": 24,
"telematics": true,
"hazardous_goods": false,
"drivers_under_25": 2,
"region": "north_west"
},
"output": {
"result": 18420.64,
"valid": true,
"risk_premium": 16447,
"ipt": 1973.64,
"compulsory_excess": 500
},
"refers": [],
"exclusions": [],
"endorsements": [
{
"step": "policy_forms",
"name": "Telematics fitted",
"exp": "{{telematics}} == true",
"result": true,
"value": "END_TELEMATICS",
"description": "Telematics data condition applies."
},
{
"step": "policy_forms",
"name": "Drivers under 25",
"exp": "{{drivers_under_25}} > 0",
"result": true,
"value": "END_YOUNG_DRIVER",
"description": "Young driver excess and named-driver condition apply."
},
{
"step": "policy_forms",
"name": "More than 20 vehicles",
"exp": "{{vehicle_count}} > 20",
"result": true,
"value": "SCHED_VEHICLES",
"description": "Vehicles listed in a separate schedule."
}
]
}Three of the four rules fired. No hazardous goods are carried, so END_HAZ_GOODS is absent and its section won't be printed. See the API for the full response.
Turn the form codes into flags, then pass the whole response to your template. Flags show or hide sections, partials hold each form's wording, and output fields fill in the figures.
import Mustache from "mustache";
// The response from POST /quotes/:project_reference,
// or a saved quote from GET /quotes/:quote_reference
const quote = await res.json();
// Turn the form codes into flags the template can test
const forms = Object.fromEntries(
quote.endorsements
.filter((e) => e.step === "policy_forms")
.map((e) => [e.value, true])
);
const html = Mustache.render(schedule, { ...quote, forms }, partials);<h1>Fleet policy schedule</h1>
<p>Policy {{quote_reference}} · {{input.vehicle_count}} vehicles</p>
<table>
<tr><td>Premium</td><td>£{{output.risk_premium}}</td></tr>
<tr><td>Insurance Premium Tax</td><td>£{{output.ipt}}</td></tr>
<tr><td>Total payable</td><td>£{{result}}</td></tr>
<tr><td>Compulsory excess</td><td>£{{output.compulsory_excess}}</td></tr>
</table>
{{#forms.SCHED_VEHICLES}}{{> vehicle_schedule}}{{/forms.SCHED_VEHICLES}}
{{#forms.END_TELEMATICS}}{{> telematics_condition}}{{/forms.END_TELEMATICS}}
{{#forms.END_HAZ_GOODS}}{{> hazardous_goods}}{{/forms.END_HAZ_GOODS}}
{{#forms.END_YOUNG_DRIVER}}{{> young_driver}}{{/forms.END_YOUNG_DRIVER}}
<h2>Endorsements</h2>
{{#endorsements}}
<p><strong>{{value}}</strong> {{name}}. {{description}}</p>
{{/endorsements}}The syntax works in Mustache and Handlebars. Liquid, Jinja or a PDF generator that takes JSON work the same way.
Endorsements choose the sections. The rest of the model supplies what goes in them and whether a document should be issued at all.
| Step | Document part | How it is used |
|---|---|---|
endorsements | Forms, schedules and clauses | Each rule that fires adds a code. The template uses the codes to choose which sections and wordings appear. |
excesses | Excess schedule | Rules that add excesses for a risk, such as young drivers or high-value items. Expose the figure as an output field to print it. |
exclusion · refer | Whether to issue at all | A declined quote comes back with valid false, so no document is produced. A referred quote can be held for an underwriter before it is issued. |
calculation | Premium breakdown | Net premium, tax, fees, commission and instalments, each exposed as an output field and printed to the penny. |
collection | Wording lookups | Tables of territory clauses, insurer details, regulator text or limits by product, looked up per risk rather than hard-coded in the template. |
transform | Display values | Labels, dates and formatted strings shaped for the document, such as a policy period or a cover description. |
Rules about cover live in one place, are tested with the rating, and are published as one version.