Templates & versions
A template is the top-level catalogue entry—defining its name, project, and total version count.The actual template content (the DSL and its sample data) lives on its versions. This section is read-focused: creating, renaming and publishing templates happens in the workspace, not through the public API.
Endpoints
Section titled “Endpoints”| Operation | Endpoint |
|---|---|
| List templates | GET /v1/templates |
| List a project’s templates | GET /v1/projects/{projectId}/templates |
| Get a template | GET /v1/templates/{id} |
| List a template’s versions | GET /v1/templates/{templateId}/versions |
| Get a version | GET /v1/templates/{templateId}/versions/latest |
| Get a version | GET /v1/templates/{templateId}/versions/{versionNumber} |
| Update the document-name template | PATCH /v1/templates/{templateId}/versions/{versionNumber}/document-name-template |
| Get a preview image | GET /v1/templates/{templateId}/versions/{versionNumber}/preview-image |
All list endpoints share the listing and pagination contract.
Example
Section titled “Example”Find a template, then read the latest published version’s sample data — the usual starting point for building your own render payload.
# List templates whose name contains "invoice"curl -G "https://pagr-prd-api-public.azurewebsites.net/v1/templates" \ -H "Authorization: Bearer pagr_prod_xxxxxxxx" \ --data-urlencode "take=50" \ --data-urlencode "sortBy=name" \ --data-urlencode "filters[0].field=name" \ --data-urlencode "filters[0].op=contains" \ --data-urlencode "filters[0].value=invoice"
# Fetch the latest published version (carries templateJson + sampleData)curl "https://pagr-prd-api-public.azurewebsites.net/v1/templates/8bec66ff-6f3d-4c1e-9a2b-1f0e5d7c4a90/versions/latest" \ -H "Authorization: Bearer pagr_prod_xxxxxxxx"import asynciofrom pagr import PagrApiClient
async def main(): async with PagrApiClient("pagr_prod_xxxxxxxx") as client: page = await client.get_templates( take=50, sort_by="name", filters=[{"field": "name", "op": "contains", "value": "invoice"}], ) print(page.total, "matching template(s)") for template in page.items: print(template.name, template.latest_version_number)
version = await client.get_template_version(page.items[0].id) # latest published print(version.version_number, version.sample_data) # already a dict
asyncio.run(main())import { PagrApiClient } from 'pagr';
const client = new PagrApiClient('pagr_prod_xxxxxxxx');
const page = await client.getTemplates({ take: 50, sortBy: 'name', filters: [{ field: 'name', op: 'contains', value: 'invoice' }],});console.log(page.total, 'matching template(s)');for (const template of page) { console.log(template.name, template.latestVersionNumber);}
const version = await client.getTemplateVersion(page.items[0].id); // latest publishedconsole.log(version.versionNumber, version.sampleData);import org.example.*;import org.example.models.*;
try (PagrApiClient client = new PagrApiClient("pagr_prod_xxxxxxxx")) {
PagedResult<Template> page = client.getTemplates(ListOptions.builder() .take(50) .sortBy("name") .filter(new Filter("name", FilterOp.CONTAINS, "invoice")) .build());
System.out.println(page.getTotal() + " matching template(s)"); for (Template template : page.getItems()) { System.out.println(template.getName() + " " + template.getLatestVersionNumber()); }
TemplateVersion version = client.getTemplateVersion(page.getItems().get(0).getId()); System.out.println(version.getVersionNumber() + " " + version.getSampleData());}using Pagr.Sdk;
using var client = new PagrApiClient("pagr_prod_xxxxxxxx");
var page = await client.GetTemplatesAsync(new ListOptions{ Take = 50, SortBy = "name", Filters = [new Filter("name", FilterOp.Contains, "invoice")],});
Console.WriteLine($"{page.Total} matching template(s)");foreach (var template in page) Console.WriteLine($"{template.Name} {template.LatestVersionNumber}");
var version = await client.GetTemplateVersionAsync(page.Items[0].Id); // latest publishedConsole.WriteLine($"{version.VersionNumber} {version.SampleData}");require "pagr"
client = Pagr::Client.new("pagr_prod_xxxxxxxx")
page = client.templates( take: 50, sort_by: "name", filters: [{ field: "name", op: :contains, value: "invoice" }],)puts "#{page.total} matching template(s)"page.each { |template| puts "#{template.name} #{template.latest_version_number}" }
version = client.template_version(page.items.first.id) # latest publishedputs "#{version.version_number} #{version.sample_data}"#include "pagr/PagrApiClient.hpp"
pagr::PagrApiClient client("pagr_prod_xxxxxxxx");
pagr::ListOptions options;options.take = 50;options.sort_by = "name";options.filters.emplace_back("name", pagr::FilterOp::Contains, "invoice");
const auto page = client.get_templates(options);std::cout << page.total << " matching template(s)\n";for (const auto& template_item : page.items) { std::cout << template_item.name << "\n";}
const auto version = client.get_template_version(page.items.front().id);std::cout << version.version_number << " " << version.sample_data << "\n";Every call also has a _async form returning std::future<T>.
List templates
Section titled “List templates”GET /v1/templatesGET /v1/projects/{projectId}/templatesLists templates for the authenticated organisation, or — using the second form — only those in one project.
Path parameters
Section titled “Path parameters”| Parameter | Type | Required | Description |
|---|---|---|---|
projectId |
string (UUID) | Only for the project-scoped form | Restricts the list to that project. |
Query parameters
Section titled “Query parameters”The shared skip / take / sortBy / sortDirection / search /
filters[i] set.
- Sortable fields:
name,createdAt,updatedAt(the default). - Filterable fields:
name(eq,contains),project.id(eq),createdAt/updatedAt(eq,gt,gte,lt,lte). searchmatchesname.
Response
Section titled “Response”200 → a paged result of templates:
{ "items": [ { "id": "8bec66ff-6f3d-4c1e-9a2b-1f0e5d7c4a90", "name": "Invoice", "documentNameTemplate": "Invoice {{Number}}", "projectId": "3d2f1a90-…", "projectName": "Billing", "latestVersionNumber": 3, "versionCount": 4, "updatedAt": "2026-07-20T14:02:00Z", "updatedBy": "jane@acme.com", "masterTemplateId": null, "masterTemplateName": null } ], "total": 1, "skip": 0, "take": 25}| Field | Type | Description |
|---|---|---|
id |
string (UUID) | The template id — what you pass to the render endpoints. |
name |
string | The template’s display name. |
documentNameTemplate |
string or null | The pattern used to name rendered documents. |
projectId / projectName |
string or null | The project the template belongs to. |
latestVersionNumber |
number or null | The newest published version. null until something is published. |
versionCount |
number | Total versions, published or not. |
updatedAt / updatedBy |
string / string | Audit fields. |
masterTemplateId / masterTemplateName |
string or null | Populated only when the template descends from a Master Template. |
Get a template
Section titled “Get a template”GET /v1/templates/{id}| Parameter | Type | Required | Description |
|---|---|---|---|
id |
string (UUID) | Yes | The template’s id. |
Response: 200 → a single template object, same shape as one items entry
above. 404 if it doesn’t exist or belongs to a different organisation.
List a template’s versions
Section titled “List a template’s versions”GET /v1/templates/{templateId}/versions| Parameter | Type | Required | Description |
|---|---|---|---|
templateId |
string (UUID), path | Yes | The template whose versions to list. |
Query parameters
Section titled “Query parameters”The shared listing set.
- Sortable fields:
versionNumber(the default),publishedAt,createdAt,updatedAt. - Filterable fields:
versionNumber,publishedAt,createdAt,updatedAt— all witheq,gt,gte,lt,lte.
Response: 200 → a paged result of version summaries: the same fields as
Get a version below, minus templateJson and sampleData
(those are only served by the single-version endpoint, since they can be large).
404 if the template doesn’t exist.
Get a version
Section titled “Get a version”GET /v1/templates/{templateId}/versions/latestGET /v1/templates/{templateId}/versions/{versionNumber}Fetch the latest published version, or a specific one by number. Unlike the list endpoints, this endpoint returns the actual template content (DSL) and its sample data.
| Parameter | Type | Required | Description |
|---|---|---|---|
templateId |
string (UUID), path | Yes | The template. |
versionNumber |
integer, path | Only for the specific-version form | The version number to fetch. |
Response
Section titled “Response”200:
{ "id": "f9a1c2e0-…", "versionNumber": 3, "templateJson": "{ … the template DSL … }", "sampleData": "{\"data\":{\"Title\":\"Acme Q3 Invoice\",\"Amount\":42},\"i18n\":{}}", "translations": null, "documentNameTemplate": "Invoice {{Number}}", "publishedAt": "2026-07-20T14:02:00Z", "publishedBy": "jane@acme.com", "templateId": "8bec66ff-6f3d-4c1e-9a2b-1f0e5d7c4a90", "updatedAt": "2026-07-20T14:02:00Z"}| Field | Type | Description |
|---|---|---|
id |
string (UUID) | The version’s own id (distinct from templateId). |
versionNumber |
number | The version number used in render paths. |
templateJson |
string | The raw template DSL, as a JSON string. Never parsed by any SDK — there’s no typed model for it yet. |
sampleData |
string | The version’s sample data, as a JSON string on the wire. Most SDKs parse it for you (see the note below). |
translations |
string or null | Translation strings as a raw JSON string, or null when the version has none. |
documentNameTemplate |
string or null | The naming pattern for documents rendered from this version. |
publishedAt / publishedBy |
string or null | When and by whom it was published. null for an unpublished draft. |
templateId |
string (UUID) | The parent template. |
updatedAt |
string | Last modification. |
sampleData matches the version’s bindings, so it’s the quickest correct payload
to pass to render or
validate.
Errors: 404 if the template or version doesn’t exist; for the latest form
specifically, 404 with code NoPublishedVersion when the template has no
published version yet.
Update a version’s document-name template
Section titled “Update a version’s document-name template”PATCH /v1/templates/{templateId}/versions/{versionNumber}/document-name-templateChanges the naming pattern used for documents rendered from this version (the
documentName field on a render
result). This is currently the only write operation the public API exposes for templates.
Request body
Section titled “Request body”{ "documentNameTemplate": "Invoice {{Number}}" }| Field | Type | Description |
|---|---|---|
documentNameTemplate |
string or null | The new pattern. Pass null to clear it. |
Response: 200 → the updated version, same shape as
Get a version. 404 if the template or version doesn’t exist.
Get a version’s preview image
Section titled “Get a version’s preview image”GET /v1/templates/{templateId}/versions/{versionNumber}/preview-imageResponse: 200 → { "url": "https://…" }, or { "url": null } when the
version exists but has no preview image yet. 404 if the template or version
doesn’t exist. The SDKs return the URL (or null) directly rather than a wrapper
object.
SDK reference
Section titled “SDK reference”| Operation | Python | TypeScript | Java | C# | Ruby | C++ |
|---|---|---|---|---|---|---|
| List templates | get_templates |
getTemplates |
getTemplates |
GetTemplatesAsync |
templates |
get_templates |
| Get a template | get_template |
getTemplate |
getTemplate |
GetTemplateAsync |
template |
get_template |
| List versions | get_template_versions |
getTemplateVersions |
getTemplateVersions |
GetTemplateVersionsAsync |
template_versions |
get_template_versions |
| Get a version | get_template_version |
getTemplateVersion |
getTemplateVersion |
GetTemplateVersionAsync |
template_version |
get_template_version |
| Update doc-name template | update_document_name_template |
updateDocumentNameTemplate |
updateDocumentNameTemplate |
UpdateDocumentNameTemplateAsync |
update_document_name_template |
update_document_name_template |
| Preview image URL | get_preview_image_url |
getPreviewImageUrl |
getPreviewImageUrl |
GetPreviewImageUrlAsync |
preview_image_url |
get_preview_image_url |
Calling get_template_version with no version argument fetches the latest
published one in every SDK.
Errors
Section titled “Errors”| Status | code |
When |
|---|---|---|
404 |
TemplateNotFound, EntityNotFound |
No such template, or it belongs to another organisation. |
404 |
VersionNotFound |
No such version number on this template. |
404 |
NoPublishedVersion |
The latest form, on a template with nothing published. |
See Errors for the full table.
Related articles
Section titled “Related articles”- Listing & pagination — the shared paging, sorting and filtering contract.
- Render a document — render using a template’s id.
- Validate data — check data against a specific version.
- Versions & publishing — what “published” means, from the workspace side.
- Template structure — the DSL carried in
templateJson.
