Generate from Template
Generate a document by combining a stored template with a data object. All $data references and source bindings in the template are resolved with the provided data before rendering. Append the desired format to the endpoint path.
POST /documents/generate-from-template/{format}
Endpoint
POST /v1/{tenantId}/documents/generate-from-template/{format}
format | Output |
|---|---|
pdf | PDF document (default) |
docx | Word document |
Headers
| Header | Value | Required |
|---|---|---|
Authorization | Bearer YOUR_ACCESS_TOKEN | Yes |
Content-Type | application/json | Yes |
YOUR_ACCESS_TOKEN is the access token you get by exchanging your API key's Client ID and secret; see Authentication.
Path parameters
| Parameter | Type | Description |
|---|---|---|
tenantId | string | Your tenant identifier |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
templateId | string (GUID) | Yes | ID of the stored template |
data | object | Yes | Data object with values to inject into the template |
{
"templateId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"data": {
"client": {
"companyName": "Meridian Logistics",
"contactName": "Sarah Mitchell",
"address": "12 Harbor Road",
"city": "Austin, TX"
},
"document": {
"title": "Professional Services Invoice",
"date": "March 30, 2026"
},
"lineItems": [
{ "service": "Platform setup", "hours": "80", "rate": "$150", "total": "$12,000" },
{ "service": "API integration", "hours": "40", "rate": "$175", "total": "$7,000" }
],
"invoice": {
"grandTotal": "$19,000"
},
"paymentTerms": [
"Wire transfer to ShipForge Ltd account",
"Net 30 days from invoice date"
]
}
}
Response
Success (200 OK)
Returns the generated document metadata with a download URL.
{
"fileName": "docpayload_v1-d4e5f6a7b8c90123456789abcdef0123.pdf",
"documentId": "d4e5f6a7b8c90123456789abcdef0123",
"status": "Succeeded",
"fileSizeBytes": 31744,
"contentType": "application/pdf",
"downloadUrl": "https://api.docpayload.com/v1/{tenantId}/assets/docs/docpayload_v1-d4e5f6a7b8c90123456789abcdef0123.pdf",
"errorCodes": []
}
The fileName and contentType reflect the requested format.
errorCodes
A document can be generated and still lack something it asked for: an image that was not found, a token with no value. The document is written, stored and counted, and errorCodes names what is missing, each code once. It is
empty when the document got everything it asked for, so check it before you hand a document on.
| Code | The document lacks |
|---|---|
IMAGE_NOT_LOADED | an image: it was not found, could not be read or could not be decoded |
FONT_NOT_LOADED | a font file it declares: it was not found or could not be read, and its text is set in another face |
SVG_NOT_LOADED | an svg file: it was not found or could not be read |
ATTACHMENT_NOT_EMBEDDED | an attachment: the file was not found or could not be read |
UNRESOLVED_TOKEN | a value: a $data or $global token had none, and its own spelling is on the page |
CONFORMANCE_WITHHELD | a conformance claim: the file does not meet a PDF/A or PDF/UA claim it would carry, so the claim is left out (Conformance). An encrypted document is simply not archival, and carries no code for it |
CONTENT_ERROR | something else the definition asked for |
Error (400 Bad Request): the signature could not be applied
Returned when the document asks for a signature and it cannot be applied. A signed document that is not signed is not the document you asked for, so nothing is generated, stored or counted.
{
"title": "Bad Request",
"status": 400,
"detail": "The document asks for a signature that could not be applied: its certificate was not found, could not be opened or holds no private key. Nothing was generated or billed.",
"errorCode": "SIGNATURE_NOT_APPLIED",
"isRetryable": false
}
Error (404 Not Found)
Returned when the template ID does not exist or does not belong to your tenant.
{
"message": "Template 'a1b2c3d4-e5f6-7890-abcd-ef1234567890' not found."
}
Error (400 Bad Request)
Returned when the template does not contain a valid document definition.
{
"message": "The template does not contain a valid document definition."
}
Example
curl -X POST https://api.docpayload.com/v1/{tenantId}/documents/generate-from-template/pdf \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"templateId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"data": {
"client": {
"companyName": "Meridian Logistics"
},
"document": {
"title": "Delivery Receipt"
}
}
}'
Data resolution
When this endpoint is called, the following resolution steps occur:
- The template is retrieved from the database by
templateId. - The template's
content(a JSON string) is parsed into a document definition. - All
$data.path.to.valuescalar references in paragraph text are replaced with values from thedataobject. - All
$datareferences in form field default values (textfield, checkbox, textarea) are resolved. - All
sourcebindings on tables and lists are resolved:- Table
sourcearrays are mapped to rows usingmap. - List
sourcearrays are converted to list items.
- Table
- The resolved document definition is rendered to the requested format (PDF or DOCX).
What is resolved
| Feature | Example | Description |
|---|---|---|
| Scalar text | $data.client.name | Replaced with the value at the given path |
| Nested paths | $data.client.address.city | Dot-separated traversal of nested objects |
| Inside formatting | [b]$data.total[/b] | Ref resolved, then formatting applied |
| Form defaults | '$data.applicant.email' | Pre-fills editable form fields |
| Table rows | "source": "$data.items" | Array items become table rows |
| List items | "source": "$data.notes" | Array items become list items |
| Unresolved refs | $data.missing.key | Preserved as literal text |
Downloading the document
Use the downloadUrl from the response to fetch the generated document:
curl -X GET "https://api.docpayload.com/v1/{tenantId}/assets/docs/docpayload_v1-d4e5f6a7b8c90123456789abcdef0123.pdf" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-o invoice.pdf