Core Operations
Endpoints for listing, creating, reading, updating, deleting, and copying Templates, plus reading a Template's owner and the datasets its processors produce.
Every core Template route is gated by the templates license feature
(req.assertFeature('templates')). On a tenant whose license lacks that
feature, the whole route tree answers 400. Read access is enforced by the
read_access model scope rather than a permission, so list and lookup routes
return only the Templates the caller may see, and an id the caller cannot see
answers 404. The id segment of any /api/templates/{id} route resolves by
either the natural id (ownerId:slug) or the UUID.
GET /api/templates
List Templates as a HAL collection.
Authentication: Required
Response:
A HAL collection (rel inf:templates) of the read-access-scoped Templates. This
is not a { total, limit, offset, results } envelope despite earlier docs
describing it as paginated.
{
"_links": {
"self": {
"href": "https://informer.example.com/api/templates"
}
},
"items": [
{
"naturalId": "admin:monthly-report",
"permissions": {
"assignTags": false,
"edit": false,
"share": false,
"delete": false,
"write": false,
"changeOwner": false,
"copy": false,
"rename": false,
"modifyInputSettings": false
},
"tenant": "acme",
"id": "00000000-0000-4000-8000-000000000001",
"type": "nunjucks",
"name": "Monthly Report",
"ownerId": "admin",
"slug": "monthly-report",
"description": "Generate monthly sales reports",
"settings": {},
"editingId": null,
"templateFileId": null,
"letterheadId": null,
"handler": "pdf",
"handlerOptions": {},
"source": null,
"sourceId": null,
"shared": false,
"createdAt": "2026-01-15T16:20:00.000Z",
"updatedAt": "2026-01-15T16:20:00.000Z",
"folderId": null,
"files": [],
"inputs": [],
"processors": []
},
{
"naturalId": "admin:monthly-report-2",
"permissions": {
"assignTags": false,
"edit": false,
"share": false,
"delete": false,
"write": false,
"changeOwner": false,
"copy": false,
"rename": false,
"modifyInputSettings": false
},
"tenant": "acme",
"id": "00000000-0000-4000-8000-000000000002",
"type": "nunjucks",
"name": "Monthly Report",
"ownerId": "admin",
"slug": "monthly-report-2",
"description": null,
"settings": {},
"editingId": "00000000-0000-4000-8000-000000000001",
"templateFileId": null,
"letterheadId": null,
"handler": "pdf",
"handlerOptions": {},
"source": null,
"sourceId": null,
"shared": false,
"createdAt": "2026-01-15T16:20:00.000Z",
"updatedAt": "2026-01-15T16:20:00.000Z",
"folderId": null,
"files": [],
"inputs": [],
"processors": []
},
{
"naturalId": "admin:scratch-template",
"permissions": {
"assignTags": false,
"edit": false,
"share": false,
"delete": false,
"write": false,
"changeOwner": false,
"copy": false,
"rename": false,
"modifyInputSettings": false
},
"tenant": "acme",
"id": "00000000-0000-4000-8000-000000000003",
"type": "nunjucks",
"name": "Scratch Template",
"ownerId": "admin",
"slug": "scratch-template",
"description": null,
"settings": {},
"editingId": null,
"templateFileId": null,
"letterheadId": null,
"handler": "pdf",
"handlerOptions": {},
"source": null,
"sourceId": null,
"shared": false,
"createdAt": "2026-01-15T16:20:00.000Z",
"updatedAt": "2026-01-15T16:20:00.000Z",
"folderId": null,
"files": [],
"inputs": [],
"processors": []
},
"… 1 more items (4 total) — omitted from docs"
],
"start": 0,
"count": 4,
"total": 4
}
POST /api/templates
Create a Template, optionally with initial files.
Authentication: Required
Pre-blocks: permission.templates.create (designer, plus the templates
feature)
Request Body:
The payload is stripUnknown, so unrecognized fields are dropped rather than
rejected. type and handler are validated against the registered drivers by
the model, so unknown values answer 400. ownerId is server-derived from the
caller and cannot be set from the payload.
| Field | Type | Required | Description |
|---|---|---|---|
name | string | Yes | Template name |
description | string | No | Template description |
type | string | No | Template engine, validated against registered drivers (default nunjucks) |
handler | string | No | Output handler, validated against registered drivers (default pdf) |
handlerOptions | object | No | Handler-specific configuration (default {}) |
initialFiles | array | No | Initial files to create (default []) |
initialFiles array items:
| Field | Type | Required | Description |
|---|---|---|---|
role | string | Yes | File role: TEMPLATE, ASSET, or DATA |
filename | string | Yes | Filename with extension |
primary | boolean | No | Mark as the primary Template file |
contentType | string | No | MIME type |
payload | string | No | File contents as a string |
Example Request:
{
"name": "Quarterly Report",
"description": "Generate quarterly sales reports",
"type": "nunjucks",
"handler": "pdf",
"handlerOptions": {
"pageSize": "letter",
"margin": "1in"
},
"initialFiles": [
{
"primary": true,
"role": "TEMPLATE",
"filename": "report.html",
"contentType": "text/html",
"payload": "<html><body><h1>{{ title }}</h1></body></html>"
},
{
"role": "ASSET",
"filename": "styles.css",
"contentType": "text/css",
"payload": "body { font-family: Arial; }"
}
]
}
Response:
The handler creates the Template, writes any initialFiles, creates a draft,
and responds 201 Created with the new Template and a Location header (built
from the Template's natural id).
{
"name": "Quarterly Report",
"description": "Generate quarterly sales reports",
"type": "nunjucks",
"handler": "pdf",
"handlerOptions": {
"pageSize": "letter",
"margin": "1in"
},
"initialFiles": [
{
"primary": true,
"role": "TEMPLATE",
"filename": "report.html",
"contentType": "text/html",
"payload": "<html><body><h1>{{ title }}</h1></body></html>"
},
{
"role": "ASSET",
"filename": "styles.css",
"contentType": "text/css",
"payload": "body { font-family: Arial; }"
}
]
}
{
"_links": {
"self": {
"href": "https://informer.example.com/api/templates/admin%3Aquarterly-report"
},
"inf:draft": {
"href": "https://informer.example.com/api/templates/admin%3Aquarterly-report/draft"
},
"inf:edit": {
"href": "https://informer.example.com/api/templates/admin%3Aquarterly-report/_edit"
},
"inf:comments": {
"href": "https://informer.example.com/api/templates/admin%3Aquarterly-report/comments{?sort,limit}",
"templated": true
},
"inf:template-share": {
"href": "https://informer.example.com/api/templates/admin%3Aquarterly-report/shares/{principalId}",
"templated": true
},
"inf:template-processors": {
"href": "https://informer.example.com/api/templates/admin%3Aquarterly-report/processors"
},
"inf:template-inputs": {
"href": "https://informer.example.com/api/templates/admin%3Aquarterly-report/inputs"
},
"inf:template-owner": {
"href": "https://informer.example.com/api/templates/admin%3Aquarterly-report/owner"
},
"inf:template-shares": {
"href": "https://informer.example.com/api/templates/admin%3Aquarterly-report/shares"
},
"inf:template-files": {
"href": "https://informer.example.com/api/templates/admin%3Aquarterly-report/files"
},
"inf:template-file-upload": {
"href": "https://informer.example.com/api/templates/admin%3Aquarterly-report/files/_upload"
},
"inf:template-file": {
"href": "https://informer.example.com/api/templates/admin%3Aquarterly-report/template-file"
},
"inf:export": {
"href": "https://informer.example.com/api/templates/admin%3Aquarterly-report/_export"
},
"inf:render": {
"href": "https://informer.example.com/api/templates/admin%3Aquarterly-report/_render"
},
"inf:render-prompt": {
"href": "https://informer.example.com/api/templates/admin%3Aquarterly-report/_render-prompt"
},
"inf:template-copy": {
"href": "https://informer.example.com/api/templates/admin%3Aquarterly-report/_copy"
},
"inf:processor-order": {
"href": "https://informer.example.com/api/templates/admin%3Aquarterly-report/_processor-order"
},
"inf:user-settings": {
"href": "https://informer.example.com/api/templates/admin%3Aquarterly-report/settings"
},
"inf:template-datasets": {
"href": "https://informer.example.com/api/templates/admin%3Aquarterly-report/datasets"
},
"inf:input-order": {
"href": "https://informer.example.com/api/templates/admin%3Aquarterly-report/_input-order"
},
"inf:favorite": {
"href": "https://informer.example.com/api/templates/admin%3Aquarterly-report/favorite"
},
"inf:template-input-locks": {
"href": "https://informer.example.com/api/templates/admin%3Aquarterly-report/input-locks"
}
},
"naturalId": "admin:quarterly-report",
"permissions": {
"assignTags": true,
"edit": true,
"share": true,
"delete": true,
"write": true,
"changeOwner": true,
"copy": true,
"rename": true,
"modifyInputSettings": true
},
"tenant": "acme",
"id": "00000000-0000-4000-8000-000000000001",
"shared": false,
"name": "Quarterly Report",
"description": "Generate quarterly sales reports",
"type": "nunjucks",
"handler": "pdf",
"handlerOptions": {
"margin": "1in",
"pageSize": "letter"
},
"updatedAt": "2026-01-15T16:20:00.000Z",
"createdAt": "2026-01-15T16:20:00.000Z",
"ownerId": "admin",
"slug": "quarterly-report",
"settings": {},
"templateFileId": "00000000-0000-4000-8000-000000000002",
"editingId": null,
"folderId": null,
"source": null,
"sourceId": null,
"letterheadId": null
}
GET /api/templates-list
List Templates as a flat array. This is the legacy compatibility endpoint.
Authentication: Required
Response:
A flat array (rel inf:templates-list) built by the template.list server
method. It excludes drafts (rows where editingId is null) and adds per-row
permissions, ownerName, favorite, tags, and naturalId. There is no
pagination envelope and no server-side ordering.
[
{
"id": "00000000-0000-4000-8000-000000000001",
"name": "Monthly Report",
"description": "Generate monthly sales reports",
"createdAt": "2026-01-15T16:20:00.000Z",
"updatedAt": "2026-01-15T16:20:00.000Z",
"shared": false,
"ownerId": "admin",
"folderId": null,
"username": "admin",
"favorite": false,
"naturalId": "admin:monthly-report",
"permissions": {
"assignTags": true,
"edit": true,
"share": true,
"delete": true,
"write": true,
"changeOwner": true,
"copy": true,
"rename": true,
"modifyInputSettings": true
},
"ownerName": "acme Administrator",
"tags": []
},
{
"id": "00000000-0000-4000-8000-000000000002",
"name": "Quarterly Report",
"description": "Generate quarterly sales reports",
"createdAt": "2026-01-15T16:20:00.000Z",
"updatedAt": "2026-01-15T16:20:00.000Z",
"shared": false,
"ownerId": "admin",
"folderId": null,
"username": "admin",
"favorite": false,
"naturalId": "admin:quarterly-report",
"permissions": {
"assignTags": true,
"edit": true,
"share": true,
"delete": true,
"write": true,
"changeOwner": true,
"copy": true,
"rename": true,
"modifyInputSettings": true
},
"ownerName": "acme Administrator",
"tags": []
},
{
"id": "00000000-0000-4000-8000-000000000003",
"name": "Scratch Template",
"description": null,
"createdAt": "2026-01-15T16:20:00.000Z",
"updatedAt": "2026-01-15T16:20:00.000Z",
"shared": false,
"ownerId": "admin",
"folderId": null,
"username": "admin",
"favorite": false,
"naturalId": "admin:scratch-template",
"permissions": {
"assignTags": true,
"edit": true,
"share": true,
"delete": true,
"write": true,
"changeOwner": true,
"copy": true,
"rename": true,
"modifyInputSettings": true
},
"ownerName": "acme Administrator",
"tags": []
}
]
GET /api/templates/{id}
Retrieve a single Template.
Authentication: Required
Pre-blocks: template.lookup(params.id)
Response:
The single Template (rel inf:template), with _links to its files,
processors, inputs, and render endpoint.
{
"_links": {
"self": {
"href": "https://informer.example.com/api/templates/00000000-0000-4000-8000-000000000001"
},
"inf:draft": {
"href": "https://informer.example.com/api/templates/admin%3Amonthly-report/draft"
},
"inf:edit": {
"href": "https://informer.example.com/api/templates/admin%3Amonthly-report/_edit"
},
"inf:comments": {
"href": "https://informer.example.com/api/templates/admin%3Amonthly-report/comments{?sort,limit}",
"templated": true
},
"inf:template-share": {
"href": "https://informer.example.com/api/templates/00000000-0000-4000-8000-000000000001/shares/{principalId}",
"templated": true
},
"inf:template-processors": {
"href": "https://informer.example.com/api/templates/00000000-0000-4000-8000-000000000001/processors"
},
"inf:template-inputs": {
"href": "https://informer.example.com/api/templates/00000000-0000-4000-8000-000000000001/inputs"
},
"inf:template-owner": {
"href": "https://informer.example.com/api/templates/00000000-0000-4000-8000-000000000001/owner"
},
"inf:template-shares": {
"href": "https://informer.example.com/api/templates/00000000-0000-4000-8000-000000000001/shares"
},
"inf:template-files": {
"href": "https://informer.example.com/api/templates/00000000-0000-4000-8000-000000000001/files"
},
"inf:template-file-upload": {
"href": "https://informer.example.com/api/templates/00000000-0000-4000-8000-000000000001/files/_upload"
},
"inf:template-file": {
"href": "https://informer.example.com/api/templates/00000000-0000-4000-8000-000000000001/template-file"
},
"inf:export": {
"href": "https://informer.example.com/api/templates/00000000-0000-4000-8000-000000000001/_export"
},
"inf:render": {
"href": "https://informer.example.com/api/templates/00000000-0000-4000-8000-000000000001/_render"
},
"inf:render-prompt": {
"href": "https://informer.example.com/api/templates/00000000-0000-4000-8000-000000000001/_render-prompt"
},
"inf:template-copy": {
"href": "https://informer.example.com/api/templates/00000000-0000-4000-8000-000000000001/_copy"
},
"inf:processor-order": {
"href": "https://informer.example.com/api/templates/00000000-0000-4000-8000-000000000001/_processor-order"
},
"inf:user-settings": {
"href": "https://informer.example.com/api/templates/00000000-0000-4000-8000-000000000001/settings"
},
"inf:template-datasets": {
"href": "https://informer.example.com/api/templates/00000000-0000-4000-8000-000000000001/datasets"
},
"inf:input-order": {
"href": "https://informer.example.com/api/templates/00000000-0000-4000-8000-000000000001/_input-order"
},
"inf:favorite": {
"href": "https://informer.example.com/api/templates/00000000-0000-4000-8000-000000000001/favorite"
},
"inf:template-input-locks": {
"href": "https://informer.example.com/api/templates/00000000-0000-4000-8000-000000000001/input-locks"
}
},
"naturalId": "admin:monthly-report",
"permissions": {
"assignTags": true,
"edit": true,
"share": true,
"delete": true,
"write": true,
"changeOwner": true,
"copy": true,
"rename": true,
"modifyInputSettings": true
},
"tenant": "acme",
"id": "00000000-0000-4000-8000-000000000001",
"type": "nunjucks",
"name": "Monthly Report",
"ownerId": "admin",
"slug": "monthly-report",
"description": "Generate monthly sales reports",
"settings": {},
"editingId": null,
"templateFileId": null,
"letterheadId": null,
"handler": "pdf",
"handlerOptions": {},
"source": null,
"sourceId": null,
"shared": false,
"createdAt": "2026-01-15T16:20:00.000Z",
"updatedAt": "2026-01-15T16:20:00.000Z",
"folderId": null,
"editing": null,
"files": [],
"inputs": [],
"processors": []
}
PUT /api/templates/{id}
Update Template properties.
Authentication: Required
Pre-blocks: template.lookup(params.id), permission.template.write(pre.template)
Request Body:
The payload is stripUnknown. description accepts an empty string and
letterheadId accepts null.
| Field | Type | Description |
|---|---|---|
name | string | Template name |
description | string | Template description (empty string allowed) |
type | string | Template engine |
handler | string | Output handler |
handlerOptions | object | Handler-specific configuration |
shared | boolean | Share the Template publicly within the tenant |
settings | object | Template settings |
letterheadId | string | null | Letterhead Template id (null clears it) |
Example Request:
{
"name": "Updated Monthly Report",
"description": "Enhanced monthly sales reports with charts",
"handlerOptions": {
"pageSize": "legal",
"margin": "0.5in"
}
}
Response:
The handler re-reads through the read_access scope and responds 200 with the
updated Template.
{
"name": "Updated Monthly Report",
"description": "Enhanced monthly sales reports with charts",
"handlerOptions": {
"pageSize": "legal",
"margin": "0.5in"
}
}
{
"_links": {
"self": {
"href": "https://informer.example.com/api/templates/00000000-0000-4000-8000-000000000001"
},
"inf:draft": {
"href": "https://informer.example.com/api/templates/admin%3Aupdated-monthly-report/draft"
},
"inf:edit": {
"href": "https://informer.example.com/api/templates/admin%3Aupdated-monthly-report/_edit"
},
"inf:comments": {
"href": "https://informer.example.com/api/templates/admin%3Aupdated-monthly-report/comments{?sort,limit}",
"templated": true
},
"inf:template-share": {
"href": "https://informer.example.com/api/templates/00000000-0000-4000-8000-000000000001/shares/{principalId}",
"templated": true
},
"inf:template-processors": {
"href": "https://informer.example.com/api/templates/00000000-0000-4000-8000-000000000001/processors"
},
"inf:template-inputs": {
"href": "https://informer.example.com/api/templates/00000000-0000-4000-8000-000000000001/inputs"
},
"inf:template-owner": {
"href": "https://informer.example.com/api/templates/00000000-0000-4000-8000-000000000001/owner"
},
"inf:template-shares": {
"href": "https://informer.example.com/api/templates/00000000-0000-4000-8000-000000000001/shares"
},
"inf:template-files": {
"href": "https://informer.example.com/api/templates/00000000-0000-4000-8000-000000000001/files"
},
"inf:template-file-upload": {
"href": "https://informer.example.com/api/templates/00000000-0000-4000-8000-000000000001/files/_upload"
},
"inf:template-file": {
"href": "https://informer.example.com/api/templates/00000000-0000-4000-8000-000000000001/template-file"
},
"inf:export": {
"href": "https://informer.example.com/api/templates/00000000-0000-4000-8000-000000000001/_export"
},
"inf:render": {
"href": "https://informer.example.com/api/templates/00000000-0000-4000-8000-000000000001/_render"
},
"inf:render-prompt": {
"href": "https://informer.example.com/api/templates/00000000-0000-4000-8000-000000000001/_render-prompt"
},
"inf:template-copy": {
"href": "https://informer.example.com/api/templates/00000000-0000-4000-8000-000000000001/_copy"
},
"inf:processor-order": {
"href": "https://informer.example.com/api/templates/00000000-0000-4000-8000-000000000001/_processor-order"
},
"inf:user-settings": {
"href": "https://informer.example.com/api/templates/00000000-0000-4000-8000-000000000001/settings"
},
"inf:template-datasets": {
"href": "https://informer.example.com/api/templates/00000000-0000-4000-8000-000000000001/datasets"
},
"inf:input-order": {
"href": "https://informer.example.com/api/templates/00000000-0000-4000-8000-000000000001/_input-order"
},
"inf:favorite": {
"href": "https://informer.example.com/api/templates/00000000-0000-4000-8000-000000000001/favorite"
},
"inf:template-input-locks": {
"href": "https://informer.example.com/api/templates/00000000-0000-4000-8000-000000000001/input-locks"
}
},
"naturalId": "admin:updated-monthly-report",
"permissions": {
"assignTags": true,
"edit": true,
"share": true,
"delete": true,
"write": true,
"changeOwner": true,
"copy": true,
"rename": true,
"modifyInputSettings": true
},
"tenant": "acme",
"id": "00000000-0000-4000-8000-000000000001",
"type": "nunjucks",
"name": "Updated Monthly Report",
"ownerId": "admin",
"slug": "updated-monthly-report",
"description": "Enhanced monthly sales reports with charts",
"settings": {},
"editingId": null,
"templateFileId": null,
"letterheadId": null,
"handler": "pdf",
"handlerOptions": {
"margin": "0.5in",
"pageSize": "legal"
},
"source": null,
"sourceId": null,
"shared": false,
"createdAt": "2026-01-15T16:20:00.000Z",
"updatedAt": "2026-01-15T16:20:00.000Z",
"folderId": null,
"files": [],
"inputs": [],
"processors": []
}
DELETE /api/templates/{id}
Delete a Template and its files, processors, and inputs.
Authentication: Required
Pre-blocks: template.lookup(params.id), permission.template.delete(pre.template)
Response:
Responds 200 with an empty body (Informer convention), not 204.
POST /api/templates/{id}/_copy
Create a copy of a Template, deep-copying its files, processors, and inputs.
Authentication: Required
Pre-blocks: template.lookup(params.id), permission.template.copy(pre.template), permission.templates.create
Request Body:
The payload is stripUnknown. progress is omitted before the copy runs.
| Field | Type | Description |
|---|---|---|
name | string | Name for the copied Template (defaults to the original name) |
progress | string | Progress-tracking id |
Example Request:
{
"name": "Copy of Monthly Report"
}
Response:
Responds 201 Created with the copied Template and a Location header.
{
"name": "Copy of Monthly Report"
}
{
"_links": {
"self": {
"href": "https://informer.example.com/api/templates/admin%3Aupdated-monthly-report-2"
},
"inf:draft": {
"href": "https://informer.example.com/api/templates/admin%3Aupdated-monthly-report-2/draft"
},
"inf:edit": {
"href": "https://informer.example.com/api/templates/admin%3Aupdated-monthly-report-2/_edit"
},
"inf:comments": {
"href": "https://informer.example.com/api/templates/admin%3Aupdated-monthly-report-2/comments{?sort,limit}",
"templated": true
},
"inf:template-share": {
"href": "https://informer.example.com/api/templates/admin%3Aupdated-monthly-report-2/shares/{principalId}",
"templated": true
},
"inf:template-processors": {
"href": "https://informer.example.com/api/templates/admin%3Aupdated-monthly-report-2/processors"
},
"inf:template-inputs": {
"href": "https://informer.example.com/api/templates/admin%3Aupdated-monthly-report-2/inputs"
},
"inf:template-owner": {
"href": "https://informer.example.com/api/templates/admin%3Aupdated-monthly-report-2/owner"
},
"inf:template-shares": {
"href": "https://informer.example.com/api/templates/admin%3Aupdated-monthly-report-2/shares"
},
"inf:template-files": {
"href": "https://informer.example.com/api/templates/admin%3Aupdated-monthly-report-2/files"
},
"inf:template-file-upload": {
"href": "https://informer.example.com/api/templates/admin%3Aupdated-monthly-report-2/files/_upload"
},
"inf:template-file": {
"href": "https://informer.example.com/api/templates/admin%3Aupdated-monthly-report-2/template-file"
},
"inf:export": {
"href": "https://informer.example.com/api/templates/admin%3Aupdated-monthly-report-2/_export"
},
"inf:render": {
"href": "https://informer.example.com/api/templates/admin%3Aupdated-monthly-report-2/_render"
},
"inf:render-prompt": {
"href": "https://informer.example.com/api/templates/admin%3Aupdated-monthly-report-2/_render-prompt"
},
"inf:template-copy": {
"href": "https://informer.example.com/api/templates/admin%3Aupdated-monthly-report-2/_copy"
},
"inf:processor-order": {
"href": "https://informer.example.com/api/templates/admin%3Aupdated-monthly-report-2/_processor-order"
},
"inf:user-settings": {
"href": "https://informer.example.com/api/templates/admin%3Aupdated-monthly-report-2/settings"
},
"inf:template-datasets": {
"href": "https://informer.example.com/api/templates/admin%3Aupdated-monthly-report-2/datasets"
},
"inf:input-order": {
"href": "https://informer.example.com/api/templates/admin%3Aupdated-monthly-report-2/_input-order"
},
"inf:favorite": {
"href": "https://informer.example.com/api/templates/admin%3Aupdated-monthly-report-2/favorite"
},
"inf:template-input-locks": {
"href": "https://informer.example.com/api/templates/admin%3Aupdated-monthly-report-2/input-locks"
}
},
"naturalId": "admin:updated-monthly-report-2",
"permissions": {
"assignTags": true,
"edit": true,
"share": true,
"delete": true,
"write": true,
"changeOwner": true,
"copy": true,
"rename": true,
"modifyInputSettings": true
},
"id": "00000000-0000-4000-8000-000000000002",
"tenant": "acme",
"type": "nunjucks",
"name": "Copy of Monthly Report",
"ownerId": "admin",
"slug": "updated-monthly-report-2",
"description": "Enhanced monthly sales reports with charts",
"settings": {},
"letterheadId": null,
"handler": "pdf",
"handlerOptions": {
"margin": "0.5in",
"pageSize": "legal"
},
"source": null,
"sourceId": null,
"shared": false,
"createdAt": "2026-01-15T16:20:00.000Z",
"updatedAt": "2026-01-15T16:20:00.000Z",
"folderId": null,
"editingId": null
}
POST /api/templates/{id}/_export
Export a Template as a portable package for import into another tenant.
Authentication: Required
Pre-blocks: template.lookup(params.id)
Response:
A downloadable export package containing the Template metadata, files, processors, and inputs.
Exporting runs a full Template render (PDF via Puppeteer) through an internal inject and produces a download resource. It is too expensive and non-deterministic to capture as a fixture, so no response is shown here.
POST /api/templates/{id}/_takeover
Take over editing of a Template that is currently being edited by another user.
Authentication: Required
Pre-blocks: template.lookup(params.id), permission.template.write(pre.template)
Response:
Confirms the takeover after the editing draft is reassigned to the caller.
Takeover requires a live draft owned by a different user and publishes realtime channel messages, so it is not captured as a fixture.
GET /api/templates/{id}/owner
Get the owner (user or team) of a Template.
Authentication: Required
Pre-blocks: template.lookup(params.id)
Response:
The owner Principal row, with inf:user or inf:team embedded depending on
which association matched. For a user-owned Template, inf:user is embedded and
the team link is absent.
{
"_links": {
"self": {
"href": "https://informer.example.com/api/templates/00000000-0000-4000-8000-000000000001/owner"
}
},
"id": "admin",
"userId": "admin",
"teamId": null,
"tenant": "acme",
"_embedded": {
"inf:user": {
"_links": {
"self": {
"href": "https://informer.example.com/api/users/admin"
},
"inf:memberships": {
"href": "https://informer.example.com/api/users/admin/memberships"
},
"inf:avatar-upload": {
"href": "https://informer.example.com/api/users/admin/_upload/{uploadId}/avatar-upload",
"templated": true
},
"inf:password": {
"href": "https://informer.example.com/api/users/admin/password"
},
"inf:feed": {
"href": "https://informer.example.com/api/users/admin/feed"
},
"inf:viewed-feed": {
"href": "https://informer.example.com/api/users/admin/_markFeedViewed"
},
"inf:superuser": {
"href": "https://informer.example.com/api/users/admin/superuser"
}
},
"permissions": {
"changeDomain": false,
"changeProfile": true,
"changePassword": true,
"delete": false,
"edit": true,
"reassign": true,
"superuser": true,
"enable": true,
"changeTheme": true,
"lock": true,
"setGlobalPermissions": true,
"manageLogin": true
},
"domain": "local",
"username": "admin",
"displayName": "acme Administrator",
"familyName": "Administrator",
"givenName": "acme",
"middleName": null,
"email": null,
"data": null,
"superuser": true,
"timezone": "America/New_York",
"settings": {
"log": {
"log": false,
"info": false,
"warn": false,
"debug": false,
"error": true,
"remote": false
}
},
"enabled": true,
"source": null,
"sourceId": null,
"lastViewedFeed": null,
"tenant": "acme",
"globalPermissions": {
"ai": false,
"jobCreation": true,
"viewAllTeams": true,
"viewAllUsers": true,
"painlessScriptCreation": true
},
"userFields": {},
"locked": false,
"lockedAt": null,
"loginAttempts": 0,
"passwordSetAt": "2026-01-15T16:20:00.000Z",
"passwordExpiresAt": "2026-01-15T16:20:00.000Z",
"forgotPasswordRequestTime": null,
"mfa": null,
"mfaConfig": {},
"aiMessage": null,
"aiConsent": false,
"hasSharedDatasources": false,
"createdAt": "2026-01-15T16:20:00.000Z",
"updatedAt": "2026-01-15T16:20:00.000Z",
"initials": "NA",
"colorIndex": 4,
"avatarColor": {
"background": "#81C784",
"text": "#1B5E20"
},
"managesPassword": true
}
}
}
PUT /api/templates/{id}/owner
Change the owner of a Template.
Authentication: Required
Pre-blocks: template.lookup(params.id), permission.template.write(pre.template), new-owner Principal lookup (by payload), permission.template.changeOwnerToTeam(pre.template, owner.teamId)
Request Body:
The new owner is resolved by looking up a Principal that matches the posted
fields; an unmatched lookup answers 400.
| Field | Type | Description |
|---|---|---|
id | string | New owner Principal id (user or team) |
Example Request:
{
"id": "engineering-team"
}
Response:
Responds 200 with the updated Template and a Location header. The handler
publishes a template-owner-change realtime message and records a
templateAssigned Activity.
Changing ownership reassigns to a different Principal and publishes realtime channel messages, so it is not captured as a fixture.
GET /api/templates/{id}/datasets
Get the datasets generated by this Template's processors.
Authentication: Required
Pre-blocks: template.lookup(params.id)
Response:
A read_access Dataset collection of the datasets generated by this Template's
processors, filtered by dataset.templateProcessorId and the caller's
ownerId, embedding inf:dataset (with inf:field). Datasets relate to a
Template through their producing processor; there is no dataset.templateId
column. A Template with no processor-backed datasets returns an empty
collection.
{
"_links": {
"self": {
"href": "https://informer.example.com/api/templates/00000000-0000-4000-8000-000000000001/datasets"
}
},
"start": 0,
"count": 0,
"total": 0,
"_embedded": {
"inf:dataset": []
}
}