Template Management
Templates define the structure and content of generated documents. This guide covers creating, updating, versioning, and promoting templates.
Creating a Template
- cURL
- JavaScript
curl -X POST "https://api.propper.ai/v1/docgen/templates" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Welcome Letter",
"description": "New customer welcome letter",
"content": "<h1>Welcome, {{customerName}}!</h1><p>Your account ({{accountId}}) is ready.</p>",
"format": "HTML"
}'
const response = await fetch('https://api.propper.ai/v1/docgen/templates', {
method: 'POST',
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: 'Welcome Letter',
description: 'New customer welcome letter',
content: '<h1>Welcome, {{customerName}}!</h1><p>Your account ({{accountId}}) is ready.</p>',
format: 'HTML',
}),
});
const template = await response.json();
Recipient (signature) placeholders
Templates that are later sent for signature can place recipient fields inline using the reserved propper.sign.recipient namespace. Each placeholder is 1-indexed by recipient ordinal:
{{propper.sign.recipient.N.<kind>}} auto / action fields
{{propper.sign.recipient.N.<kind>.<fieldId>}} custom inputs
{{propper.sign.recipient.N.radio.<fieldId>.<option>}} radio options
Nis the recipient number (1,2, …), matching the order you assign recipients at send time.- Auto/action kinds:
signature,initials,dateSigned,fullName,title,company,agreementId. - Custom input kinds require a
fieldId(letters, digits, underscores; must start with a letter or underscore):text,email,number,date,checkbox,dropdown,radio,attachment.radiotakes an optional trailing option segment.
For example, {{propper.sign.recipient.1.signature}} becomes the first recipient's signature field, {{propper.sign.recipient.1.dateSigned}} auto-fills the date they sign, and {{propper.sign.recipient.2.text.employeeId}} is a text input collected from the second recipient. These placeholders render as nothing in a plain generated document and become signature fields automatically when the generated document is sent for signature.
Collections (repeating data)
A collection is a typed, repeating data field — use it for line items, tables, schedules, or any list whose length you do not know ahead of time. Declare a collection in the template's dataSchema so the payload can be validated at generation time:
{
"lineItems": {
"type": "collection",
"item": {
"fields": [
{ "key": "description", "type": "text", "label": "Description" },
{ "key": "quantity", "type": "number", "label": "Qty" },
{ "key": "amount", "type": "currency", "label": "Amount" },
{ "key": "deliveredOn", "type": "date", "label": "Delivered" }
]
}
}
}
Each item field has a key, a type (text, number, currency, date, or boolean), and a display label. In the template body, a collection renders through a repeating section that iterates over the array:
At generation time, pass the collection as an array of objects whose keys match the declared item fields:
{
"lineItems": [
{ "description": "Consulting", "quantity": 10, "amount": 5000, "deliveredOn": "2024-01-10" },
{ "description": "Development", "quantity": 20, "amount": 10000, "deliveredOn": "2024-01-12" }
]
}
Each row is rendered once by the template's repeating section. If a declared collection is not an array, or an item's values do not match the declared field types, generation returns a 400 so you can correct the payload before the document is produced.
Updating a Template
Update a template's name, description, or content. This creates a new version automatically.
- cURL
- JavaScript
curl -X PATCH "https://api.propper.ai/v1/docgen/templates/{templateId}" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Welcome Letter v2",
"content": "<h1>Welcome, {{customerName}}!</h1><p>Your account ({{accountId}}) is active since {{startDate}}.</p>"
}'
const response = await fetch(`https://api.propper.ai/v1/docgen/templates/${templateId}`, {
method: 'PATCH',
headers: {
Authorization: `Bearer ${token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
name: 'Welcome Letter v2',
content:
'<h1>Welcome, {{customerName}}!</h1><p>Your account ({{accountId}}) is active since {{startDate}}.</p>',
}),
});
Archiving a Template
Archive a template to prevent it from being used in new document generation. Requires docgen:admin scope.
curl -X POST "https://api.propper.ai/v1/docgen/templates/{templateId}/archive" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Template Versioning
Create a New Version
curl -X POST "https://api.propper.ai/v1/docgen/templates/{templateId}/versions" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"content": "<h1>Updated content for {{customerName}}</h1>",
"changeNotes": "Updated header formatting"
}'
List Versions
curl "https://api.propper.ai/v1/docgen/templates/{templateId}/versions" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Response:
{
"data": [
{
"id": "ver_001",
"version": 3,
"changeNotes": "Updated header formatting",
"createdAt": "2024-01-17T10:00:00Z"
},
{
"id": "ver_002",
"version": 2,
"changeNotes": "Added start date field",
"createdAt": "2024-01-16T10:00:00Z"
}
]
}
Restore a Version
Restore a previous version to make it the active version.
curl -X POST "https://api.propper.ai/v1/docgen/templates/{templateId}/versions/{versionId}/restore" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN"
Cloning a Template
Create a copy of an existing template.
curl -X POST "https://api.propper.ai/v1/docgen/templates/{templateId}/clone" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "Welcome Letter (Copy)"
}'
Promoting Templates
Promote a template between environments (DEV, TEST, PROD). Requires docgen:admin scope and may trigger an approval workflow.
curl -X POST "https://api.propper.ai/v1/docgen/templates/{templateId}/promote" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"targetEnvironment": "PROD"
}'
If approval is required, the response includes a pending approval:
{
"id": "tmpl_abc123",
"promotionStatus": "PENDING_APPROVAL",
"approvalId": "apr_def456"
}
See the Approvals Guide for managing approval workflows.