Pulp Engine API
Template management and document rendering API for Pulp Engine. Authenticate with X-Api-Key (scoped API keys) or X-Editor-Token (short-lived session token). See /docs for the interactive UI. API stability policy: https://github.com/TroyCoderBoy/PulpEngine/blob/main/docs/api-stability.md.
Preview
11 endpoints
post/render/preview/csv
Preview template CSV with an inline definition (editor use — no DB save required)
Preview template CSV with an inline definition (editor use — no DB save required).
previewCsvapplication/jsonPOST /render/preview/csvpost/render/preview/docx
Preview template DOCX with an inline definition (editor use — no DB save required)
Preview template DOCX with an inline definition (editor use — no DB save required).
previewDocxapplication/jsonPOST /render/preview/docxpost/render/preview/email
Preview email HTML, plain text and inline images
Preview email HTML, plain text and inline images.
previewEmailapplication/jsonPOST /render/preview/emailpost/render/preview/expression
Evaluate an expression with server plugin functions
Evaluate an expression with server plugin functions.
previewExpressionapplication/jsonPOST /render/preview/expressionpost/render/preview/html
Preview template HTML with an inline definition (editor use — no DB save required)
Preview template HTML with an inline definition (editor use — no DB save required).
previewHtml| Name | In | Required | Description |
|---|---|---|---|
| annotate | query |
application/jsonPOST /render/preview/htmlpost/render/preview/image
Preview PDF pages as PNG, JPEG or WebP
Preview PDF pages as PNG, JPEG or WebP.
previewImageapplication/jsonPOST /render/preview/imagepost/render/preview/parameters
Resolve parameters for an unsaved report
Resolve parameters for an unsaved report.
previewParametersapplication/jsonPOST /render/preview/parameterspost/render/preview/pdf
Preview template PDF with an inline definition (editor use — no DB save required)
Preview template PDF with an inline definition (editor use — no DB save required).
previewPdf| Name | In | Required | Description |
|---|---|---|---|
| annotate | query | Include preview-only node destinations for the editor page map. | |
| stream | query | Streaming control. Unset (default) or true → chunked stream. false → force buffered response. Preview has no post-render hooks, so stream=true never errors. |
application/jsonPOST /render/preview/pdfpost/render/preview/pptx
Preview template PPTX with an inline definition (editor use — no DB save required)
Preview template PPTX with an inline definition (editor use — no DB save required).
previewPptxapplication/jsonPOST /render/preview/pptxget/render/preview/status
Preview capability status — cached startup snapshot; always returns 200
Returns whether the preview renderer was available when this process started. This is a startup snapshot, not a perpetual guarantee: if preview is available at startup but a later individual render fails, that travels the normal 422/500 path. Raw browser failure details are kept in server logs only.
getPreviewStatusGET /render/preview/statuspost/render/preview/xlsx
Preview template XLSX with an inline definition (editor use — no DB save required)
Preview template XLSX with an inline definition (editor use — no DB save required).
previewXlsxapplication/jsonPOST /render/preview/xlsxBatch
1 endpoint
post/batch/
Execute multiple GET requests in a single HTTP call
Accepts an array of GET sub-requests targeting template read surfaces (/templates, /templates/:key, /templates/:key/versions, /templates/:key/labels). Returns an array of {status, body} responses. Max 20 items. Auth scope: admin or editor.
submitReadBatchapplication/jsonPOST /batch/PDF Transform
11 endpoints
post/render/pdf/attach
Attach files to a PDF
Attach files to a PDF.
attachPdfFilesapplication/jsonPOST /render/pdf/attachpost/render/pdf/facturx
Embed a Factur-X invoice in a PDF/A-3b document
Embed a Factur-X invoice in a PDF/A-3b document.
createFacturXapplication/jsonPOST /render/pdf/facturxpost/render/pdf/fill
Fill an existing AcroForm and optionally flatten its appearances
Fill an existing AcroForm and optionally flatten its appearances.
fillPdfFormapplication/jsonPOST /render/pdf/fillpost/render/pdf/form-fields
Inspect AcroForm fields and XFA status
Inspect AcroForm fields and XFA status.
listPdfFormFields| Name | In | Required | Description |
|---|---|---|---|
| limit | query | ||
| offset | query |
application/jsonPOST /render/pdf/form-fieldspost/render/pdf/insert
Insert pages into a PDF
Insert all pages from one PDF into another at a specified position.
insertPdfPagesapplication/jsonPOST /render/pdf/insertpost/render/pdf/merge
Merge multiple PDFs into one
Concatenate pages from multiple PDF documents into a single PDF, in the order provided.
mergePdfapplication/jsonPOST /render/pdf/mergepost/render/pdf/process
Apply a pipeline of PDF operations
Apply a pipeline of PDF operations.
processPdfapplication/jsonPOST /render/pdf/processpost/render/pdf/process/upload
Process PDF files with a multipart JSON spec
Multipart fields: spec (JSON using sources[].part), and named PDF files. The spec is validated using the same operation schema as processPdf.
processPdfUploadPOST /render/pdf/process/uploadpost/render/pdf/protect
Encrypt a PDF with AES-256
Encrypt a PDF with AES-256.
protectPdfapplication/jsonPOST /render/pdf/protectpost/render/pdf/sign
Apply a deployment-owned digital seal (admin only)
Apply a deployment-owned digital seal (admin only).
signPdfapplication/jsonPOST /render/pdf/signpost/render/pdf/watermark
Apply a watermark to a PDF
Overlay a text or image watermark on every page (or a page range) of a PDF.
watermarkPdfapplication/jsonPOST /render/pdf/watermarkTemplates
71 endpoints
get/promotion-requests
listPromotionInbox.
listPromotionInbox| Name | In | Required | Description |
|---|---|---|---|
| status | query | ||
| label | query | ||
| version | query | ||
| nodeId | query | ||
| from | query | ||
| to | query | ||
| limit | query | ||
| offset | query |
GET /promotion-requestsget/templates/
List all templates (paginated)
Returns a paginated list of templates. Use ?expand=versions,labels,lastRenders to include nested relations. When expand is present, limit is capped at 100.
listTemplates| Name | In | Required | Description |
|---|---|---|---|
| kind | query | ||
| limit | query | Maximum number of items to return (1-1000, default 50) | |
| offset | query | Number of items to skip | |
| expand | query | Comma-separated list of relations to include: versions, labels, lastRenders, permissions. When present, list limit is capped at 100. | |
| q | query | ||
| key | query | ||
| folderId | query | ||
| folderPath | query | ||
| recursive | query | ||
| tag | query | ||
| owner | query | ||
| label | query | ||
| state | query | ||
| sort | query | ||
| order | query |
GET /templates/post/templates/
Create a new template
Supports optional Idempotency-Key for safe retries. Stored render responses honour it only with output.store=true and output.respondWith=link.
createTemplate| Name | In | Required | Description |
|---|---|---|---|
| folderId | query | ||
| x-pulpengine-change-note | header | Percent-encoded UTF-8 change note; up to 1000 decoded UTF-16 code units and 8 KB encoded. Optional on create. | |
| idempotency-key | header | Retry key, scoped to the current tenant, principal, method and concrete path. Reuse only for the same request. |
application/jsonPOST /templates/delete/templates/{key}
Delete a template (admin; soft-delete needs If-Match, permanent=true requires trash)
Delete a template (admin; soft-delete needs If-Match, permanent=true requires trash).
deleteTemplate| Name | In | Required | Description |
|---|---|---|---|
| permanent | query | ||
| key | path | ✓ | |
| if-match | header | Current version ETag, e.g. "1.0.3" | |
| x-pulpengine-change-note | header | Percent-encoded UTF-8 change note; at most 1000 decoded characters and 8 KB encoded. |
DELETE /templates/{key}get/templates/{key}
Get a template with its current definition
Get a template with its current definition.
getTemplate| Name | In | Required | Description |
|---|---|---|---|
| expand | query | Comma-separated list of relations to include: versions, labels, lastRenders, permissions. When present, list limit is capped at 100. | |
| key | path | ✓ |
GET /templates/{key}put/templates/{key}
Update a template definition (requires If-Match header; auto-bumps version)
Update a template definition (requires If-Match header; auto-bumps version).
updateTemplate| Name | In | Required | Description |
|---|---|---|---|
| key | path | ✓ | |
| if-match | header | Current version ETag, e.g. "1.0.3" | |
| x-pulpengine-change-note | header | Percent-encoded UTF-8 change note; at most 1000 decoded characters and 8 KB encoded. |
application/jsonPUT /templates/{key}get/templates/{key}/bindings
Discover bound paths and the effective input contract
Discover bound paths and the effective input contract.
getTemplateBindings| Name | In | Required | Description |
|---|---|---|---|
| version | query | ||
| label | query | ||
| key | path | ✓ |
GET /templates/{key}/bindingsget/templates/{key}/comments
listTemplateComments.
listTemplateComments| Name | In | Required | Description |
|---|---|---|---|
| status | query | ||
| label | query | ||
| version | query | ||
| nodeId | query | ||
| from | query | ||
| to | query | ||
| limit | query | ||
| offset | query | ||
| key | path | ✓ |
GET /templates/{key}/commentspost/templates/{key}/comments
createTemplateComment.
createTemplateComment| Name | In | Required | Description |
|---|---|---|---|
| key | path | ✓ |
application/jsonPOST /templates/{key}/commentsdelete/templates/{key}/comments/{id}
deleteTemplateComment.
deleteTemplateComment| Name | In | Required | Description |
|---|---|---|---|
| key | path | ✓ | |
| id | path | ✓ |
DELETE /templates/{key}/comments/{id}patch/templates/{key}/comments/{id}
updateTemplateComment.
updateTemplateComment| Name | In | Required | Description |
|---|---|---|---|
| key | path | ✓ | |
| id | path | ✓ |
application/jsonPATCH /templates/{key}/comments/{id}get/templates/{key}/compatibility
Compare payload contracts between revisions
Compare payload contracts between revisions.
compareTemplateContracts| Name | In | Required | Description |
|---|---|---|---|
| base | query | ✓ | |
| candidate | query | ||
| key | path | ✓ |
GET /templates/{key}/compatibilityget/templates/{key}/datasets
List shared sample datasets with current schema validation
List shared sample datasets with current schema validation.
listTemplateDatasets| Name | In | Required | Description |
|---|---|---|---|
| limit | query | Maximum number of items to return (1-1000, default 50) | |
| offset | query | Number of items to skip | |
| tag | query | ||
| key | path | ✓ |
GET /templates/{key}/datasetsdelete/templates/{key}/datasets/{name}
Delete a shared sample dataset (idempotent)
Delete a shared sample dataset (idempotent).
deleteTemplateDataset| Name | In | Required | Description |
|---|---|---|---|
| key | path | ✓ | |
| name | path | ✓ |
DELETE /templates/{key}/datasets/{name}get/templates/{key}/datasets/{name}
Read a shared sample dataset
Read a shared sample dataset.
getTemplateDataset| Name | In | Required | Description |
|---|---|---|---|
| key | path | ✓ | |
| name | path | ✓ |
GET /templates/{key}/datasets/{name}put/templates/{key}/datasets/{name}
Create or update a shared sample dataset
Stores schema-invalid data with validation warnings. Optional If-Match protects revisions; use "0" to create only.
putTemplateDataset| Name | In | Required | Description |
|---|---|---|---|
| key | path | ✓ | |
| name | path | ✓ | |
| if-match | header |
application/jsonPUT /templates/{key}/datasets/{name}get/templates/{key}/dependencies
Inspect transitive template and asset dependencies
Inspect transitive template and asset dependencies.
getTemplateDependencies| Name | In | Required | Description |
|---|---|---|---|
| version | query | ||
| label | query | ||
| key | path | ✓ |
GET /templates/{key}/dependenciesget/templates/{key}/dependents
Find templates that use a shared component
Scans current and labelled versions in this tenant, including reachable version pins. Transitive traversal is bounded to five hops. Truncated scans must not be treated as exhaustive.
listTemplateDependents| Name | In | Required | Description |
|---|---|---|---|
| limit | query | Maximum number of items to return (1-1000, default 50) | |
| offset | query | Number of items to skip | |
| transitive | query | ||
| key | path | ✓ |
GET /templates/{key}/dependentspost/templates/{key}/dependents/validate
Validate children against a saved or draft layout
Validate children against a saved or draft layout.
validateTemplateDependents| Name | In | Required | Description |
|---|---|---|---|
| key | path | ✓ |
application/jsonPOST /templates/{key}/dependents/validatepost/templates/{key}/diff
Diff two stored versions of a template
Computes a structural diff between two stored versions of the same template key. Returns the raw TemplateDiff JSON from @pulp-engine/template-diff — metadata, renderConfig, inputSchema, fieldMapping, document-root, and document-tree changes plus aggregate counts. v1 scope: both versions must exist in the resolved tenant.
diffTemplateVersions| Name | In | Required | Description |
|---|---|---|---|
| key | path | ✓ |
application/jsonPOST /templates/{key}/diffdelete/templates/{key}/draft
Delete your draft
Requires a named actor. Draft writes are last-write-wins and do not advance HEAD or labels.
deleteTemplateDraft| Name | In | Required | Description |
|---|---|---|---|
| key | path | ✓ |
DELETE /templates/{key}/draftget/templates/{key}/draft
Read your draft
Requires a named actor. Draft writes are last-write-wins and do not advance HEAD or labels.
getTemplateDraft| Name | In | Required | Description |
|---|---|---|---|
| key | path | ✓ |
GET /templates/{key}/draftput/templates/{key}/draft
Save your draft without publishing
Requires a named actor. Draft writes are last-write-wins and do not advance HEAD or labels.
putTemplateDraft| Name | In | Required | Description |
|---|---|---|---|
| key | path | ✓ |
application/jsonPUT /templates/{key}/draftget/templates/{key}/drafts
List teammates’ draft summaries
Read-only draft summaries, scoped to the resolved tenant and template.
listTemplateDrafts| Name | In | Required | Description |
|---|---|---|---|
| limit | query | Maximum number of items to return (1-1000, default 50) | |
| offset | query | Number of items to skip | |
| key | path | ✓ |
GET /templates/{key}/draftsget/templates/{key}/drafts/{owner}
Read a teammate’s draft
Read-only review; this operation cannot modify the teammate’s draft.
getTemplateDraftForReview| Name | In | Required | Description |
|---|---|---|---|
| key | path | ✓ | |
| owner | path | ✓ |
GET /templates/{key}/drafts/{owner}get/templates/{key}/effective
Get the template after applying its master layout
Get the template after applying its master layout.
getEffectiveTemplate| Name | In | Required | Description |
|---|---|---|---|
| version | query | ||
| label | query | ||
| key | path | ✓ |
GET /templates/{key}/effectiveget/templates/{key}/form-metadata
Get form-rendering metadata for a template
Returns { key, version, title?, description?, inputSchema, hasFieldMappings } for the given template. Used by the <pulp-engine-form> embed to auto-generate a fillable form. hasFieldMappings=true signals that the template transforms raw input via fieldMappings; the v1 form refuses to render such templates because inputSchema describes the POST-MAPPING shape, not the submission shape.
getTemplateFormMetadata| Name | In | Required | Description |
|---|---|---|---|
| version | query | Exact version to pin; mutually exclusive with label | |
| label | query | Label name to resolve; mutually exclusive with version | |
| key | path | ✓ |
GET /templates/{key}/form-metadataget/templates/{key}/i18n
getTemplateI18n.
getTemplateI18n| Name | In | Required | Description |
|---|---|---|---|
| format | query | ||
| languages | query | ||
| key | path | ✓ |
GET /templates/{key}/i18nput/templates/{key}/i18n
putTemplateI18n.
putTemplateI18n| Name | In | Required | Description |
|---|---|---|---|
| key | path | ✓ |
application/jsonPUT /templates/{key}/i18nget/templates/{key}/labels
List all labels on a template
Returns every named label pointer and the version it resolves to. Dual-scoped: admin or editor.
listTemplateLabels| Name | In | Required | Description |
|---|---|---|---|
| key | path | ✓ |
GET /templates/{key}/labelsdelete/templates/{key}/labels/{label}
Delete a label (admin-only)
Removes the label pointer. Idempotent — succeeds silently on unknown labels as long as the template exists. Admin scope required.
deleteTemplateLabel| Name | In | Required | Description |
|---|---|---|---|
| force | query | Allow deletion even when a component reference pins this label. | |
| key | path | ✓ | |
| label | path | ✓ |
DELETE /templates/{key}/labels/{label}get/templates/{key}/labels/{label}
Get the template definition at a labeled version
Resolves the label to its target version and returns the full template definition. Dual-scoped: admin or editor.
getTemplateAtLabel| Name | In | Required | Description |
|---|---|---|---|
| asOf | query | ||
| key | path | ✓ | |
| label | path | ✓ |
GET /templates/{key}/labels/{label}put/templates/{key}/labels/{label}
Create or re-point a label (admin-only)
Creates the label if it does not exist, or re-points it if it does. The target version must be a saved version. Supports optimistic concurrency via the If-Match header: when present, the label's current version must match the supplied string or the request fails with 412 Precondition Failed. When absent, the label is upserted unconditionally (for automated promotion flows that trust their own serialization). Admin scope required.
setTemplateLabel| Name | In | Required | Description |
|---|---|---|---|
| requireCompatible | query | ||
| key | path | ✓ | |
| label | path | ✓ |
application/jsonPUT /templates/{key}/labels/{label}get/templates/{key}/labels/{label}/history
listTemplateLabelHistory.
listTemplateLabelHistory| Name | In | Required | Description |
|---|---|---|---|
| status | query | ||
| label | query | ||
| version | query | ||
| nodeId | query | ||
| from | query | ||
| to | query | ||
| limit | query | ||
| offset | query | ||
| key | path | ✓ | |
| label | path | ✓ |
GET /templates/{key}/labels/{label}/historypost/templates/{key}/labels/{label}/schedule
scheduleTemplateLabel.
scheduleTemplateLabel| Name | In | Required | Description |
|---|---|---|---|
| key | path | ✓ | |
| label | path | ✓ |
application/jsonPOST /templates/{key}/labels/{label}/scheduledelete/templates/{key}/labels/{label}/schedule/{eventId}
cancelTemplateLabelSchedule.
cancelTemplateLabelSchedule| Name | In | Required | Description |
|---|---|---|---|
| key | path | ✓ | |
| label | path | ✓ | |
| eventId | path | ✓ |
DELETE /templates/{key}/labels/{label}/schedule/{eventId}delete/templates/{key}/lock
Release own lock or force release as admin
Release own lock or force release as admin.
releaseTemplateLock| Name | In | Required | Description |
|---|---|---|---|
| sessionId | query | ||
| force | query | ||
| key | path | ✓ |
DELETE /templates/{key}/lockput/templates/{key}/lock
Acquire an advisory editing lock
Acquire an advisory editing lock.
acquireTemplateLock| Name | In | Required | Description |
|---|---|---|---|
| key | path | ✓ |
application/jsonPUT /templates/{key}/lockpatch/templates/{key}/meta
Update folder, tags and owner without creating a version
Update folder, tags and owner without creating a version.
updateTemplateMeta| Name | In | Required | Description |
|---|---|---|---|
| key | path | ✓ |
application/jsonPATCH /templates/{key}/metaput/templates/{key}/office
Replace an Office template source and save a version
Replace an Office template source and save a version.
replaceOfficeTemplateSource| Name | In | Required | Description |
|---|---|---|---|
| key | path | ✓ | |
| if-match | header | Current version ETag, e.g. "1.0.3" | |
| x-pulpengine-change-note | header | Percent-encoded UTF-8 change note; at most 1000 decoded characters and 8 KB encoded. |
multipart/form-dataPUT /templates/{key}/officeget/templates/{key}/office/source
Download the original private Office template source
Download the original private Office template source.
downloadOfficeTemplateSource| Name | In | Required | Description |
|---|---|---|---|
| version | query | ||
| key | path | ✓ |
GET /templates/{key}/office/sourceget/templates/{key}/office/tags
Inspect an Office template tag contract
Inspect an Office template tag contract.
getOfficeTemplateTags| Name | In | Required | Description |
|---|---|---|---|
| version | query | ||
| key | path | ✓ |
GET /templates/{key}/office/tagspost/templates/{key}/parameters/resolve
Resolve report parameter defaults and choices
Resolve report parameter defaults and choices.
resolveTemplateParameters| Name | In | Required | Description |
|---|---|---|---|
| key | path | ✓ |
application/jsonPOST /templates/{key}/parameters/resolveget/templates/{key}/presence
List active editors and advisory lock
List active editors and advisory lock.
getTemplatePresence| Name | In | Required | Description |
|---|---|---|---|
| key | path | ✓ |
GET /templates/{key}/presenceput/templates/{key}/presence
Refresh editor presence and renew its advisory lock
Refresh editor presence and renew its advisory lock.
heartbeatTemplatePresence| Name | In | Required | Description |
|---|---|---|---|
| key | path | ✓ |
application/jsonPUT /templates/{key}/presencedelete/templates/{key}/presence/{sessionId}
Leave presence and release this session lock
Leave presence and release this session lock.
leaveTemplatePresence| Name | In | Required | Description |
|---|---|---|---|
| key | path | ✓ | |
| sessionId | path | ✓ |
DELETE /templates/{key}/presence/{sessionId}get/templates/{key}/promotion-requests
listPromotionRequests.
listPromotionRequests| Name | In | Required | Description |
|---|---|---|---|
| status | query | ||
| label | query | ||
| version | query | ||
| nodeId | query | ||
| from | query | ||
| to | query | ||
| limit | query | ||
| offset | query | ||
| key | path | ✓ |
GET /templates/{key}/promotion-requestspost/templates/{key}/promotion-requests
createPromotionRequest.
createPromotionRequest| Name | In | Required | Description |
|---|---|---|---|
| key | path | ✓ |
application/jsonPOST /templates/{key}/promotion-requestspost/templates/{key}/promotion-requests/{id}/approve
approvePromotionRequest.
approvePromotionRequest| Name | In | Required | Description |
|---|---|---|---|
| key | path | ✓ | |
| id | path | ✓ |
application/jsonPOST /templates/{key}/promotion-requests/{id}/approvepost/templates/{key}/promotion-requests/{id}/cancel
cancelPromotionRequest.
cancelPromotionRequest| Name | In | Required | Description |
|---|---|---|---|
| key | path | ✓ | |
| id | path | ✓ |
application/jsonPOST /templates/{key}/promotion-requests/{id}/cancelpost/templates/{key}/promotion-requests/{id}/reject
rejectPromotionRequest.
rejectPromotionRequest| Name | In | Required | Description |
|---|---|---|---|
| key | path | ✓ | |
| id | path | ✓ |
application/jsonPOST /templates/{key}/promotion-requests/{id}/rejectdelete/templates/{key}/sample
Delete stored sample data for a template version
Admin-only. Idempotent — returns 204 whether or not a row existed. Use ?version= to target a specific version; defaults to the current version. Subsequent GET falls through to SampleService.
deleteTemplateSample| Name | In | Required | Description |
|---|---|---|---|
| version | query | Target template version. Defaults to currentVersion. | |
| key | path | ✓ |
DELETE /templates/{key}/sampleget/templates/{key}/sample
Get sample preview data for a template
Returns stored sample data when present and still valid against the template's inputSchema; otherwise tries the valid default dataset, then synthesises a payload via SampleService. Use ?version= to target a specific historical version; defaults to the current version. The source is reported in the X-Sample-Source response header.
getTemplateSample| Name | In | Required | Description |
|---|---|---|---|
| version | query | ||
| label | query | ||
| key | path | ✓ |
GET /templates/{key}/sampleput/templates/{key}/sample
Persist sample preview data against the template's current version
Last-write-wins: no If-Match, no ETag response header. The payload is AJV-validated against the current inputSchema before persist; invalid payloads are rejected with 422 and no row is written. Audit: emits a `template_mutation` event with operation `set_sample`.
putTemplateSample| Name | In | Required | Description |
|---|---|---|---|
| key | path | ✓ |
application/jsonPUT /templates/{key}/sampleget/templates/{key}/schema
Get the JSON Schema input definition for a template
Get the JSON Schema input definition for a template.
getTemplateSchema| Name | In | Required | Description |
|---|---|---|---|
| version | query | ||
| label | query | ||
| key | path | ✓ |
GET /templates/{key}/schemapost/templates/{key}/tests/run
Run stored dataset content checks against a saved or unsaved template
Returns checks and counts only. Negative and schema-stale datasets are skipped. Does not block server-side label promotion.
runTemplateTests| Name | In | Required | Description |
|---|---|---|---|
| key | path | ✓ |
application/jsonPOST /templates/{key}/tests/runget/templates/{key}/theme
Get a brand kit at its current, labelled or pinned version
Get a brand kit at its current, labelled or pinned version.
getTemplateTheme| Name | In | Required | Description |
|---|---|---|---|
| label | query | ||
| version | query | ||
| key | path | ✓ |
GET /templates/{key}/themeget/templates/{key}/thumbnail
Render a private, cached first-page template thumbnail
Render a private, cached first-page template thumbnail.
getTemplateThumbnail| Name | In | Required | Description |
|---|---|---|---|
| version | query | ||
| width | query | ||
| format | query | ||
| key | path | ✓ |
GET /templates/{key}/thumbnailpost/templates/{key}/undelete
Restore a template from trash (admin only)
Restore a template from trash (admin only).
undeleteTemplate| Name | In | Required | Description |
|---|---|---|---|
| key | path | ✓ |
POST /templates/{key}/undeletepost/templates/{key}/validate
Validate a data payload against a template's input schema
Validates arbitrary input data against the stored template's JSON Schema. Applies field mappings (data adapter) before validation. Use this to pre-check data payloads before calling the render endpoint. This does NOT validate the template structure itself — use POST /render/validate for that.
validateTemplateData| Name | In | Required | Description |
|---|---|---|---|
| version | query | ||
| label | query | ||
| key | path | ✓ |
application/jsonPOST /templates/{key}/validateget/templates/{key}/versions
List all saved versions for a template (newest first, paginated)
List all saved versions for a template (newest first, paginated).
listTemplateVersions| Name | In | Required | Description |
|---|---|---|---|
| limit | query | Maximum number of items to return (1-1000, default 50) | |
| offset | query | Number of items to skip | |
| key | path | ✓ |
GET /templates/{key}/versionsget/templates/{key}/versions/{version}
Get a template's definition at a specific version
Get a template's definition at a specific version.
getTemplateVersion| Name | In | Required | Description |
|---|---|---|---|
| key | path | ✓ | |
| version | path | ✓ |
GET /templates/{key}/versions/{version}patch/templates/{key}/versions/{version}
Amend a version change note
Admin or the version author may amend its note without changing the version.
setTemplateVersionNote| Name | In | Required | Description |
|---|---|---|---|
| key | path | ✓ | |
| version | path | ✓ |
application/jsonPATCH /templates/{key}/versions/{version}post/templates/{key}/versions/{version}/restore
Promote a historical version to current (admin only; requires If-Match header)
Supports optional Idempotency-Key for safe retries. Stored render responses honour it only with output.store=true and output.respondWith=link.
restoreTemplateVersion| Name | In | Required | Description |
|---|---|---|---|
| key | path | ✓ | |
| version | path | ✓ | |
| if-match | header | Current version ETag, e.g. "1.0.3" | |
| x-pulpengine-change-note | header | Percent-encoded UTF-8 change note; at most 1000 decoded characters and 8 KB encoded. | |
| idempotency-key | header | Retry key, scoped to the current tenant, principal, method and concrete path. Reuse only for the same request. |
POST /templates/{key}/versions/{version}/restorepost/templates/edit
Propose validated edits to an unsaved template
Propose validated edits to an unsaved template.
editTemplateWithAiapplication/jsonPOST /templates/editpost/templates/generate
Generate a draft template from a natural-language prompt (AI)
Schema-constrained Claude tool-use call. Returns an unsaved draft TemplateDefinition validated by the same Zod schema as hand-authored saves. The caller must POST /templates to persist. Per-actor rate limited (default 5/min). Returns 503 when ANTHROPIC_API_KEY is unset. 502 is returned for any upstream failure (network, malformed tool use, or validation exhausted after repair attempts) — query the audit log (event=template_generation) for specifics. Supports optional Idempotency-Key for safe retries. Stored render responses honour it only with output.store=true and output.respondWith=link.
generateTemplate| Name | In | Required | Description |
|---|---|---|---|
| idempotency-key | header | Retry key, scoped to the current tenant, principal, method and concrete path. Reuse only for the same request. |
application/jsonPOST /templates/generatepost/templates/generate-sample
Generate schema-valid named sample scenarios
Generate schema-valid named sample scenarios.
generateSampleWithAiapplication/jsonPOST /templates/generate-samplepost/templates/import
Import a document as an unsaved editable draft
Import a document as an unsaved editable draft. HTML and DOCX support deterministic conversion without AI. PDF and raster images require AI_TEMPLATE_IMPORT_ENABLED and an Anthropic key. Draft templates are never saved by this operation.
importTemplateapplication/json, multipart/form-dataPOST /templates/importpost/templates/infer-schema
Infer a Draft-07 input schema from a sample
Infer a Draft-07 input schema from a sample.
inferTemplateSchemaapplication/jsonPOST /templates/infer-schemapost/templates/office
Create an Office template from an authored file
Create an Office template from an authored file.
createOfficeTemplatemultipart/form-dataPOST /templates/officepost/templates/office/lint
Lint an Office-authored file without saving it
Lint an Office-authored file without saving it.
lintOfficeTemplatemultipart/form-dataPOST /templates/office/lintAssets
11 endpoints
get/assets/
List uploaded assets, optionally filtered by name (?q=), MIME type (?mimeType=), or legacy SVG signals (?legacySvg=true)
List uploaded assets, optionally filtered by name (?q=), MIME type (?mimeType=), or legacy SVG signals (?legacySvg=true).
listAssets| Name | In | Required | Description |
|---|---|---|---|
| q | query | Case-insensitive substring filter on originalName | |
| kind | query | ||
| mimeType | query | Exact MIME type filter (e.g. image/png). Case-insensitive. | |
| tag | query | ||
| folder | query | ||
| recursive | query | ||
| sort | query | ||
| order | query | ||
| include | query | ||
| legacySvg | query | Return assets matching legacy SVG detection signals: declared mimeType of image/svg+xml OR filename ending with .svg. Use this to enumerate assets that may have been uploaded before v0.27.0 SVG rejection was enforced. | |
| limit | query | Maximum number of items to return (1-1000, default 50) | |
| offset | query | Number of items to skip |
GET /assets/delete/assets/{id}
Delete an asset; referenced assets require force=true
Delete an asset; referenced assets require force=true.
deleteAsset| Name | In | Required | Description |
|---|---|---|---|
| force | query | ||
| id | path | ✓ |
DELETE /assets/{id}patch/assets/{id}
Update asset metadata
Update asset metadata.
updateAsset| Name | In | Required | Description |
|---|---|---|---|
| force | query | ||
| id | path | ✓ |
application/jsonPATCH /assets/{id}put/assets/{id}/content
Replace asset bytes while keeping its URL and MIME type
Replace asset bytes while keeping its URL and MIME type.
replaceAssetContent| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ | |
| if-match | header | Current version ETag, e.g. "1.0.3" | |
| x-pulpengine-change-note | header | Percent-encoded UTF-8 change note; at most 1000 decoded characters and 8 KB encoded. |
PUT /assets/{id}/contentget/assets/{id}/details
Get an asset and its template references
Get an asset and its template references.
getAssetDetails| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
GET /assets/{id}/detailsget/assets/{id}/font-info
Read uploaded font metadata
Read uploaded font metadata.
getAssetFontInfo| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
GET /assets/{id}/font-infoget/assets/{id}/form-fields
Inspect the fields of an uploaded PDF form
Inspect the fields of an uploaded PDF form.
getAssetFormFields| Name | In | Required | Description |
|---|---|---|---|
| limit | query | ||
| offset | query | ||
| id | path | ✓ |
GET /assets/{id}/form-fieldsget/assets/{id}/versions
List retained asset versions
List retained asset versions.
listAssetVersions| Name | In | Required | Description |
|---|---|---|---|
| limit | query | Maximum number of items to return (1-1000, default 50) | |
| offset | query | Number of items to skip | |
| id | path | ✓ |
GET /assets/{id}/versionspost/assets/{id}/versions/{version}/restore
Restore retained bytes as a new asset version
Restore retained bytes as a new asset version.
restoreAssetVersion| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ | |
| version | path | ✓ |
POST /assets/{id}/versions/{version}/restoreget/assets/facets
List asset folders and tags
List asset folders and tags.
getAssetFacetsGET /assets/facetspost/assets/upload
Upload an image, PDF or font asset (multipart/form-data, max 10 MB)
Supports optional Idempotency-Key for safe retries. Stored render responses honour it only with output.store=true and output.respondWith=link.
uploadAsset| Name | In | Required | Description |
|---|---|---|---|
| idempotency-key | header | Retry key, scoped to the current tenant, principal, method and concrete path. Reuse only for the same request. |
POST /assets/uploadSchedules
25 endpoints
get/schedules/
List schedules
Returns a paginated list of schedule definitions. Admin scope required.
listSchedules| Name | In | Required | Description |
|---|---|---|---|
| limit | query | Maximum number of items to return (1-1000, default 50) | |
| offset | query | Number of items to skip | |
| enabled | query | Filter by enabled status (true/false) | |
| templateKey | query | ||
| templateLabel | query |
GET /schedules/post/schedules/
Create a schedule
Creates a new schedule definition. Computes and stores the next fire time from the cron expression. Admin scope required. Supports optional Idempotency-Key for safe retries. Stored render responses honour it only with output.store=true and output.respondWith=link.
createSchedule| Name | In | Required | Description |
|---|---|---|---|
| idempotency-key | header | Retry key, scoped to the current tenant, principal, method and concrete path. Reuse only for the same request. |
application/jsonPOST /schedules/delete/schedules/{id}
Delete schedule
Deletes a schedule and all its execution history. Admin scope required.
deleteSchedule| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
DELETE /schedules/{id}get/schedules/{id}
Get schedule by ID
Returns a single schedule definition with secrets masked. Admin scope required.
getSchedule| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
GET /schedules/{id}patch/schedules/{id}
Partially update schedule
Updates specified fields only. JSON fields (dataSource, deliveryTargets) are full-replaced, not deep-merged. Recomputes next fire time if cron or enabled changes. Admin scope required.
updateSchedule| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
application/jsonPATCH /schedules/{id}put/schedules/{id}
Update schedule (full replace)
Replaces the entire schedule definition. Recomputes next fire time. Admin scope required.
replaceSchedule| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
application/jsonPUT /schedules/{id}post/schedules/{id}/duplicate
Duplicate a schedule while preserving its secrets
Duplicate a schedule while preserving its secrets.
duplicateSchedule| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
application/jsonPOST /schedules/{id}/duplicateget/schedules/{id}/executions
List execution history
Returns a paginated list of executions for a schedule. Admin scope required.
listScheduleExecutions| Name | In | Required | Description |
|---|---|---|---|
| limit | query | Maximum number of items to return (1-1000, default 50) | |
| offset | query | Number of items to skip | |
| status | query | Filter by execution status | |
| id | path | ✓ |
GET /schedules/{id}/executionsget/schedules/{id}/executions/{execId}
Get execution detail
Returns a single execution record. Admin scope required.
getScheduleExecution| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ | |
| execId | path | ✓ |
GET /schedules/{id}/executions/{execId}get/schedules/{id}/executions/{execId}/items
listScheduleExecutionItems.
listScheduleExecutionItems| Name | In | Required | Description |
|---|---|---|---|
| limit | query | Maximum number of items to return (1-1000, default 50) | |
| offset | query | Number of items to skip | |
| status | query | ||
| id | path | ✓ | |
| execId | path | ✓ |
GET /schedules/{id}/executions/{execId}/itemsget/schedules/{id}/preview
previewScheduleFires.
previewScheduleFires| Name | In | Required | Description |
|---|---|---|---|
| count | query | ||
| id | path | ✓ |
GET /schedules/{id}/previewpost/schedules/{id}/test
Send a saved schedule to test recipients
Send a saved schedule to test recipients.
testSchedule| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
application/jsonPOST /schedules/{id}/testpost/schedules/{id}/trigger
Manually trigger schedule
Creates an immediate execution for the schedule. Rate-limited. Admin scope required. Supports optional Idempotency-Key for safe retries. Stored render responses honour it only with output.store=true and output.respondWith=link.
triggerSchedule| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ | |
| idempotency-key | header | Retry key, scoped to the current tenant, principal, method and concrete path. Reuse only for the same request. |
application/jsonPOST /schedules/{id}/triggerpost/schedules/burst/preview
previewScheduleBurst.
previewScheduleBurstapplication/jsonPOST /schedules/burst/previewget/schedules/calendars
listScheduleCalendars.
listScheduleCalendars| Name | In | Required | Description |
|---|---|---|---|
| limit | query | Maximum number of items to return (1-1000, default 50) | |
| offset | query | Number of items to skip |
GET /schedules/calendarspost/schedules/calendars
createScheduleCalendar.
createScheduleCalendarapplication/jsonPOST /schedules/calendarsdelete/schedules/calendars/{id}
deleteScheduleCalendar.
deleteScheduleCalendar| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
DELETE /schedules/calendars/{id}get/schedules/calendars/{id}
getScheduleCalendar.
getScheduleCalendar| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
GET /schedules/calendars/{id}patch/schedules/calendars/{id}
updateScheduleCalendar.
updateScheduleCalendar| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
application/jsonPATCH /schedules/calendars/{id}put/schedules/calendars/{id}
replaceScheduleCalendar.
replaceScheduleCalendar| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
application/jsonPUT /schedules/calendars/{id}post/schedules/calendars/{id}/import
importScheduleCalendarIcal.
importScheduleCalendarIcal| Name | In | Required | Description |
|---|---|---|---|
| mode | query | ||
| id | path | ✓ |
text/calendarPOST /schedules/calendars/{id}/importpost/schedules/cron-preview
Preview upcoming schedule fires
Preview upcoming schedule fires.
previewScheduleCronapplication/jsonPOST /schedules/cron-previewpost/schedules/data-source/test
Test a schedule data source
Test a schedule data source.
testScheduleDataSourceapplication/jsonPOST /schedules/data-source/testpost/schedules/preview
previewScheduleTiming.
previewScheduleTimingapplication/jsonPOST /schedules/previewget/schedules/recent-failures
List recent failed scheduled runs
List recent failed scheduled runs.
listRecentScheduleFailures| Name | In | Required | Description |
|---|---|---|---|
| limit | query | Maximum number of items to return (1-1000, default 50) | |
| offset | query | Number of items to skip | |
| sinceHours | query |
GET /schedules/recent-failuresAuth
10 endpoints
post/auth/console-session
Exchange an admin API key for a restricted console session
Exchange an admin API key for a restricted console session.
createConsoleSessionapplication/jsonPOST /auth/console-sessionpost/auth/editor-token
Exchange an API key for a short-lived editor session token (8 hours)
Exchange an API key for a short-lived editor session token (8 hours).
createEditorTokenapplication/jsonPOST /auth/editor-tokenget/auth/oidc/callback
OIDC authorization code callback
OIDC authorization code callback. Available only when OIDC is configured.
oidcCallback| Name | In | Required | Description |
|---|---|---|---|
| code | query | ||
| state | query | ||
| error | query | ||
| error_description | query |
GET /auth/oidc/callbackpost/auth/oidc/complete
Exchange a single-use OIDC completion code for a Pulp Engine editor token
Exchange a single-use OIDC completion code for a Pulp Engine editor token. Available only when OIDC is configured.
oidcCompleteapplication/jsonPOST /auth/oidc/completepost/auth/oidc/exchange
Exchange an OIDC id_token for a Pulp Engine editor session token (embed mode)
Exchange an OIDC id_token for a Pulp Engine editor session token (embed mode). Available only when OIDC is configured.
oidcExchangeapplication/jsonPOST /auth/oidc/exchangeget/auth/oidc/login
Redirect to OIDC provider for SSO login
Redirect to OIDC provider for SSO login. Available only when OIDC is configured.
oidcLogin| Name | In | Required | Description |
|---|---|---|---|
| return_url | query | ||
| prompt | query |
GET /auth/oidc/loginget/auth/oidc/logout
OIDC RP-initiated logout
OIDC RP-initiated logout. Available only when OIDC is configured.
oidcLogoutGET /auth/oidc/logoutget/auth/status
Check whether authentication is required and if editor login is available
Check whether authentication is required and if editor login is available.
getAuthStatus| Name | In | Required | Description |
|---|---|---|---|
| tenant | query | ||
| query |
GET /auth/statuspost/render-tokens/
Mint a scoped browser render token
Mint a scoped browser render token.
createRenderTokenapplication/jsonPOST /render-tokens/delete/render-tokens/{tokenId}
Revoke a browser render token
Revoke a browser render token.
revokeRenderToken| Name | In | Required | Description |
|---|---|---|---|
| tokenId | path | ✓ |
DELETE /render-tokens/{tokenId}Admin
36 endpoints
get/admin/api-keys/
List tenant API keys without secrets
List tenant API keys without secrets.
listApiKeys| Name | In | Required | Description |
|---|---|---|---|
| limit | query | ||
| offset | query | ||
| status | query | ||
| scope | query | ||
| mode | query | ||
| q | query |
GET /admin/api-keys/post/admin/api-keys/
Create an API key and reveal its secret once
Create an API key and reveal its secret once.
createApiKeyapplication/jsonPOST /admin/api-keys/get/admin/api-keys/{id}
Get API key metadata
Get API key metadata.
getApiKey| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
GET /admin/api-keys/{id}patch/admin/api-keys/{id}
Update API key metadata, expiry and restrictions
Update API key metadata, expiry and restrictions.
updateApiKey| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
application/jsonPATCH /admin/api-keys/{id}post/admin/api-keys/{id}/revoke
Revoke an API key
Revoke an API key.
revokeApiKey| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
POST /admin/api-keys/{id}/revokepost/admin/api-keys/{id}/rotate
Rotate an API key with bounded overlap
Rotate an API key with bounded overlap.
rotateApiKey| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
application/jsonPOST /admin/api-keys/{id}/rotateget/admin/batch-dlq/
List batch webhook DLQ entries
Returns a paginated list of dead-lettered batch webhook delivery attempts. Each entry includes a `replayable` flag: on postgres deployments this is a three-part check (the durable batch-job row exists + the result blob is present + the DLQ entry is still `pending`). On file/sqlserver deployments it falls back to the pre-T3 in-memory check. Admin scope required. Returns 503 in file mode (requires STORAGE_MODE=postgres or sqlserver for the DLQ store).
listBatchDlq| Name | In | Required | Description |
|---|---|---|---|
| limit | query | Maximum number of items to return (1-1000, default 50) | |
| offset | query | Number of items to skip | |
| status | query | Filter by status: pending | replayed | abandoned | |
| jobId | query | Filter by batch job id |
GET /admin/batch-dlq/get/admin/batch-dlq/{id}
Get a batch webhook DLQ entry
Get a batch webhook DLQ entry.
getBatchDlqEntry| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
GET /admin/batch-dlq/{id}post/admin/batch-dlq/{id}/abandon
Mark a batch webhook DLQ entry as abandoned
Marks a DLQ entry as terminal (abandoned). Does not require active tenant (terminal cleanup). Admin scope required.
abandonBatchDlqEntry| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
POST /admin/batch-dlq/{id}/abandonpost/admin/batch-dlq/{id}/replay
Replay a dead-lettered batch webhook delivery
Re-delivers the batch job webhook. On postgres deployments reads the webhook URL, secret, and result payload from the durable batch-job + blob stores, so replay survives API restart. On file/sqlserver deployments falls back to the in-memory job store. Returns 409 `job_expired` if the job has been purged, 409 `job_not_completed` if the job is still running, 409 `already_terminal` if already replayed/abandoned.
replayBatchDlqEntry| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
POST /admin/batch-dlq/{id}/replayget/admin/ingest/sources
List tenant-bound queue and folder intake sources
List tenant-bound queue and folder intake sources.
listIngestSources| Name | In | Required | Description |
|---|---|---|---|
| limit | query | Maximum number of items to return (1-1000, default 50) | |
| offset | query | Number of items to skip |
GET /admin/ingest/sourcespost/admin/ingest/sources/{id}/pause
Pause an intake source
Pause an intake source.
pauseIngestSource| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
POST /admin/ingest/sources/{id}/pausepost/admin/ingest/sources/{id}/resume
Resume an intake source
Resume an intake source.
resumeIngestSource| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
POST /admin/ingest/sources/{id}/resumeget/admin/schedule-dlq/
List schedule delivery DLQ entries
Returns a paginated list of dead-lettered delivery attempts. Response includes references only — the raw target config is never echoed back. Admin scope required. Returns 503 when the DLQ store is not available (file mode — requires STORAGE_MODE=postgres or sqlserver).
listScheduleDlq| Name | In | Required | Description |
|---|---|---|---|
| limit | query | Maximum number of items to return (1-1000, default 50) | |
| offset | query | Number of items to skip | |
| status | query | Filter by status: pending | replayed | abandoned | orphaned | |
| scheduleId | query | Filter by schedule id |
GET /admin/schedule-dlq/get/admin/schedule-dlq/{id}
Get a schedule delivery DLQ entry
Get a schedule delivery DLQ entry.
getScheduleDlqEntry| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
GET /admin/schedule-dlq/{id}post/admin/schedule-dlq/{id}/abandon
Mark a DLQ entry as abandoned
Marks a DLQ entry as terminal (abandoned). Use when an operator has determined the delivery cannot or should not be replayed. Admin scope required.
abandonScheduleDlqEntry| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
POST /admin/schedule-dlq/{id}/abandonpost/admin/schedule-dlq/{id}/replay
Replay a dead-lettered delivery
Re-dispatches a single failed delivery target. Rehydrates the current target config from the live schedule — an operator fix to the schedule (e.g. correcting a webhook URL) is picked up automatically. Returns 409 with a specific `code` when the replay cannot proceed: schedule_gone, schedule_mutated, render_artifact_expired, dispatcher_unavailable, already_terminal.
replayScheduleDlqEntry| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
POST /admin/schedule-dlq/{id}/replayget/admin/system
Admin system and available console surfaces
Admin system and available console surfaces.
getAdminSystemGET /admin/systemget/admin/tenants/
List tenants (super-admin only)
List tenants (super-admin only). Available only when MULTI_TENANT_ENABLED is configured.
listTenants| Name | In | Required | Description |
|---|---|---|---|
| limit | query | Maximum number of items to return (1-1000, default 50) | |
| offset | query | Number of items to skip |
GET /admin/tenants/post/admin/tenants/
Create a tenant (super-admin only)
Creates a new tenant row. Requires a super-admin credential (API_KEY_SUPER_ADMIN or an API_KEYS_JSON entry with tenantId: null). Tenant-bound admin credentials are rejected with 403 super_admin_only. Available only when MULTI_TENANT_ENABLED is configured.
createTenantapplication/jsonPOST /admin/tenants/delete/admin/tenants/{id}
Permanently purge an archived tenant
Permanently purge an archived tenant. Available only when MULTI_TENANT_ENABLED is configured.
purgeTenant| Name | In | Required | Description |
|---|---|---|---|
| purge | query | ||
| confirm | query | ||
| retainAudit | query | ||
| retainUsage | query | ||
| id | path | ✓ |
DELETE /admin/tenants/{id}get/admin/tenants/{id}
Get a tenant by id (super-admin only)
Get a tenant by id (super-admin only). Available only when MULTI_TENANT_ENABLED is configured.
getTenant| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ | Tenant slug |
GET /admin/tenants/{id}patch/admin/tenants/{id}
Update a tenant (super-admin only)
Update a tenant (super-admin only). Available only when MULTI_TENANT_ENABLED is configured.
updateTenant| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ | Tenant slug |
application/jsonPATCH /admin/tenants/{id}post/admin/tenants/{id}/archive
Soft-archive a tenant (super-admin only). Reads still work; writes fail with 409 tenant_archived.
Soft-archive a tenant (super-admin only). Reads still work; writes fail with 409 tenant_archived.. Available only when MULTI_TENANT_ENABLED is configured.
archiveTenant| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ | Tenant slug |
POST /admin/tenants/{id}/archivepost/admin/tenants/{id}/clone
Clone a tenant with disabled schedules
Clone a tenant with disabled schedules. Available only when MULTI_TENANT_ENABLED is configured.
cloneTenant| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
application/jsonPOST /admin/tenants/{id}/cloneget/admin/tenants/{id}/export
Export a portable tenant ZIP bundle
Export a portable tenant ZIP bundle. Available only when MULTI_TENANT_ENABLED is configured.
exportTenant| Name | In | Required | Description |
|---|---|---|---|
| include | query | ||
| auditSince | query | ||
| id | path | ✓ |
GET /admin/tenants/{id}/exportget/admin/tenants/{id}/operations
List tenant lifecycle operations
List tenant lifecycle operations. Available only when MULTI_TENANT_ENABLED is configured.
listTenantOperations| Name | In | Required | Description |
|---|---|---|---|
| limit | query | Maximum number of items to return (1-1000, default 50) | |
| offset | query | Number of items to skip | |
| id | path | ✓ |
GET /admin/tenants/{id}/operationsget/admin/tenants/{id}/operations/{opId}
Get tenant lifecycle operation
Get tenant lifecycle operation. Available only when MULTI_TENANT_ENABLED is configured.
getTenantOperation| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ | |
| opId | path | ✓ |
GET /admin/tenants/{id}/operations/{opId}get/admin/tenants/{id}/purge-preview
Preview tenant erasure
Preview tenant erasure. Available only when MULTI_TENANT_ENABLED is configured.
previewTenantPurge| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
GET /admin/tenants/{id}/purge-previewpost/admin/tenants/{id}/unarchive
Unarchive a tenant (super-admin only). Writes resume immediately after cache bust.
Unarchive a tenant (super-admin only). Writes resume immediately after cache bust.. Available only when MULTI_TENANT_ENABLED is configured.
unarchiveTenant| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ | Tenant slug |
POST /admin/tenants/{id}/unarchivepost/admin/tenants/import
Import a portable tenant ZIP bundle
Multipart fields: bundle (ZIP file), id (new tenant slug), name, activate (true or false; default false). Expanded and compressed archives are limited to 128 MiB. Available only when MULTI_TENANT_ENABLED is configured.
importTenantPOST /admin/tenants/importget/admin/users/
List all named editor users (key redacted)
List all named editor users (key redacted).
listUsersGET /admin/users/post/admin/users/
Add a new named editor user
Add a new named editor user.
createUserapplication/jsonPOST /admin/users/delete/admin/users/{id}
Remove a named editor user (existing tokens rejected on next request)
Remove a named editor user (existing tokens rejected on next request).
deleteUser| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
DELETE /admin/users/{id}put/admin/users/{id}
Update an existing named editor user
Update an existing named editor user.
updateUser| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
application/jsonPUT /admin/users/{id}post/admin/users/reload
Reload the editor-user registry cache from the authoritative store (file or DB)
Reload the editor-user registry cache from the authoritative store (file or DB).
reloadUsersPOST /admin/users/reloadAudit
3 endpoints
delete/audit-events/
Purge audit events
Deletes audit events. Supply "before" for time-based retention purges, "actor" for GDPR erasure of a specific identity, or both to scope an erasure to events older than a cutoff. At least one of "before" or "actor" is required. Admin scope required.
purgeAuditEvents| Name | In | Required | Description |
|---|---|---|---|
| before | query | ISO 8601 cutoff — events with timestamp strictly before this value are deleted | |
| actor | query | Actor identifier — deletes events attributed to this actor (GDPR erasure). May be combined with "before" for scoped erasure. |
DELETE /audit-events/get/audit-events/
List audit events
Returns a paginated, filterable list of audit events. Admin scope required.
listAuditEvents| Name | In | Required | Description |
|---|---|---|---|
| limit | query | Maximum number of items to return (1-1000, default 50) | |
| offset | query | Number of items to skip | |
| event | query | Filter by event type | |
| operation | query | Filter by operation | |
| actor | query | Filter by actor | |
| resourceType | query | Filter by resource type | |
| resourceId | query | Filter by resource ID (template key or asset ID) | |
| since | query | ISO 8601 lower bound (inclusive) | |
| until | query | ISO 8601 upper bound (inclusive) |
GET /audit-events/get/audit-events/export
Stream audit events as CSV or NDJSON
Admin-only ascending export. Defaults to the last 30 days; CSV cells are protected from spreadsheet formulas. Each export is audited.
exportAuditEvents| Name | In | Required | Description |
|---|---|---|---|
| event | query | Filter by event type | |
| operation | query | Filter by operation | |
| actor | query | Filter by actor | |
| resourceType | query | Filter by resource type | |
| resourceId | query | Filter by resource ID (template key or asset ID) | |
| since | query | ISO 8601 lower bound (inclusive) | |
| until | query | ISO 8601 upper bound (inclusive) | |
| format | query |
GET /audit-events/exportUsage
9 endpoints
get/admin/usage
Cross-tenant usage; super-admin only
Cross-tenant usage; super-admin only.
getAdminUsageRollup| Name | In | Required | Description |
|---|---|---|---|
| from | query | ✓ | Inclusive lower bound |
| to | query | ✓ | Exclusive upper bound |
| source | query | ||
| mode | query | ||
| templateKey | query | ||
| credentialId | query | ||
| actor | query | ||
| scope | query | ||
| status | query | ||
| limit | query | ||
| offset | query | ||
| groupBy | query | ||
| stats | query |
GET /admin/usageget/renders
Search the tenant render log (admin)
Search the tenant render log (admin).
listRenders| Name | In | Required | Description |
|---|---|---|---|
| limit | query | Maximum number of items to return (1-1000, default 50) | |
| offset | query | Number of items to skip | |
| from | query | ✓ | |
| to | query | ✓ | |
| status | query | ||
| templateKey | query | ||
| format | query | ||
| mode | query | ||
| source | query | ||
| errorCode | query | ||
| correlationId | query | ||
| requestId | query | ||
| meta | query |
GET /rendersget/renders/{id}
Get a tenant render log entry (admin)
Get a tenant render log entry (admin).
getRender| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
GET /renders/{id}get/usage
Rollup render usage by time bucket or category
Aggregates render volume for the caller's tenant over a half-open [from, to) window. Temporal buckets (day/week/month) use UTC date_trunc; categorical buckets use direct group-by. Window capped at 92 days. Admin scope required. Returns 503 usage_not_available in file mode (no DB-backed store).
getUsageRollup| Name | In | Required | Description |
|---|---|---|---|
| from | query | ✓ | Inclusive lower bound |
| to | query | ✓ | Exclusive upper bound |
| source | query | ||
| mode | query | ||
| templateKey | query | ||
| credentialId | query | ||
| actor | query | ||
| scope | query | ||
| status | query | ||
| groupBy | query | ||
| stats | query |
GET /usageget/usage.csv
Export render usage rows as CSV for invoicing pipelines
Returns up to USAGE_EXPORT_MAX_ROWS rows as text/csv, ordered by timestamp. Hard cap 500000: if count exceeds cap, returns 413 usage_export_too_large with the count. Narrow the window to fit. Admin scope required. Returns 503 in file mode (no DB-backed store).
exportUsageCsv| Name | In | Required | Description |
|---|---|---|---|
| from | query | ✓ | Inclusive lower bound |
| to | query | ✓ | Exclusive upper bound |
| source | query | ||
| mode | query | ||
| templateKey | query | ||
| credentialId | query | ||
| actor | query | ||
| scope | query | ||
| status | query |
GET /usage.csvget/usage/ai
Roll up tenant AI usage and monthly budget
Roll up tenant AI usage and monthly budget.
getAiUsageRollup| Name | In | Required | Description |
|---|---|---|---|
| from | query | ✓ | |
| to | query | ✓ | |
| groupBy | query |
GET /usage/aiget/usage/ai.csv
Export tenant AI usage as CSV
Export tenant AI usage as CSV.
exportAiUsageCsv| Name | In | Required | Description |
|---|---|---|---|
| from | query | ✓ | |
| to | query | ✓ | |
| groupBy | query |
GET /usage/ai.csvget/usage/quota
Read caller render quotas and rate limits
Read caller render quotas and rate limits.
getRenderQuotaGET /usage/quotaget/usage/templates
Per-report usage and unused reports in a bounded window
Per-report usage and unused reports in a bounded window.
getUsageTemplateStats| Name | In | Required | Description |
|---|---|---|---|
| from | query | ✓ | Inclusive lower bound |
| to | query | ✓ | Exclusive upper bound |
| source | query | ||
| mode | query | ||
| templateKey | query | ||
| credentialId | query | ||
| actor | query | ||
| scope | query | ||
| status | query | ||
| limit | query | ||
| offset | query | ||
| sort | query | ||
| order | query | ||
| includeUnused | query | ||
| unusedOnly | query |
GET /usage/templatesHealth
4 endpoints
get/capabilities
Server feature capabilities — per-format render toggles + future flags
Returns which features are currently enabled at this server. v0.60.0 only carries per-format render route booleans (pdf/html/docx/csv/xlsx/pptx). PPTX is gated by the PPTX_ENABLED env var (default true). Always returns 200.
getCapabilitiesGET /capabilitiesget/capabilities/format-support
Per-format node and feature support
Per-format node and feature support.
getFormatSupportGET /capabilities/format-supportget/health
Liveness probe — always 200 if the process is up
Liveness probe — always 200 if the process is up.
getHealthGET /healthget/health/ready
Readiness probe — 503 if storage is unreachable
Readiness probe — 503 if storage is unreachable.
getHealthReadyGET /health/readyDatasets
3 endpoints
post/datasets
Upload a temporary JSON dataset
Tenant-private JSON data, reusable through dataRef until expiry. Gzip request encoding is supported. Supports optional Idempotency-Key for safe retries. Stored render responses honour it only with output.store=true and output.respondWith=link.
createDataset| Name | In | Required | Description |
|---|---|---|---|
| ttlSeconds | query | ||
| idempotency-key | header | Retry key, scoped to the current tenant, principal, method and concrete path. Reuse only for the same request. |
application/jsonPOST /datasetsdelete/datasets/{id}
Delete temporary dataset data
Delete temporary dataset data.
deleteDataset| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
DELETE /datasets/{id}get/datasets/{id}
Read temporary dataset metadata
Read temporary dataset metadata.
getDataset| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
GET /datasets/{id}Identity
25 endpoints
get/admin/identity-providers/
listIdentityProviders.
listIdentityProviders| Name | In | Required | Description |
|---|---|---|---|
| limit | query | ||
| offset | query |
GET /admin/identity-providers/post/admin/identity-providers/
createIdentityProvider.
createIdentityProviderapplication/jsonPOST /admin/identity-providers/delete/admin/identity-providers/{id}
deleteIdentityProvider.
deleteIdentityProvider| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
DELETE /admin/identity-providers/{id}get/admin/identity-providers/{id}
getIdentityProvider.
getIdentityProvider| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
GET /admin/identity-providers/{id}patch/admin/identity-providers/{id}
updateIdentityProvider.
updateIdentityProvider| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
application/jsonPATCH /admin/identity-providers/{id}get/auth/oidc/{slug}/callback
ssoOidcCallback. Available only when OIDC is configured.
ssoOidcCallback| Name | In | Required | Description |
|---|---|---|---|
| code | query | ||
| state | query | ||
| error | query | ||
| slug | path | ✓ |
GET /auth/oidc/{slug}/callbackpost/auth/saml/{slug}/acs
samlAcs.
samlAcs| Name | In | Required | Description |
|---|---|---|---|
| slug | path | ✓ |
application/jsonPOST /auth/saml/{slug}/acsget/auth/saml/{slug}/metadata
samlMetadata.
samlMetadata| Name | In | Required | Description |
|---|---|---|---|
| slug | path | ✓ |
GET /auth/saml/{slug}/metadataget/auth/sso/{slug}/login
ssoLogin.
ssoLogin| Name | In | Required | Description |
|---|---|---|---|
| return_url | query | ||
| slug | path | ✓ |
GET /auth/sso/{slug}/loginpost/auth/sso/discover
discoverSsoProvider.
discoverSsoProviderapplication/jsonPOST /auth/sso/discoverget/scim/v2/Groups
scimListGroups.
scimListGroups| Name | In | Required | Description |
|---|---|---|---|
| filter | query | ||
| startIndex | query | ||
| count | query |
GET /scim/v2/Groupspost/scim/v2/Groups
scimCreateGroups.
scimCreateGroupsapplication/jsonPOST /scim/v2/Groupsdelete/scim/v2/Groups/{id}
scimDeleteGroups.
scimDeleteGroups| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
DELETE /scim/v2/Groups/{id}get/scim/v2/Groups/{id}
scimGetGroups.
scimGetGroups| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
GET /scim/v2/Groups/{id}patch/scim/v2/Groups/{id}
scimPatchGroups.
scimPatchGroups| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
application/jsonPATCH /scim/v2/Groups/{id}put/scim/v2/Groups/{id}
scimReplaceGroups.
scimReplaceGroups| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
application/jsonPUT /scim/v2/Groups/{id}get/scim/v2/ResourceTypes
scimGetResourceTypes.
scimGetResourceTypesGET /scim/v2/ResourceTypesget/scim/v2/Schemas
scimGetSchemas.
scimGetSchemasGET /scim/v2/Schemasget/scim/v2/ServiceProviderConfig
scimGetServiceProviderConfig.
scimGetServiceProviderConfigGET /scim/v2/ServiceProviderConfigget/scim/v2/Users
scimListUsers.
scimListUsers| Name | In | Required | Description |
|---|---|---|---|
| filter | query | ||
| startIndex | query | ||
| count | query |
GET /scim/v2/Userspost/scim/v2/Users
scimCreateUsers.
scimCreateUsersapplication/jsonPOST /scim/v2/Usersdelete/scim/v2/Users/{id}
scimDeleteUsers.
scimDeleteUsers| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
DELETE /scim/v2/Users/{id}get/scim/v2/Users/{id}
scimGetUsers.
scimGetUsers| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
GET /scim/v2/Users/{id}patch/scim/v2/Users/{id}
scimPatchUsers.
scimPatchUsers| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
application/jsonPATCH /scim/v2/Users/{id}put/scim/v2/Users/{id}
scimReplaceUsers.
scimReplaceUsers| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
application/jsonPUT /scim/v2/Users/{id}Access Control
8 endpoints
get/admin/role-bindings
List direct and inherited bindings
List direct and inherited bindings.
listRoleBindings| Name | In | Required | Description |
|---|---|---|---|
| limit | query | ||
| offset | query | ||
| principalType | query | ||
| principalId | query | ||
| resourceType | query | ||
| resourceId | query | ||
| includeInherited | query |
GET /admin/role-bindingspost/admin/role-bindings
Bind a role to a principal and resource
Bind a role to a principal and resource.
createRoleBindingapplication/jsonPOST /admin/role-bindingsdelete/admin/role-bindings/{id}
Remove a role binding
Remove a role binding.
deleteRoleBinding| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
DELETE /admin/role-bindings/{id}get/admin/roles
List built-in and custom roles
List built-in and custom roles.
listRoles| Name | In | Required | Description |
|---|---|---|---|
| limit | query | ||
| offset | query |
GET /admin/rolespost/admin/roles
Create a custom role
Create a custom role.
createRoleapplication/jsonPOST /admin/rolesdelete/admin/roles/{name}
Delete an unused custom role
Delete an unused custom role.
deleteRole| Name | In | Required | Description |
|---|---|---|---|
| name | path | ✓ |
DELETE /admin/roles/{name}put/admin/roles/{name}
Update a custom role
Update a custom role.
updateRole| Name | In | Required | Description |
|---|---|---|---|
| name | path | ✓ |
application/jsonPUT /admin/roles/{name}get/auth/me
Inspect the current principal and effective permissions
Inspect the current principal and effective permissions.
getAuthMeGET /auth/mePortal
10 endpoints
get/portal/reports
List permitted published reports
List permitted published reports.
listPortalReports| Name | In | Required | Description |
|---|---|---|---|
| limit | query | ||
| offset | query | ||
| q | query | ||
| category | query |
GET /portal/reportsget/portal/reports/{key}
Get a published report and its guided form
Get a published report and its guided form.
getPortalReport| Name | In | Required | Description |
|---|---|---|---|
| key | path | ✓ |
GET /portal/reports/{key}post/portal/reports/{key}/runs
Run the published label and archive the result
Run the published label and archive the result.
runPortalReport| Name | In | Required | Description |
|---|---|---|---|
| key | path | ✓ |
application/jsonPOST /portal/reports/{key}/runsget/portal/runs
List report runs owned by the signed-in user
List report runs owned by the signed-in user.
listPortalRuns| Name | In | Required | Description |
|---|---|---|---|
| limit | query | ||
| offset | query |
GET /portal/runsget/portal/runs/{id}/download
Download an owned run using its signed expiring link
Download an owned run using its signed expiring link.
downloadPortalRun| Name | In | Required | Description |
|---|---|---|---|
| exp | query | ✓ | |
| d | query | ✓ | |
| sig | query | ✓ | |
| id | path | ✓ |
GET /portal/runs/{id}/downloadget/portal/subscriptions
List subscriptions owned by the signed-in user
List subscriptions owned by the signed-in user.
listPortalSubscriptions| Name | In | Required | Description |
|---|---|---|---|
| limit | query | ||
| offset | query |
GET /portal/subscriptionspost/portal/subscriptions
Subscribe only the signed-in user to their own email address
Subscribe only the signed-in user to their own email address.
createPortalSubscriptionapplication/jsonPOST /portal/subscriptionsdelete/portal/subscriptions/{id}
Delete an owned subscription
Delete an owned subscription.
deletePortalSubscription| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
DELETE /portal/subscriptions/{id}get/templates/{key}/portal
Read operational portal publication settings
Read operational portal publication settings.
getPortalPublication| Name | In | Required | Description |
|---|---|---|---|
| key | path | ✓ |
GET /templates/{key}/portalput/templates/{key}/portal
Set operational portal publication settings
Set operational portal publication settings.
setPortalPublication| Name | In | Required | Description |
|---|---|---|---|
| key | path | ✓ |
application/jsonPUT /templates/{key}/portalData
1 endpoint
post/data/convert
Convert CSV, XML or XLSX input to JSON
Convert CSV, XML or XLSX input to JSON.
convertDataapplication/jsonPOST /data/convertConnections
15 endpoints
get/admin/connections
List shared data connections
List shared data connections. Credentials are encrypted and write-only; responses never include tenant identifiers or stored secrets.
listDataConnections| Name | In | Required | Description |
|---|---|---|---|
| limit | query | Maximum number of items to return (1-1000, default 50) | |
| offset | query | Number of items to skip |
GET /admin/connectionspost/admin/connections
Create an encrypted data connection
Create an encrypted data connection. Credentials are encrypted and write-only; responses never include tenant identifiers or stored secrets.
createDataConnectionapplication/jsonPOST /admin/connectionsdelete/admin/connections/{id}
Delete a shared data connection
Delete a shared data connection. Credentials are encrypted and write-only; responses never include tenant identifiers or stored secrets.
deleteDataConnection| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
DELETE /admin/connections/{id}get/admin/connections/{id}
Get data connection settings
Get data connection settings. Credentials are encrypted and write-only; responses never include tenant identifiers or stored secrets.
getDataConnection| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
GET /admin/connections/{id}patch/admin/connections/{id}
Update connection settings or replace its secret
Update connection settings or replace its secret. Credentials are encrypted and write-only; responses never include tenant identifiers or stored secrets.
updateDataConnection| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
application/jsonPATCH /admin/connections/{id}post/admin/connections/{id}/test
Test connection authentication and reachability
Test connection authentication and reachability. Credentials are encrypted and write-only; responses never include tenant identifiers or stored secrets.
testDataConnection| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
application/jsonPOST /admin/connections/{id}/testget/connections/
List encrypted delivery connections
List encrypted delivery connections.
listDeliveryConnections| Name | In | Required | Description |
|---|---|---|---|
| limit | query | ||
| offset | query | ||
| type | query |
GET /connections/post/connections/
Create an encrypted delivery connection
Create an encrypted delivery connection.
createDeliveryConnectionapplication/jsonPOST /connections/delete/connections/{id}
Delete an unused delivery connection
Delete an unused delivery connection.
deleteDeliveryConnection| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
DELETE /connections/{id}get/connections/{id}
Get delivery connection settings
Get delivery connection settings.
getDeliveryConnection| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
GET /connections/{id}patch/connections/{id}
Update delivery settings and merge secrets
Update delivery settings and merge secrets.
updateDeliveryConnection| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
application/jsonPATCH /connections/{id}post/connections/{id}/test
Test delivery connection access
Test delivery connection access.
testDeliveryConnection| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
POST /connections/{id}/testget/connections/providers
List delivery providers and target schemas
List delivery providers and target schemas.
listDeliveryProvidersGET /connections/providersget/data/connections
List credential-free connection choices
List credential-free connection choices. Credentials are encrypted and write-only; responses never include tenant identifiers or stored secrets.
listAvailableDataConnections| Name | In | Required | Description |
|---|---|---|---|
| limit | query | Maximum number of items to return (1-1000, default 50) | |
| offset | query | Number of items to skip |
GET /data/connectionspost/render/preview/data-sources
Test an unsaved template data source
Editor-only bounded fetch using tenant-scoped connections. Returns the first 50 rows or a bounded text preview, source status and HTTP status. Credentials are never returned.
previewDataSourceapplication/jsonPOST /render/preview/data-sourcesESign
6 endpoints
post/esign/callbacks/{id}
Authenticated provider callback; status is re-fetched from the provider
Authenticated provider callback; status is re-fetched from the provider.
receiveEsignCallback| Name | In | Required | Description |
|---|---|---|---|
| t | query | ||
| id | path | ✓ |
POST /esign/callbacks/{id}get/esign/envelopes
List signature envelopes
List signature envelopes.
listEsignEnvelopes| Name | In | Required | Description |
|---|---|---|---|
| limit | query | ||
| offset | query | ||
| status | query | ||
| templateKey | query |
GET /esign/envelopespost/esign/envelopes
Render PDF and send it for signature
Render PDF and send it for signature.
createEsignEnvelopeapplication/jsonPOST /esign/envelopesget/esign/envelopes/{id}
Get signature envelope status
Get signature envelope status.
getEsignEnvelope| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
GET /esign/envelopes/{id}get/esign/envelopes/{id}/documents/{kind}
Download signed document or completion certificate
Download signed document or completion certificate.
downloadEsignDocument| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ | |
| kind | path | ✓ |
GET /esign/envelopes/{id}/documents/{kind}post/esign/envelopes/{id}/void
Void an outstanding signature request
Void an outstanding signature request.
voidEsignEnvelope| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
application/jsonPOST /esign/envelopes/{id}/voidBundles
2 endpoints
get/admin/bundles/export
Export portable templates and dependencies
Export portable templates and dependencies.
exportBundle| Name | In | Required | Description |
|---|---|---|---|
| keys | query | ||
| all | query | ||
| history | query | ||
| withDeps | query | ||
| include | query | ||
| version | query | ||
| label | query |
GET /admin/bundles/exportpost/admin/bundles/import
Plan or apply a portable environment bundle
Multipart bundle field. Validation and planning finish before any write. Application is atomic per template; partial failures return completed resources in plan.
importBundle| Name | In | Required | Description |
|---|---|---|---|
| dryRun | query | ||
| onConflict | query | ||
| preserveVersions | query | ||
| labelMap | query | ||
| allowMissingDeps | query | ||
| requireCompatible | query |
POST /admin/bundles/importTenant
6 endpoints
get/admin/tenants/{id}/settings
getAdminTenantSettings. Available only when MULTI_TENANT_ENABLED is configured.
getAdminTenantSettings| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
GET /admin/tenants/{id}/settingspatch/admin/tenants/{id}/settings
updateAdminTenantSettings. Available only when MULTI_TENANT_ENABLED is configured.
updateAdminTenantSettings| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ | |
| if-match | header | Current version ETag, e.g. "1.0.3" | |
| x-pulpengine-change-note | header | Percent-encoded UTF-8 change note; at most 1000 decoded characters and 8 KB encoded. |
application/jsonPATCH /admin/tenants/{id}/settingsget/tenant/branding
getTenantBranding.
getTenantBrandingGET /tenant/brandingget/tenant/quota
getTenantQuota.
getTenantQuotaGET /tenant/quotaget/tenant/settings
getTenantSettings.
getTenantSettingsGET /tenant/settingspatch/tenant/settings
updateTenantSettings.
updateTenantSettings| Name | In | Required | Description |
|---|---|---|---|
| if-match | header | Current version ETag, e.g. "1.0.3" | |
| x-pulpengine-change-note | header | Percent-encoded UTF-8 change note; at most 1000 decoded characters and 8 KB encoded. |
application/jsonPATCH /tenant/settingsCatalogue
5 endpoints
post/admin/catalogue/upgrade
bulkUpgradeCatalogueTemplate.
bulkUpgradeCatalogueTemplateapplication/jsonPOST /admin/catalogue/upgradeget/catalogue/templates
listCatalogueTemplates.
listCatalogueTemplates| Name | In | Required | Description |
|---|---|---|---|
| limit | query | ||
| offset | query |
GET /catalogue/templatesget/catalogue/templates/{key}
getCatalogueTemplate.
getCatalogueTemplate| Name | In | Required | Description |
|---|---|---|---|
| version | query | ||
| key | path | ✓ |
GET /catalogue/templates/{key}post/templates/{key}/fork
forkCatalogueTemplate.
forkCatalogueTemplate| Name | In | Required | Description |
|---|---|---|---|
| key | path | ✓ |
application/jsonPOST /templates/{key}/forkpost/templates/{key}/upgrade
upgradeCatalogueTemplate.
upgradeCatalogueTemplate| Name | In | Required | Description |
|---|---|---|---|
| key | path | ✓ | |
| if-match | header | Current version ETag, e.g. "1.0.3" | |
| x-pulpengine-change-note | header | Percent-encoded UTF-8 change note; at most 1000 decoded characters and 8 KB encoded. |
application/jsonPOST /templates/{key}/upgradeWebhooks
11 endpoints
get/webhooks/
List outbound event subscriptions
List outbound event subscriptions.
listWebhooks| Name | In | Required | Description |
|---|---|---|---|
| limit | query | Maximum number of items to return (1-1000, default 50) | |
| offset | query | Number of items to skip |
GET /webhooks/post/webhooks/
Create an outbound event subscription
Create an outbound event subscription.
createWebhookapplication/jsonPOST /webhooks/delete/webhooks/{id}
Delete a subscription and its delivery log
Delete a subscription and its delivery log.
deleteWebhook| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
DELETE /webhooks/{id}get/webhooks/{id}
Get an outbound event subscription
Get an outbound event subscription.
getWebhook| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
GET /webhooks/{id}patch/webhooks/{id}
Update an outbound event subscription
Update an outbound event subscription.
updateWebhook| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
application/jsonPATCH /webhooks/{id}get/webhooks/{id}/deliveries
List a subscription delivery log
List a subscription delivery log.
listWebhookDeliveries| Name | In | Required | Description |
|---|---|---|---|
| limit | query | Maximum number of items to return (1-1000, default 50) | |
| offset | query | Number of items to skip | |
| status | query | ||
| eventType | query | ||
| id | path | ✓ |
GET /webhooks/{id}/deliveriesget/webhooks/{id}/deliveries/{deliveryId}
Get the exact event payload and delivery outcome
Get the exact event payload and delivery outcome.
getWebhookDelivery| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ | |
| deliveryId | path | ✓ |
GET /webhooks/{id}/deliveries/{deliveryId}post/webhooks/{id}/deliveries/{deliveryId}/redeliver
Enqueue a new delivery of the same event
Enqueue a new delivery of the same event.
redeliverWebhook| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ | |
| deliveryId | path | ✓ |
POST /webhooks/{id}/deliveries/{deliveryId}/redeliverpost/webhooks/{id}/ping
Send and record a synchronous test event
Send and record a synchronous test event.
pingWebhook| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
POST /webhooks/{id}/pingpost/webhooks/{id}/rotate-secret
Rotate a subscription signing secret
Rotate a subscription signing secret.
rotateWebhookSecret| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
application/jsonPOST /webhooks/{id}/rotate-secretget/webhooks/event-types
List available outbound event types
List available outbound event types.
webhookEventTypesGET /webhooks/event-typesNodes
4 endpoints
post/nodes/expression
Generate and validate a JEXL expression
Generate and validate a JEXL expression.
generateExpressionapplication/jsonPOST /nodes/expressionpost/nodes/narrative/preview
Generate or retrieve a grounded narrative for explicit facts
Generate or retrieve a grounded narrative for explicit facts.
previewNarrativeapplication/jsonPOST /nodes/narrative/previewpost/nodes/rewrite
AI-rewrite the content of a single text or heading node (SSE stream)
Streams `delta` (append) or `replace` (reset-buffer) events, optional `restart` on repair, then a terminal `done` or `error`. Response Content-Type is text/event-stream. See plan for wire contract. Returns 503 when AI generation is disabled and 409 when block-form Handlebars (`{{#each}}`, `{{#if}}`, `{{else}}`) is present in content.
rewriteNodeapplication/jsonPOST /nodes/rewritepost/nodes/rewrite/outcome
Record the user's apply/dismiss choice for an AI node rewrite
Record the user's apply/dismiss choice for an AI node rewrite.
recordRewriteOutcomeapplication/jsonPOST /nodes/rewrite/outcomeTemplate Folders
5 endpoints
get/template-folders
List folders in the current tenant
List folders in the current tenant.
listTemplateFolders| Name | In | Required | Description |
|---|---|---|---|
| limit | query | Maximum number of items to return (1-1000, default 50) | |
| offset | query | Number of items to skip |
GET /template-folderspost/template-folders
Create a folder
Create a folder.
createTemplateFolderapplication/jsonPOST /template-foldersdelete/template-folders/{id}
Delete an empty folder (admin only)
Delete an empty folder (admin only).
deleteTemplateFolder| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
DELETE /template-folders/{id}patch/template-folders/{id}
Rename or move a folder and its subtree
Rename or move a folder and its subtree.
updateTemplateFolder| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
application/jsonPATCH /template-folders/{id}get/template-tags
List tags with active template counts
List tags with active template counts.
listTemplateTags| Name | In | Required | Description |
|---|---|---|---|
| limit | query | Maximum number of items to return (1-1000, default 50) | |
| offset | query | Number of items to skip | |
| q | query |
GET /template-tagsMCP
3 endpoints
delete/mcp
MCP supports POST only
MCP supports POST only.
mcpDeleteNotAllowedDELETE /mcpget/mcp
MCP supports POST only
MCP supports POST only.
mcpGetNotAllowedGET /mcppost/mcp
Stateless MCP streamable HTTP request
Stateless MCP streamable HTTP request.
mcpRequestapplication/jsonPOST /mcpDocuments
6 endpoints
get/documents/
List stored documents for the current tenant
List stored documents for the current tenant. Available only when DOCUMENT_STORE_ENABLED is configured.
listDocuments| Name | In | Required | Description |
|---|---|---|---|
| templateKey | query | ||
| format | query | ||
| source | query | ||
| scheduleId | query | ||
| createdFrom | query | ||
| createdTo | query | ||
| limit | query | ||
| offset | query |
GET /documents/delete/documents/{id}
Erase a stored document and its bytes
Erase a stored document and its bytes. Available only when DOCUMENT_STORE_ENABLED is configured.
deleteDocument| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
DELETE /documents/{id}get/documents/{id}
Read stored document metadata
Read stored document metadata. Available only when DOCUMENT_STORE_ENABLED is configured.
getDocument| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
GET /documents/{id}get/documents/{id}/content
Download stored bytes using an API key or signed URL
Download stored bytes using an API key or signed URL. Available only when DOCUMENT_STORE_ENABLED is configured.
downloadDocument| Name | In | Required | Description |
|---|---|---|---|
| exp | query | Signed Unix expiry; do not edit. | |
| d | query | Signed disposition a (attachment) or i (inline). | |
| id | path | ✓ |
GET /documents/{id}/contentpost/documents/{id}/links
Issue a signed document download link
Issue a signed document download link. Available only when DOCUMENT_STORE_ENABLED is configured.
createDocumentLink| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
application/jsonPOST /documents/{id}/linkspost/documents/{id}/links/revoke
Revoke every outstanding document link
Revoke every outstanding document link. Available only when DOCUMENT_STORE_ENABLED is configured.
revokeDocumentLinks| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
POST /documents/{id}/links/revokeRender Preview
1 endpoint
post/render/preview/office
Fill a stored Office template for private preview or native download
Fill a stored Office template for private preview or native download.
previewOfficeTemplateapplication/jsonPOST /render/preview/officeRender
30 endpoints
post/render/
[Deprecated - use /render/pdf] Render a template to PDF
Sunset: 2027-03-06. Supports optional Idempotency-Key for safe retries. Stored render responses honour it only with output.store=true and output.respondWith=link.
renderPdfLegacy| Name | In | Required | Description |
|---|---|---|---|
| stream | query | Streaming control. Unset (default) or true → chunked stream when no post-render hooks are registered. false → force buffered response. true + post-render hooks → 400 STREAM_INCOMPATIBLE_HOOK. | |
| idempotency-key | header | Retry key, scoped to the current tenant, principal, method and concrete path. Reuse only for the same request. |
application/jsonPOST /render/post/render/batch
Render multiple templates to PDF in a single request
Renders up to 50 templates concurrently. Each item is rendered independently; one failure does not abort others. Default response is a single JSON envelope. When the caller sends `Accept: application/x-ndjson`, the route streams one `result` line per item in completion order as each resolves, followed by a single `summary` line with authoritative totals.
renderBatchPdfapplication/jsonPOST /render/batchpost/render/batch/async
[Deprecated - use /render/jobs] Submit an async PDF batch render with webhook callback
Accepts up to 50 templates. Returns 202 immediately with a job ID. Results are rendered in the background and the webhook URL receives a metadata-only notification on completion. Poll GET /render/batch/jobs/:id for full results including rendered PDFs. Supports optional Idempotency-Key for safe retries. Stored render responses honour it only with output.store=true and output.respondWith=link.
submitAsyncBatchPdfLegacy| Name | In | Required | Description |
|---|---|---|---|
| idempotency-key | header | Retry key, scoped to the current tenant, principal, method and concrete path. Reuse only for the same request. |
application/jsonPOST /render/batch/asyncpost/render/batch/async/docx
[Deprecated - use /render/jobs] Submit an async DOCX batch render with webhook callback
Accepts up to 50 templates. Returns 202 immediately with a job ID. Results are rendered in the background and the webhook URL receives a metadata-only notification on completion. Poll GET /render/batch/jobs/:id for full results including rendered DOCX bytes. Supports optional Idempotency-Key for safe retries. Stored render responses honour it only with output.store=true and output.respondWith=link.
submitAsyncBatchDocxLegacy| Name | In | Required | Description |
|---|---|---|---|
| idempotency-key | header | Retry key, scoped to the current tenant, principal, method and concrete path. Reuse only for the same request. |
application/jsonPOST /render/batch/async/docxpost/render/batch/csv
renderBatchCsv.
renderBatchCsvapplication/jsonPOST /render/batch/csvpost/render/batch/docx
Render multiple templates to DOCX in a single request
Renders up to 50 templates concurrently. Each item is rendered independently; one failure does not abort others. Results are returned as base64-encoded DOCX bytes in a JSON envelope.
renderBatchDocxapplication/jsonPOST /render/batch/docxpost/render/batch/html
renderBatchHtml.
renderBatchHtmlapplication/jsonPOST /render/batch/htmlget/render/batch/jobs/{id}
[Deprecated - use /render/jobs] Poll async batch job status
Returns the current status and results (when complete) of an async batch render job. Results include base64-encoded rendered output. Jobs are retained after completion for at least WEBHOOK_JOB_RETENTION_SECONDS; on postgres deployments completed jobs survive API restart and remain pollable until that retention window elapses. Pending/processing jobs that survive a restart without their worker are failed at the next start via the orphan-reconciliation step.
getAsyncBatchJobLegacy| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
GET /render/batch/jobs/{id}post/render/batch/pptx
Render multiple templates to PPTX in a single request
Renders up to 50 templates concurrently as PowerPoint presentations. Each item is rendered independently; one failure does not abort others. Each successful result includes a warningCount field counting structured warnings emitted by the renderer. Beta in v0.60.0 — gated by PPTX_ENABLED.
renderBatchPptxapplication/jsonPOST /render/batch/pptxpost/render/batch/xlsx
renderBatchXlsx.
renderBatchXlsxapplication/jsonPOST /render/batch/xlsxpost/render/convert/pdf
Convert HTML or an allowlisted URL to PDF
Convert HTML or an allowlisted URL to PDF. Available only when CONVERT_HTML_ENABLED is configured.
convertHtmlToPdf| Name | In | Required | Description |
|---|---|---|---|
| stream | query |
application/jsonPOST /render/convert/pdfpost/render/csv
Export table data as CSV, TSV or a ZIP
Extracts table and pivot data with configurable CSV dialects. Select `tableId` for one table or `csv.tables: all` for a ZIP or stacked file. Request options override template CSV defaults. A tab delimiter returns TSV. BOM is off by default. Supports optional Idempotency-Key for safe retries. Stored render responses honour it only with output.store=true and output.respondWith=link.
renderCsv| Name | In | Required | Description |
|---|---|---|---|
| idempotency-key | header | Retry key, scoped to the current tenant, principal, method and concrete path. Reuse only for the same request. |
application/jsonPOST /render/csvpost/render/docx
Render a template to DOCX
Renders a template to a Word document (.docx). The template AST is walked directly — no browser required. Supports optional Idempotency-Key for safe retries. Stored render responses honour it only with output.store=true and output.respondWith=link.
renderDocx| Name | In | Required | Description |
|---|---|---|---|
| idempotency-key | header | Retry key, scoped to the current tenant, principal, method and concrete path. Reuse only for the same request. |
application/jsonPOST /render/docxpost/render/einvoice
Generate a CII or UBL invoice from a saved template
Generate a CII or UBL invoice from a saved template.
renderEInvoiceapplication/jsonPOST /render/einvoicepost/render/email
Render email HTML, plain text and inline images
Render email HTML, plain text and inline images.
renderEmailapplication/jsonPOST /render/emailpost/render/html
Render a template to HTML
Supports optional Idempotency-Key for safe retries. Stored render responses honour it only with output.store=true and output.respondWith=link.
renderHtml| Name | In | Required | Description |
|---|---|---|---|
| idempotency-key | header | Retry key, scoped to the current tenant, principal, method and concrete path. Reuse only for the same request. |
application/jsonPOST /render/htmlpost/render/image
Render PDF pages as PNG, JPEG or WebP
Render PDF pages as PNG, JPEG or WebP.
renderImageapplication/jsonPOST /render/imageget/render/jobs
List render jobs
List render jobs.
listRenderJobs| Name | In | Required | Description |
|---|---|---|---|
| status | query | ||
| since | query | ||
| until | query | ||
| reference | query | ||
| limit | query | ||
| offset | query |
GET /render/jobspost/render/jobs
Submit a pollable render job in any format
Supports optional Idempotency-Key for safe retries. Stored render responses honour it only with output.store=true and output.respondWith=link.
submitRenderJob| Name | In | Required | Description |
|---|---|---|---|
| idempotency-key | header | Retry key, scoped to the current tenant, principal, method and concrete path. Reuse only for the same request. |
application/jsonPOST /render/jobsdelete/render/jobs/{id}
Purge a terminal render job and its transport blobs
Purge a terminal render job and its transport blobs.
deleteRenderJob| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
DELETE /render/jobs/{id}get/render/jobs/{id}
Poll a render job
Poll a render job.
getRenderJob| Name | In | Required | Description |
|---|---|---|---|
| include | query | ||
| id | path | ✓ |
GET /render/jobs/{id}post/render/jobs/{id}/cancel
Cancel a render job, keeping finished items
Cancel a render job, keeping finished items.
cancelRenderJob| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
POST /render/jobs/{id}/cancelget/render/jobs/{id}/items/{index}/content
Download completed item bytes
Download completed item bytes.
downloadRenderJobItem| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ | |
| index | path | ✓ |
GET /render/jobs/{id}/items/{index}/contentget/render/jobs/{id}/package
downloadRenderJobPackage.
downloadRenderJobPackage| Name | In | Required | Description |
|---|---|---|---|
| id | path | ✓ |
GET /render/jobs/{id}/packagepost/render/pdf
Render a template to PDF
Supports optional Idempotency-Key for safe retries. Stored render responses honour it only with output.store=true and output.respondWith=link.
renderPdf| Name | In | Required | Description |
|---|---|---|---|
| stream | query | Streaming control. Unset (default) or true → chunked stream when no post-render hooks are registered. false → force buffered response. true + post-render hooks → 400 STREAM_INCOMPATIBLE_HOOK. | |
| idempotency-key | header | Retry key, scoped to the current tenant, principal, method and concrete path. Reuse only for the same request. |
application/jsonPOST /render/pdfpost/render/pdf/book
Assemble a PDF report book with final folios and contents
Assemble a PDF report book with final folios and contents.
renderPdfBookapplication/jsonPOST /render/pdf/bookpost/render/pptx
Render a template to PPTX
Renders a template to a PowerPoint presentation (.pptx). Beta in v0.60.0 — gated by the PPTX_ENABLED env var (default true). The renderer walks the template AST directly and produces a .pptx binary via pptxgenjs. Structured warnings are surfaced via the x-render-warnings response header. Supports optional Idempotency-Key for safe retries. Stored render responses honour it only with output.store=true and output.respondWith=link.
renderPptx| Name | In | Required | Description |
|---|---|---|---|
| idempotency-key | header | Retry key, scoped to the current tenant, principal, method and concrete path. Reuse only for the same request. |
application/jsonPOST /render/pptxpost/render/preview/einvoice
Check an unsaved invoice with sample data
Check an unsaved invoice with sample data.
checkEInvoiceapplication/jsonPOST /render/preview/einvoicepost/render/validate
Validate a template for publish readiness — always registered, no HTML/PDF output
Validates a template DEFINITION for structural correctness and renderability. Always runs (1) Zod structural parse and (2) blocked-asset detection. For (3) renderability, behaviour depends on whether the request includes a `formats` array. Without `formats` (legacy default): runs an HTML-only trial render and returns `{ valid, issues }` byte-for-byte unchanged from pre-v0.78.0. With `formats` (v0.78.0+): runs each requested format through its real renderer, classifies typed errors into structural (untagged, emitted once) and format-specific (tagged with the originating `format`), and returns a `skippedFormats` array listing any requested formats disabled by server capability (e.g. pptx when PPTX_ENABLED=false). PDF is special: it never boots Chromium — when requested, an HTML preflight runs and an info-severity PDF_VALIDATED_VIA_HTML issue is emitted to acknowledge transitive coverage. For format-specific runtime issues a real /render call is required. This endpoint does NOT validate input data against a stored template — use POST /templates/:key/validate for that.
validateTemplateDefinitionapplication/jsonPOST /render/validatepost/render/xlsx
Export table data from a template as XLSX
Extracts table nodes from a template and renders them into an Excel workbook. Single-table templates auto-select; multi-table templates produce one sheet per table (or filter to a single table via `tableId`). Supports optional Idempotency-Key for safe retries. Stored render responses honour it only with output.store=true and output.respondWith=link.
renderXlsx| Name | In | Required | Description |
|---|---|---|---|
| idempotency-key | header | Retry key, scoped to the current tenant, principal, method and concrete path. Reuse only for the same request. |
application/jsonPOST /render/xlsx