contentTemplates
The methods of pd.contentTemplates. Inputs and outputs are described in Conventions; every method can also fail as described in Errors.
Methods
pd.contentTemplates.list(input, init?)
List the content templates available to a workspace
GET /api/workspaces/{workspaceId}/content-templates
Returns the built-in templates (isSystem true, workspaceId null), which every workspace shares, together with the workspace's own, ordered by name. Requires templates.read.
Input
| Name | In | Type | Required | Description |
|---|---|---|---|---|
workspaceId |
path | string (uuid) |
yes | Id of the workspace the request works in. The caller must be a member of it, or hold an API key issued by it. For anyone else, an unknown id and an id they do not belong to both answer 404 RESOURCE_NOT_FOUND, so membership cannot be probed. |
init |
init | { signal?: AbortSignal; timeoutMs?: number } |
no | The second argument: signal aborts the call, timeoutMs overrides the client's per-attempt timeout. |
Returns 200 OK
| Field | Type | Required | Description |
|---|---|---|---|
templates |
object[] |
yes | Built-in templates and the workspace's own, ordered by name. |
templates[].id |
string (uuid) |
yes | Template id; pass it as contentTemplateId when generating an article. |
templates[].workspaceId |
string (uuid) | null |
yes | Owning workspace. Null for a built-in template, shared by every workspace. |
templates[].name |
string |
yes | Display name; the list is ordered by it. |
templates[].slug |
string |
yes | Derived from the name at creation; it does not change on rename. |
templates[].description |
string |
yes | What the template is for; empty when none was given. |
templates[].sections |
object[] |
yes | The headings a generated outline must carry, top to bottom, each with its level and what it covers. Empty for a template that fixes no structure. |
templates[].sections[].heading |
string |
yes | Heading text the generated outline must carry for this section, 1-200 characters. |
templates[].sections[].level |
2 | 3 |
yes | Heading level: 2 for a main section, 3 for a subsection under the previous 2. |
templates[].sections[].purpose |
string |
yes | What the section must cover, up to 500 characters; guides the generated text. May be empty. |
templates[].defaultWordCount |
integer |
yes | Target article length in words, pre-filled in the web app when the template is chosen. |
templates[].tone |
string | null |
yes | Tone pre-filled in the web app when the template is chosen (professional, conversational, authoritative, practical or persuasive). Null when the template sets none. |
templates[].cta |
string | null |
yes | The call to action that closes the article. |
templates[].isSystem |
boolean |
yes | True for a built-in template, which is read-only. |
Errors 400 invalid input, 401 missing or invalid key, 403 the key's roles lack the permission, 404 not found, 429 rate limited or out of quota. See Errors.
Example
import { PrismDraft } from "@prism-draft/sdk";
const pd = new PrismDraft({ apiKey: process.env.PRISMDRAFT_API_KEY! });
const result = await pd.contentTemplates.list({
workspaceId: "3f0c5a1e-8b2d-4c6e-9a7f-1d2e3f4a5b6c",
});
console.log(result);
pd.contentTemplates.create(input, init?)
Create a workspace content template
POST /api/workspaces/{workspaceId}/content-templates
Requires templates.create; answers 201 and records a templates.created audit entry. The slug is derived from the name and unique within the workspace: when it is taken, a random six-character suffix is added. Sections are required in order; the call to action closes the article. Generation follows the sections and the call to action; defaultWordCount and tone are defaults the web app pre-fills when the template is chosen.
Input
| Name | In | Type | Required | Description |
|---|---|---|---|---|
workspaceId |
path | string (uuid) |
yes | Id of the workspace the request works in. The caller must be a member of it, or hold an API key issued by it. For anyone else, an unknown id and an id they do not belong to both answer 404 RESOURCE_NOT_FOUND, so membership cannot be probed. |
body |
body | object |
yes | |
body.name |
body | string |
yes | Display name, 1-120 characters. The slug is derived from it when the template is created and does not follow a later rename. |
body.description |
body | string |
no | What the template is for, up to 500 characters. Stored as an empty string when omitted on create; left unchanged when omitted on update. |
body.sections |
body | object[] |
yes | The sections an article written from this template must have, in order: 1 to 20. On update the list replaces the stored one as a whole. |
body.sections[].heading |
body | string |
yes | Heading text the generated outline must carry for this section, 1-200 characters. |
body.sections[].level |
body | 2 | 3 |
yes | Heading level: 2 for a main section, 3 for a subsection under the previous 2. |
body.sections[].purpose |
body | string |
yes | What the section must cover, up to 500 characters; guides the generated text. May be empty. |
body.defaultWordCount |
body | integer |
yes | Target article length in words, 200 to 10000. The web app pre-fills it when the template is chosen. |
body.tone |
body | "professional" | "conversational" | "authoritative" | "practical" | "persuasive" | null |
no | Tone the web app pre-fills when the template is chosen: professional, conversational, authoritative, practical or persuasive. null or omitted on create: no tone is set; on update null clears it and omitting leaves it unchanged. |
body.cta |
body | string | null |
no | Call to action that closes a generated article, 1-200 characters. null or omitted on create: none; on update null clears it and omitting leaves it unchanged. |
init |
init | { signal?: AbortSignal; timeoutMs?: number } |
no | The second argument: signal aborts the call, timeoutMs overrides the client's per-attempt timeout. |
Returns 201 Created
| Field | Type | Required | Description |
|---|---|---|---|
template |
object |
yes | The template as stored after the call. |
template.id |
string (uuid) |
yes | Template id; pass it as contentTemplateId when generating an article. |
template.workspaceId |
string (uuid) | null |
yes | Owning workspace. Null for a built-in template, shared by every workspace. |
template.name |
string |
yes | Display name; the list is ordered by it. |
template.slug |
string |
yes | Derived from the name at creation; it does not change on rename. |
template.description |
string |
yes | What the template is for; empty when none was given. |
template.sections |
object[] |
yes | The headings a generated outline must carry, top to bottom, each with its level and what it covers. Empty for a template that fixes no structure. |
template.sections[].heading |
string |
yes | Heading text the generated outline must carry for this section, 1-200 characters. |
template.sections[].level |
2 | 3 |
yes | Heading level: 2 for a main section, 3 for a subsection under the previous 2. |
template.sections[].purpose |
string |
yes | What the section must cover, up to 500 characters; guides the generated text. May be empty. |
template.defaultWordCount |
integer |
yes | Target article length in words, pre-filled in the web app when the template is chosen. |
template.tone |
string | null |
yes | Tone pre-filled in the web app when the template is chosen (professional, conversational, authoritative, practical or persuasive). Null when the template sets none. |
template.cta |
string | null |
yes | The call to action that closes the article. |
template.isSystem |
boolean |
yes | True for a built-in template, which is read-only. |
Errors 400 invalid input, 401 missing or invalid key, 403 the key's roles lack the permission, 404 not found, 429 rate limited or out of quota. See Errors.
Example
import { PrismDraft } from "@prism-draft/sdk";
const pd = new PrismDraft({ apiKey: process.env.PRISMDRAFT_API_KEY! });
const result = await pd.contentTemplates.create({
workspaceId: "3f0c5a1e-8b2d-4c6e-9a7f-1d2e3f4a5b6c",
body: {
name: "example",
sections: [
{
heading: "example",
level: 2,
purpose: "example",
},
],
defaultWordCount: 200,
},
});
console.log(result);
pd.contentTemplates.update(input, init?)
Update a workspace content template
PATCH /api/workspaces/{workspaceId}/content-templates/{templateId}
Requires templates.update. Only the fields sent change; sections, when sent, replaces the whole list. Built-in templates answer 403: every workspace shares them. A template that does not exist or belongs to another workspace answers 404. The slug does not change. Records a templates.updated audit entry.
Input
| Name | In | Type | Required | Description |
|---|---|---|---|---|
workspaceId |
path | string (uuid) |
yes | Id of the workspace the request works in. The caller must be a member of it, or hold an API key issued by it. For anyone else, an unknown id and an id they do not belong to both answer 404 RESOURCE_NOT_FOUND, so membership cannot be probed. |
templateId |
path | string (uuid) |
yes | Id of the content template, from contentTemplates.list. |
body |
body | object |
no | |
body.name |
body | string |
no | Display name, 1-120 characters. The slug is derived from it when the template is created and does not follow a later rename. |
body.description |
body | string |
no | What the template is for, up to 500 characters. Stored as an empty string when omitted on create; left unchanged when omitted on update. |
body.sections |
body | object[] |
no | The sections an article written from this template must have, in order: 1 to 20. On update the list replaces the stored one as a whole. |
body.sections[].heading |
body | string |
yes | Heading text the generated outline must carry for this section, 1-200 characters. |
body.sections[].level |
body | 2 | 3 |
yes | Heading level: 2 for a main section, 3 for a subsection under the previous 2. |
body.sections[].purpose |
body | string |
yes | What the section must cover, up to 500 characters; guides the generated text. May be empty. |
body.defaultWordCount |
body | integer |
no | Target article length in words, 200 to 10000. The web app pre-fills it when the template is chosen. |
body.tone |
body | "professional" | "conversational" | "authoritative" | "practical" | "persuasive" | null |
no | Tone the web app pre-fills when the template is chosen: professional, conversational, authoritative, practical or persuasive. null or omitted on create: no tone is set; on update null clears it and omitting leaves it unchanged. |
body.cta |
body | string | null |
no | Call to action that closes a generated article, 1-200 characters. null or omitted on create: none; on update null clears it and omitting leaves it unchanged. |
init |
init | { signal?: AbortSignal; timeoutMs?: number } |
no | The second argument: signal aborts the call, timeoutMs overrides the client's per-attempt timeout. |
Returns 200 OK
| Field | Type | Required | Description |
|---|---|---|---|
template |
object |
yes | The template as stored after the call. |
template.id |
string (uuid) |
yes | Template id; pass it as contentTemplateId when generating an article. |
template.workspaceId |
string (uuid) | null |
yes | Owning workspace. Null for a built-in template, shared by every workspace. |
template.name |
string |
yes | Display name; the list is ordered by it. |
template.slug |
string |
yes | Derived from the name at creation; it does not change on rename. |
template.description |
string |
yes | What the template is for; empty when none was given. |
template.sections |
object[] |
yes | The headings a generated outline must carry, top to bottom, each with its level and what it covers. Empty for a template that fixes no structure. |
template.sections[].heading |
string |
yes | Heading text the generated outline must carry for this section, 1-200 characters. |
template.sections[].level |
2 | 3 |
yes | Heading level: 2 for a main section, 3 for a subsection under the previous 2. |
template.sections[].purpose |
string |
yes | What the section must cover, up to 500 characters; guides the generated text. May be empty. |
template.defaultWordCount |
integer |
yes | Target article length in words, pre-filled in the web app when the template is chosen. |
template.tone |
string | null |
yes | Tone pre-filled in the web app when the template is chosen (professional, conversational, authoritative, practical or persuasive). Null when the template sets none. |
template.cta |
string | null |
yes | The call to action that closes the article. |
template.isSystem |
boolean |
yes | True for a built-in template, which is read-only. |
Errors 400 invalid input, 401 missing or invalid key, 403 the key's roles lack the permission, 404 not found, 429 rate limited or out of quota. See Errors.
Example
import { PrismDraft } from "@prism-draft/sdk";
const pd = new PrismDraft({ apiKey: process.env.PRISMDRAFT_API_KEY! });
const result = await pd.contentTemplates.update({
workspaceId: "3f0c5a1e-8b2d-4c6e-9a7f-1d2e3f4a5b6c",
templateId: "3f0c5a1e-8b2d-4c6e-9a7f-1d2e3f4a5b6c",
});
console.log(result);
pd.contentTemplates.delete(input, init?)
Delete a workspace content template
DELETE /api/workspaces/{workspaceId}/content-templates/{templateId}
Requires templates.delete. Built-in templates answer 403; a template that does not exist or belongs to another workspace answers 404. Articles that used the template keep their content; generating them again runs without its structure. Records a templates.deleted audit entry.
Input
| Name | In | Type | Required | Description |
|---|---|---|---|---|
workspaceId |
path | string (uuid) |
yes | Id of the workspace the request works in. The caller must be a member of it, or hold an API key issued by it. For anyone else, an unknown id and an id they do not belong to both answer 404 RESOURCE_NOT_FOUND, so membership cannot be probed. |
templateId |
path | string (uuid) |
yes | Id of the content template, from contentTemplates.list. |
init |
init | { signal?: AbortSignal; timeoutMs?: number } |
no | The second argument: signal aborts the call, timeoutMs overrides the client's per-attempt timeout. |
Returns 200 OK
| Field | Type | Required | Description |
|---|---|---|---|
ok |
boolean |
yes | Always true; a failure is an error response. |
Errors 400 invalid input, 401 missing or invalid key, 403 the key's roles lack the permission, 404 not found, 429 rate limited or out of quota. See Errors.
Example
import { PrismDraft } from "@prism-draft/sdk";
const pd = new PrismDraft({ apiKey: process.env.PRISMDRAFT_API_KEY! });
const result = await pd.contentTemplates.delete({
workspaceId: "3f0c5a1e-8b2d-4c6e-9a7f-1d2e3f4a5b6c",
templateId: "3f0c5a1e-8b2d-4c6e-9a7f-1d2e3f4a5b6c",
});
console.log(result);