# Dynamic Document API: Templates

> Read published templates, versions and data schemas; create, publish and roll back.

> Part of the Dynamic Document API documentation. Index of all pages for agents: [llms.txt](https://dynamicdocumentapi.com/llms.txt), every page in one file: [llms-full.txt](https://dynamicdocumentapi.com/llms-full.txt).

10 endpoints of the [API reference](https://dynamicdocumentapi.com/docs/api-reference/index.md), version 1.0.0. Interactive reference: https://dynamicdocumentapi.com/docs/api-reference#tag/templates. Machine-readable OpenAPI document: https://dynamicdocumentapi.com/openapi/openapi-public.json

## Servers

- https://api-eu.dynamicdocumentapi.com — EU (Germany)

## Endpoints

- `GET /v1/templates` — List templates
- `POST /v1/templates` — Create a template
- `GET /v1/templates/{template_id}` — Retrieve a template
- `DELETE /v1/templates/{template_id}` — Delete a template
- `PUT /v1/templates/{template_id}/draft` — Replace the draft sources
- `POST /v1/templates/{template_id}/publish` — Publish the draft
- `POST /v1/templates/{template_id}/rollback` — Roll back to a version
- `GET /v1/templates/{template_id}/schema` — Data schema of a template
- `GET /v1/templates/{template_id}/versions` — List template versions
- `GET /v1/templates/{template_id}/versions/{number}` — Retrieve a template version

## GET /v1/templates

**List templates**

Parameters:

| Name | In | Type | Description |
|---|---|---|---|
| `cursor` | query | string |  |
| `limit` | query | integer |  |
| `q` | query | string |  |
| `type` | query | string |  |

Responses:

- `200` 
- `401` Missing, invalid, expired or revoked credentials.
- `403` Insufficient scope, IP not allowed, workspace suspended or scheduled for deletion, or email not verified.
- `429` Rate limited (`Retry-After`).

## POST /v1/templates

**Create a template**

Creates a `pdf_code`, `pdf_markdown` or `image_canvas` template. The content fields depend on `type` (any type may send one `content` object instead); they land in the draft — publish it to get a live version.

Parameters:

| Name | In | Type | Description |
|---|---|---|---|
| `Idempotency-Key` | header | string | Replays the stored response for 24 h; a different body with the same key → 422. |

Request body (`application/json`): TemplateCreateRequest

Responses:

- `201` 
- `400` Invalid request body (`errors[]` with JSON pointers).
- `401` Missing, invalid, expired or revoked credentials.
- `403` Insufficient scope, IP not allowed, workspace suspended or scheduled for deletion, or email not verified; or `template_not_allowed_for_key`: the key is restricted to specific templates.
- `429` Rate limited (`Retry-After`).
- `503` The control plane is unreachable (`Retry-After`).

## GET /v1/templates/{template_id}

**Retrieve a template**

Parameters:

| Name | In | Type | Description |
|---|---|---|---|
| `template_id` (required) | path | string |  |

Responses:

- `200` 
- `401` Missing, invalid, expired or revoked credentials.
- `403` Insufficient scope, IP not allowed, workspace suspended or scheduled for deletion, or email not verified.
- `404` Template not found.
- `410` Template deleted.
- `429` Rate limited (`Retry-After`).

## DELETE /v1/templates/{template_id}

**Delete a template**

Soft delete: the template moves to the trash and is purged after 30 days. Renders that reference it keep working until then; new renders answer `410 template_deleted`.

Parameters:

| Name | In | Type | Description |
|---|---|---|---|
| `template_id` (required) | path | string | Template id (`tpl_…`). |

Responses:

- `200` 
- `400` Invalid request body (`errors[]` with JSON pointers).
- `401` Missing, invalid, expired or revoked credentials.
- `403` Insufficient scope, IP not allowed, workspace suspended or scheduled for deletion, or email not verified.
- `404` Template not found.
- `410` Template already deleted.
- `423` The template is locked (`template_locked`); Owners and Admins unlock it in the dashboard.
- `429` Rate limited (`Retry-After`).
- `503` The control plane is unreachable (`Retry-After`).

## PUT /v1/templates/{template_id}/draft

**Replace the draft sources**

Replaces the draft with the content fields of the template's type (see `POST /v1/templates`) or one `content` object. Send `If-Match: <revision>` (the `revision` of the draft you edited) to detect concurrent edits; a stale revision answers `409 draft_revision_conflict`. The response carries the new revision in `ETag`. `image_canvas` drafts are compiled when published — and by `version: draft` renders, which answer `422` with JSON pointers under `/template/draft` when the draft does not compile.

Parameters:

| Name | In | Type | Description |
|---|---|---|---|
| `If-Match` | header | string | Draft revision you based the edit on. |
| `template_id` (required) | path | string | Template id (`tpl_…`). |

Request body (`application/json`): TemplateDraftWriteRequest

Responses:

- `200` Saved. `ETag` holds the new revision.
- `400` Invalid request body (`errors[]` with JSON pointers).
- `401` Missing, invalid, expired or revoked credentials.
- `403` Insufficient scope, IP not allowed, workspace suspended or scheduled for deletion, or email not verified.
- `404` Template not found.
- `409` The draft changed since the revision in `If-Match` (`draft_revision_conflict`).
- `410` Template deleted.
- `423` The template is locked (`template_locked`); Owners and Admins unlock it in the dashboard.
- `429` Rate limited (`Retry-After`).
- `503` The control plane is unreachable (`Retry-After`).

## POST /v1/templates/{template_id}/publish

**Publish the draft**

Validates the draft (compile, options, syntax, datasets) and publishes a new live version. `201` when the run finished, `202` when validation is still running, `422` when a step failed — the problem details then carry the run in `publish_run`.

Parameters:

| Name | In | Type | Description |
|---|---|---|---|
| `Idempotency-Key` | header | string | Replays the stored response for 24 h; a different body with the same key → 422. |
| `template_id` (required) | path | string | Template id (`tpl_…`). |

Request body (`application/json`): TemplatePublish

| Field | Type | Description |
|---|---|---|
| `note` | string |  |

Responses:

- `201` Published.
- `202` Validation is still running.
- `400` Invalid request body (`errors[]` with JSON pointers).
- `401` Missing, invalid, expired or revoked credentials.
- `403` Insufficient scope, IP not allowed, workspace suspended or scheduled for deletion, or email not verified.
- `404` Template not found.
- `410` Template deleted.
- `422` Validation failed; `publish_run` holds the failing steps.
- `429` Rate limited (`Retry-After`).
- `503` The control plane is unreachable (`Retry-After`).

## POST /v1/templates/{template_id}/rollback

**Roll back to a version**

Points `live_version` at an existing version. Nothing is re-rendered and no new version is created.

Parameters:

| Name | In | Type | Description |
|---|---|---|---|
| `Idempotency-Key` | header | string | Replays the stored response for 24 h; a different body with the same key → 422. |
| `template_id` (required) | path | string | Template id (`tpl_…`). |

Request body (`application/json`, required): TemplateRollback

| Field | Type | Description |
|---|---|---|
| `version` (required) | integer or string | Version number (`7`) or a `tv_…` id. |

Responses:

- `200` 
- `400` Invalid request body (`errors[]` with JSON pointers).
- `401` Missing, invalid, expired or revoked credentials.
- `403` Insufficient scope, IP not allowed, workspace suspended or scheduled for deletion, or email not verified.
- `404` Template or version not found.
- `410` Template deleted.
- `429` Rate limited (`Retry-After`).
- `503` The control plane is unreachable (`Retry-After`).

## GET /v1/templates/{template_id}/schema

**Data schema of a template**

Parameters:

| Name | In | Type | Description |
|---|---|---|---|
| `format` | query | "make" | `make` adds `make_parameters`, the data fields as Make module parameters. |
| `template_id` (required) | path | string |  |

Responses:

- `200` 
- `400` Unknown `format`.
- `401` Missing, invalid, expired or revoked credentials.
- `403` Insufficient scope, IP not allowed, workspace suspended or scheduled for deletion, or email not verified.
- `404` Template not found.
- `429` Rate limited (`Retry-After`).

## GET /v1/templates/{template_id}/versions

**List template versions**

Parameters:

| Name | In | Type | Description |
|---|---|---|---|
| `template_id` (required) | path | string |  |

Responses:

- `200` 
- `401` Missing, invalid, expired or revoked credentials.
- `403` Insufficient scope, IP not allowed, workspace suspended or scheduled for deletion, or email not verified.
- `429` Rate limited (`Retry-After`).

## GET /v1/templates/{template_id}/versions/{number}

**Retrieve a template version**

Parameters:

| Name | In | Type | Description |
|---|---|---|---|
| `number` (required) | path | string |  |
| `template_id` (required) | path | string |  |

Responses:

- `200` 
- `401` Missing, invalid, expired or revoked credentials.
- `403` Insufficient scope, IP not allowed, workspace suspended or scheduled for deletion, or email not verified.
- `404` Version not found.
- `429` Rate limited (`Retry-After`).
