Duplicate a template
POST/api/v1/email/templates/{id}/duplicate
POST /email/templates/{id}/duplicate
curl -X POST 'https://www.unitpost.com/api/v1/email/templates/tmpl_123/duplicate' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'User-Agent: my-app/1.0' \
-H 'Content-Type: application/json' \
-d '{ }'Response · 201
{
"object": "template",
"id": "id_123",
"name": "Example",
"subject": "Welcome to Acme",
"status": "draft",
"editor": "simple",
"kind": "simple",
"preview_text": "string",
"category": "transactional",
"html": "string",
"tsx": "string",
"text": "string",
"warnings": [
"string"
],
"created_at": "2026-01-01T00:00:00.000Z",
"updated_at": "2026-01-01T00:00:00.000Z"
}Copy a template into a new draft, as the dashboard's Duplicate does: its name (with " (copy)", or your name), subject, editor and body carry over; its status, versions and usage don't. Pass an Idempotency-Key so a retry returns the same copy instead of making a second one. Requires the templates:write capability.
Parameters2 fields
| Field | Type | Description |
|---|---|---|
idrequired | string · path | — |
Idempotency-Key | string · header | Any unique string (1–256 characters, e.g. a UUID). Retrying with the same key and the same body within 24 hours returns the first result instead of sending again; the same key with a different body is `409 invalid_idempotent_request`, and one still in flight is `409 concurrent_idempotent_requests`. |
Request body1 field
| Field | Type | Description |
|---|---|---|
name | string | The copy's name. Default: the original's with " (copy)". |
Response · 201 fields15 fields
| Field | Type | Description |
|---|---|---|
objectrequired | string | — |
idrequired | string | — |
namerequired | string | — |
subjectrequired | string | null | — |
statusrequired | enumdraft | published | — |
editor | enumsimple | design | code | Which editor this template is authored in — and so which body field updates it. `design`: built from @unitpost/email components (the dashboard's Design tab) — update with `tsx`. `simple`: a plain, personal Gmail-style email (the Simple tab) — update with `text`. `code`: raw HTML (the Code tab) — update with `html`. Keep the editor unless the user asked to switch; to switch, send the other body field or `editor` alone to convert the current body. |
kindrequired | enumsimple | designed | The coarse kind: `simple` (editor `simple`) or `designed` (editor `design` or `code`). Prefer `editor`. |
preview_text | string | Inbox preview text: the snippet most inboxes show after the subject. Empty when unset. |
category | enumtransactional | marketing | `marketing` (a campaign can send it; it gets the unsubscribe footer at send) or `transactional` (receipts, sign-in codes, notifications: no footer, and campaigns refuse it). Change it with `category` on an update. |
html | string | null | — |
tsx | string | null | A `design` template's body as @unitpost/email component TSX, wrapped in the `<Email …>` element that carries its theme, preview text and category — edit it and send it back as `tsx`. Null for `simple` and `code` templates. Present on single reads; omitted from list rows. |
text | string | null | A `simple` template's body in the Simple `text` format: edit it and send it back as `text`. Null for `design` and `code` templates, and for a Simple email the format can't carry whole (an indented line): change that one in the dashboard, or send a whole new `text`. Present on single reads; omitted from list rows. |
warnings | string[] | Create or update only: what changed that you didn't write, in plain words — markup the Simple format removed from `text`, `<Email>` attributes or theme values that were ignored, what an `editor` conversion flattened or couldn't keep, a `tsx` write that switched the template's editor. Absent when nothing did. Tell the user. |
created_atrequired | string | — |
updated_atrequired | string | — |
201400401403404409422