Document templates
Printable document templates — quotes, invoices, specifications — written in HTML with Handlebars placeholders, and the endpoints to manage them.
A document template turns an order into a printable document: a quote, an invoice, a production specification. A
template is HTML with Handlebars placeholders such as {{order.serial}} and
{{#each products}}. The app renders it against an order and converts it to PDF.
The templating language, the available fields and the allowed HTML are described in the user guide: Document templates. This page covers only managing templates through the API.
Templates with is_shown_widget: true can also be printed by customers in the widget.
Field types follow the field notation.
Access
Every endpoint on this page requires both the projects and documents OAuth scopes. The user must be a member of
the project, and the owner's subscription must be active. Otherwise the endpoint returns 404 RES_NOT_FOUND. The
project owner bypasses permission checks.
| Permission | Grants |
|---|---|
can_view_documents |
Read templates |
can_edit_documents |
Create, update and delete templates |
Document Template Object
Document Template Structure
| Field | Type | Description |
|---|---|---|
| uuid | uuid | Template ID |
| project_uuid | uuid | Project ID. Only in Get Document Template |
| name | string | Name, 1–255 characters |
| content | string | HTML with Handlebars placeholders, up to 3 MB (UTF-8) |
| is_shown_widget | boolean | Whether customers can print it from the widget |
| logo_uuid | ?uuid | File rendered by the {{{logo}}} placeholder |
| logo_url | ?string | Relative URL of the logo, /uploads/{uuid} |
| created_at | ISO8601 datetime | When the template was created |
| updated_at | ISO8601 datetime | When the template was last changed |
Example Document Template
{
"uuid": "0199ae5a-7182-7394-a5b6-c7d8e9f0a1b2",
"name": "Quote",
"content": "<style>table{width:100%}</style><div>{{{logo}}}</div><h1>Quote {{order.serial}}</h1><table>{{#each products}}<tr><td>{{name}}</td><td>{{quantity}} {{unit}}</td><td>{{sale_amount}}</td></tr>{{/each}}</table><p>Total: {{order.total_amount}}</p>",
"is_shown_widget": true,
"logo_uuid": "0199ae50-0000-7000-8000-000000000001",
"logo_url": "/uploads/0199ae50-0000-7000-8000-000000000001",
"created_at": "2026-08-14T13:00:00.000Z",
"updated_at": "2026-09-20T10:15:00.000Z"
}
List Document Templates
GET /api/v1/projects/{project.uuid}/documents
Returns the project's templates, oldest first, including content. Requires can_view_documents.
Get Document Template
GET /api/v1/projects/{project.uuid}/documents/{document.uuid}
Requires can_view_documents.
Create Document Template
POST /api/v1/projects/{project.uuid}/documents
Requires can_edit_documents.
JSON Params
| Field | Type | Description |
|---|---|---|
| name | string | 1–255 characters |
| content | string | Template HTML, up to 3 MB |
| is_shown_widget? | boolean | Default false |
| logo_uuid? | ?uuid | Logo file |
The template is not checked for syntax when saved. Unsupported HTML is removed only when a document is rendered.
Response
201 Created with {"uuid": "..."}.
Modify Document Template
PATCH /api/v1/projects/{project.uuid}/documents/{document.uuid}
Updates any of name, content, is_shown_widget, logo_uuid. At least one must be present. PUT requires all
four; logo_uuid may be null.
204 No Content. Requires can_edit_documents.
Delete Document Template
DELETE /api/v1/projects/{project.uuid}/documents/{document.uuid}
204 No Content. Requires can_edit_documents.
Errors
| Status | Code | When |
|---|---|---|
| 400 | REQ_VALIDATION_FAILED |
The body does not match the schema, or content is larger than 3 MB |
| 400 | RES_NOT_FOUND |
logo_uuid is not a file of this project or of the user |
| 400 | REQ_NO_DATA_PROVIDED |
Modify: the body has no fields |
| 403 | AUTH_INSUFFICIENT_SCOPE |
The token lacks projects or documents |
| 403 | AUTH_NO_PROJECT_ACCESS |
The user's role lacks can_view_documents (read) or can_edit_documents (write) |
| 404 | RES_NOT_FOUND |
The project or template does not exist |