categories
The methods of pd.categories. Inputs and outputs are described in Conventions; every method can also fail as described in Errors.
Methods
pd.categories.list(input, init?)
List categories
GET /api/workspaces/{workspaceId}/categories
Every category of the workspace, oldest first, each with its names in every language (sorted by language) and articleCount: how many of the workspace's articles carry it. Needs categories.read.
Input
| Name | In | Type | Required | Description |
|---|---|---|---|---|
workspaceId |
path | string (uuid) |
yes | Id of the workspace the categories belong to. |
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 |
|---|---|---|---|
categories |
object[] |
yes | Every category of the workspace, oldest first. |
categories[].id |
string (uuid) |
yes | Id of the category. |
categories[].workspaceId |
string (uuid) |
yes | Id of the workspace the category belongs to. |
categories[].primaryLanguage |
string |
yes | Language tag of the category's main name; it always has a name in this language. |
categories[].createdAt |
string (date-time) |
yes | When the category was created. |
categories[].updatedAt |
string (date-time) |
yes | When the category's main language or one of its names last changed. |
categories[].translations |
object[] |
yes | The category's names, one per language, sorted by language tag. |
categories[].translations[].id |
string (uuid) |
yes | Id of this name. |
categories[].translations[].categoryId |
string (uuid) |
yes | Id of the category the name belongs to. |
categories[].translations[].workspaceId |
string (uuid) |
yes | Id of the workspace the category belongs to. |
categories[].translations[].language |
string |
yes | Language tag this name is written in. |
categories[].translations[].name |
string |
yes | The category's name in language. |
categories[].translations[].slug |
string |
yes | URL-safe form of name, unique among the workspace's categories in language (category when the name has no Latin letter or digit; a short suffix breaks a clash). |
categories[].translations[].createdAt |
string (date-time) |
yes | When this name was added. |
categories[].translations[].updatedAt |
string (date-time) |
yes | When this name was last renamed. |
categories[].articleCount |
integer |
yes | Articles of the workspace that carry the category, every status and language. |
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.categories.list({
workspaceId: "3f0c5a1e-8b2d-4c6e-9a7f-1d2e3f4a5b6c",
});
console.log(result);
pd.categories.create(input, init?)
Create a category
POST /api/workspaces/{workspaceId}/categories
A category belongs to the workspace, so every project can use it. It is named in at least its primary language; a name that already exists in that language (compared without regard to case) is a 409, and a body without a name in primaryLanguage or with two names in one language is refused with INVALID_REQUEST. Needs categories.create; writes an audit entry. Answers 201.
Input
| Name | In | Type | Required | Description |
|---|---|---|---|---|
workspaceId |
path | string (uuid) |
yes | Id of the workspace the categories belong to. |
body |
body | object |
yes | |
body.primaryLanguage |
body | string |
yes | The category's main language. translations must hold a name in this language. |
body.translations |
body | object[] |
yes | The category's names, 1 to 20, at most one per language. |
body.translations[].language |
body | string |
yes | Language tag this name is written in, e.g. en or pt-BR. |
body.translations[].name |
body | string |
yes | The category's name in language, 1 to 80 characters, trimmed. Case-insensitively unique among the workspace's categories in that language (409 otherwise); the category's slug for that language is derived from it. |
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 |
|---|---|---|---|
category |
object |
yes | The category as it is after the change. |
category.id |
string (uuid) |
yes | Id of the category. |
category.workspaceId |
string (uuid) |
yes | Id of the workspace the category belongs to. |
category.primaryLanguage |
string |
yes | Language tag of the category's main name; it always has a name in this language. |
category.createdAt |
string (date-time) |
yes | When the category was created. |
category.updatedAt |
string (date-time) |
yes | When the category's main language or one of its names last changed. |
category.translations |
object[] |
yes | The category's names, one per language, sorted by language tag. |
category.translations[].id |
string (uuid) |
yes | Id of this name. |
category.translations[].categoryId |
string (uuid) |
yes | Id of the category the name belongs to. |
category.translations[].workspaceId |
string (uuid) |
yes | Id of the workspace the category belongs to. |
category.translations[].language |
string |
yes | Language tag this name is written in. |
category.translations[].name |
string |
yes | The category's name in language. |
category.translations[].slug |
string |
yes | URL-safe form of name, unique among the workspace's categories in language (category when the name has no Latin letter or digit; a short suffix breaks a clash). |
category.translations[].createdAt |
string (date-time) |
yes | When this name was added. |
category.translations[].updatedAt |
string (date-time) |
yes | When this name was last renamed. |
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.categories.create({
workspaceId: "3f0c5a1e-8b2d-4c6e-9a7f-1d2e3f4a5b6c",
body: {
primaryLanguage: "example",
translations: [
{
language: "example",
name: "example",
},
],
},
});
console.log(result);
pd.categories.update(input, init?)
Rename a category, add or remove a language
PATCH /api/workspaces/{workspaceId}/categories/{categoryId}
Changes any of the category's main language, its names and the languages it is named in; at least one of primaryLanguage, translations and removeLanguages is required. It must end with a name in the primary language, and a language cannot be both renamed and removed (INVALID_REQUEST); a name that clashes with another category's in that language is a 409. Needs categories.update. When the change alters what articles embed of the category (a name, a language, the primary language), each PUBLISHED article carrying it emits an article.updated webhook with categories among the changed fields. Writes an audit entry.
Input
| Name | In | Type | Required | Description |
|---|---|---|---|---|
workspaceId |
path | string (uuid) |
yes | Id of the workspace the categories belong to. |
categoryId |
path | string (uuid) |
yes | Id of the category, as id in GET /api/workspaces/{workspaceId}/categories. |
body |
body | object |
no | |
body.primaryLanguage |
body | string |
no | New main language. The category must still have a name in it once the other changes apply. Omit to keep the current one. |
body.translations |
body | object[] |
no | Names to set, up to 20, at most one per language: added when the category has no name in that language yet, otherwise it renames that one. |
body.translations[].language |
body | string |
yes | Language tag this name is written in, e.g. en or pt-BR. |
body.translations[].name |
body | string |
yes | The category's name in language, 1 to 80 characters, trimmed. Case-insensitively unique among the workspace's categories in that language (409 otherwise); the category's slug for that language is derived from it. |
body.removeLanguages |
body | string[] |
no | Languages whose name is deleted, up to 20. Refused if a language is also in translations, or if it would leave no name in the primary language. |
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 |
|---|---|---|---|
category |
object |
yes | The category as it is after the change. |
category.id |
string (uuid) |
yes | Id of the category. |
category.workspaceId |
string (uuid) |
yes | Id of the workspace the category belongs to. |
category.primaryLanguage |
string |
yes | Language tag of the category's main name; it always has a name in this language. |
category.createdAt |
string (date-time) |
yes | When the category was created. |
category.updatedAt |
string (date-time) |
yes | When the category's main language or one of its names last changed. |
category.translations |
object[] |
yes | The category's names, one per language, sorted by language tag. |
category.translations[].id |
string (uuid) |
yes | Id of this name. |
category.translations[].categoryId |
string (uuid) |
yes | Id of the category the name belongs to. |
category.translations[].workspaceId |
string (uuid) |
yes | Id of the workspace the category belongs to. |
category.translations[].language |
string |
yes | Language tag this name is written in. |
category.translations[].name |
string |
yes | The category's name in language. |
category.translations[].slug |
string |
yes | URL-safe form of name, unique among the workspace's categories in language (category when the name has no Latin letter or digit; a short suffix breaks a clash). |
category.translations[].createdAt |
string (date-time) |
yes | When this name was added. |
category.translations[].updatedAt |
string (date-time) |
yes | When this name was last renamed. |
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.categories.update({
workspaceId: "3f0c5a1e-8b2d-4c6e-9a7f-1d2e3f4a5b6c",
categoryId: "3f0c5a1e-8b2d-4c6e-9a7f-1d2e3f4a5b6c",
});
console.log(result);
pd.categories.delete(input, init?)
Delete a category
DELETE /api/workspaces/{workspaceId}/categories/{categoryId}
Permanent: the category, its names and its links to articles are removed, and the answer says how many articles carried it. Needs categories.delete. Each PUBLISHED article that carried it emits an article.updated webhook with categories among the changed fields. Writes an audit entry.
Input
| Name | In | Type | Required | Description |
|---|---|---|---|---|
workspaceId |
path | string (uuid) |
yes | Id of the workspace the categories belong to. |
categoryId |
path | string (uuid) |
yes | Id of the category, as id in GET /api/workspaces/{workspaceId}/categories. |
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 |
true |
yes | Always true; the category was deleted. |
articleCount |
integer |
yes | Articles that carried the category. |
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.categories.delete({
workspaceId: "3f0c5a1e-8b2d-4c6e-9a7f-1d2e3f4a5b6c",
categoryId: "3f0c5a1e-8b2d-4c6e-9a7f-1d2e3f4a5b6c",
});
console.log(result);
pd.categories.setForArticle(input, init?)
Set an article's categories
PUT /api/articles/{articleId}/categories
Replaces the article's whole set with categoryIds; ids not listed are unlinked, and listing the same id twice counts once. Every id must be a category of the article's own workspace (INVALID_REQUEST otherwise). Needs articles.update. When the set changed and the article is PUBLISHED, it emits an article.updated webhook with categories among the changed fields; assigning the same set again sends nothing. Writes an audit entry.
Input
| Name | In | Type | Required | Description |
|---|---|---|---|---|
articleId |
path | string (uuid) |
yes | Id of the article whose categories are replaced. |
body |
body | object |
yes | |
body.categoryIds |
body | string (uuid)[] |
yes | Ids of the categories the article should carry, up to 50, replacing its current set. Send [] to remove them all. Each must be a category of the article's workspace. |
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 |
|---|---|---|---|
categories |
object[] |
yes | The categories the article carries now, in the order they were assigned. |
categories[].id |
string (uuid) |
yes | Id of the category. |
categories[].primaryLanguage |
string |
yes | Language tag of the category's main name. |
categories[].translations |
object[] |
yes | The category's name in each language it has. |
categories[].translations[].language |
string |
yes | Language tag of this name. |
categories[].translations[].name |
string |
yes | The category's name in language. |
categories[].translations[].slug |
string |
yes | URL-safe form of name, unique among the workspace's categories in language. |
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.categories.setForArticle({
articleId: "3f0c5a1e-8b2d-4c6e-9a7f-1d2e3f4a5b6c",
body: {
categoryIds: ["3f0c5a1e-8b2d-4c6e-9a7f-1d2e3f4a5b6c"],
},
});
console.log(result);
pd.categories.suggestForArticle(input, init?)
Suggest categories for an article
POST /api/articles/{articleId}/categories/suggest
Up to seven suggestions in all: the workspace's existing categories that the article does not carry yet, then new names only if none fits. Nothing is stored; accept a suggestion with PUT /api/articles/{articleId}/categories or POST /api/workspaces/{workspaceId}/categories. Needs articles.update. Costs one credit, reserved before the model is called (402 INSUFFICIENT_CREDITS when the wallet cannot cover it) and released when nothing comes back, in which case credits is 0. 429 QUOTA_EXCEEDED when the workspace's monthly AI operations quota is used up.
Input
| Name | In | Type | Required | Description |
|---|---|---|---|---|
articleId |
path | string (uuid) |
yes | Id of the article to suggest categories for. |
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 |
|---|---|---|---|
existing |
object[] |
yes | Categories of the workspace that fit and are not yet assigned. |
existing[].category |
object |
yes | A category of the workspace that fits the article. |
existing[].category.id |
string (uuid) |
yes | Id of the existing category, to send to PUT /api/articles/{articleId}/categories. |
existing[].category.name |
string |
yes | The name in the article's language. |
existing[].reason |
string |
yes | Why the model suggests the category, at most 300 characters. |
proposed |
object[] |
yes | New names, offered only when no existing category fits. |
proposed[].name |
string |
yes | A new category name, in the article's language. |
proposed[].reason |
string |
yes | Why the model proposes the name, at most 300 characters. |
credits |
integer |
yes | Credits charged: the price when something came back, 0 when nothing did. |
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.categories.suggestForArticle({
articleId: "3f0c5a1e-8b2d-4c6e-9a7f-1d2e3f4a5b6c",
});
console.log(result);
pd.categories.suggestForProject(input, init?)
Suggest a starter set of categories for a project
POST /api/projects/{projectId}/categories/suggest
Up to seven new names drawn from the project's article titles, target keywords and idea clusters, none repeating a category name the workspace already has. Nothing is stored; accept a name with POST /api/workspaces/{workspaceId}/categories. Needs categories.create and articles.read on the project. Costs one credit, reserved before the model is called (402 INSUFFICIENT_CREDITS) and released when nothing comes back, in which case credits is 0. 429 QUOTA_EXCEEDED when the workspace's monthly AI operations quota is used up.
Input
| Name | In | Type | Required | Description |
|---|---|---|---|---|
projectId |
path | string (uuid) |
yes | Id of the project the starter categories are suggested for. |
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 |
|---|---|---|---|
categories |
object[] |
yes | Up to 7 new category names, none repeating a name the workspace already has. |
categories[].name |
string |
yes | A suggested category name, in the project's language. |
categories[].reason |
string |
yes | Why the model suggests the name, at most 300 characters. |
credits |
integer |
yes | Credits charged: the price when something came back, 0 when nothing did. |
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.categories.suggestForProject({
projectId: "3f0c5a1e-8b2d-4c6e-9a7f-1d2e3f4a5b6c",
});
console.log(result);
pd.categories.translate(input, init?)
Suggest names for a category in other languages
POST /api/workspaces/{workspaceId}/categories/{categoryId}/translate
One suggested name per requested language, translated from the category's name in its primary language, for review: nothing is saved until the category is updated with PATCH /api/workspaces/{workspaceId}/categories/{categoryId}. Needs categories.update. Costs half a credit per language, rounded up per request (402 INSUFFICIENT_CREDITS when the wallet cannot cover it), and the reservation is released when nothing comes back, in which case credits is 0. INVALID_REQUEST when languages includes the category's primary language. 429 QUOTA_EXCEEDED when the workspace's monthly AI operations quota is used up.
Input
| Name | In | Type | Required | Description |
|---|---|---|---|---|
workspaceId |
path | string (uuid) |
yes | Id of the workspace the category belongs to. |
categoryId |
path | string (uuid) |
yes | Id of the category to suggest names for. |
body |
body | object |
yes | |
body.languages |
body | string[] |
yes | Language tags to suggest a name in, 1 to 10, each once. The category's primary language is refused. |
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 |
|---|---|---|---|
names |
object[] |
yes | One suggested name for each requested language, for review; nothing is saved. |
names[].language |
string |
yes | Language tag the name is written in. |
names[].name |
string |
yes | The suggested name of the category in language. |
credits |
integer |
yes | Credits charged: the price when something came back, 0 when nothing did. |
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.categories.translate({
workspaceId: "3f0c5a1e-8b2d-4c6e-9a7f-1d2e3f4a5b6c",
categoryId: "3f0c5a1e-8b2d-4c6e-9a7f-1d2e3f4a5b6c",
body: {
languages: ["example"],
},
});
console.log(result);