PrismDraft SDK

ideas

The methods of pd.ideas. Inputs and outputs are described in Conventions; every method can also fail as described in Errors.

Methods

pd.ideas.list(input, init?)

List content ideas

GET /api/workspaces/{workspaceId}/ideas

Returns the workspace's content ideas ordered by priority (lowest number first), then newest first; the list is not paginated. Requires articles.read; with projectId, on that project (403 for a caller who is not one of its members; 404 RESOURCE_NOT_FOUND for a project that does not exist or belongs to another workspace), and without it the ideas of projects the caller cannot access are left out. An idea has no status of its own: it is open while its articleId is null and written once an article was created from it.

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.
projectId query string (uuid) no Only the ideas planned for this project. Absent: every idea of the workspace, including workspace-level ones, which a project filter leaves out.
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
ideas object[] yes The ideas, ordered by priority (lowest number first), then newest first. Not paginated.
ideas[].id string (uuid) yes Id of the idea.
ideas[].workspaceId string (uuid) yes Id of the workspace that owns the idea.
ideas[].projectId string (uuid) | null yes Id of the project the idea is planned for. null for an idea that belongs to the workspace rather than to a project.
ideas[].topic string yes The subject to write about, in up to 300 characters. For a suggested idea (ideas.generate, or an onboarding draft) it equals title.
ideas[].title string yes Working headline for the article, up to 300 characters. An empty string when none was given.
ideas[].primaryKeyword string yes The main search phrase the idea targets. An empty string when none was given.
ideas[].searchIntent "informational" | "commercial" | "transactional" | "navigational" | null yes What a reader searching for this is after: informational (to learn), commercial (to compare options before choosing), transactional (to act or buy) or navigational (to reach a specific site or page). null when not set.
ideas[].contentCluster string yes Label of the group of related topics the idea belongs to, used to keep ideas on one theme together. An empty string when none was given.
ideas[].priority integer yes Rank from 1 (write first) to 5 (last). ideas.list returns lower numbers first; 3 when none was given.
ideas[].articleId string (uuid) | null yes Id of the article written from the idea. The server sets it when an article is created with this idea's ideaId (articles.create); it cannot be set here. null while the idea is open, and again if that article is deleted.
ideas[].createdAt string (date-time) yes When the idea was created, as an ISO 8601 UTC date-time.
ideas[].updatedAt string (date-time) yes When the idea was last changed, as an ISO 8601 UTC date-time.

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.ideas.list({
  workspaceId: "3f0c5a1e-8b2d-4c6e-9a7f-1d2e3f4a5b6c",
});
console.log(result);

pd.ideas.create(input, init?)

Create a content idea

POST /api/workspaces/{workspaceId}/ideas

Stores an idea by hand. Requires articles.create in the workspace, and on projectId when one is sent: a foreign project answers 404 and an archived one 409. An idea becomes an article through articles.create, which takes the idea's ideaId and sets its articleId; this call cannot set it. Answers 201.

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.topic body string yes The subject to write about, 1 to 300 characters. Required on creation.
body.title body string no A working headline for the article, up to 300 characters. Stored as an empty string when absent.
body.primaryKeyword body string no The main search phrase the idea targets, up to 200 characters. Stored as an empty string when absent.
body.searchIntent body "informational" | "commercial" | "transactional" | "navigational" | null no What a reader searching for this is after: informational (to learn), commercial (to compare options before choosing), transactional (to act or buy) or navigational (to reach a specific site or page). null or absent: not set.
body.contentCluster body string no Label of the group of related topics the idea belongs to, up to 200 characters. Stored as an empty string when absent.
body.priority body integer no Rank from 1 (write first) to 5 (last). Defaults to 3.
body.projectId body string (uuid) | null no Id of the project the idea is planned for. It must be in this workspace (404 otherwise) and not archived (409), and the caller needs the permission on it. null or absent: a workspace-level idea.
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
idea object yes The idea as stored after the request.
idea.id string (uuid) yes Id of the idea.
idea.workspaceId string (uuid) yes Id of the workspace that owns the idea.
idea.projectId string (uuid) | null yes Id of the project the idea is planned for. null for an idea that belongs to the workspace rather than to a project.
idea.topic string yes The subject to write about, in up to 300 characters. For a suggested idea (ideas.generate, or an onboarding draft) it equals title.
idea.title string yes Working headline for the article, up to 300 characters. An empty string when none was given.
idea.primaryKeyword string yes The main search phrase the idea targets. An empty string when none was given.
idea.searchIntent "informational" | "commercial" | "transactional" | "navigational" | null yes What a reader searching for this is after: informational (to learn), commercial (to compare options before choosing), transactional (to act or buy) or navigational (to reach a specific site or page). null when not set.
idea.contentCluster string yes Label of the group of related topics the idea belongs to, used to keep ideas on one theme together. An empty string when none was given.
idea.priority integer yes Rank from 1 (write first) to 5 (last). ideas.list returns lower numbers first; 3 when none was given.
idea.articleId string (uuid) | null yes Id of the article written from the idea. The server sets it when an article is created with this idea's ideaId (articles.create); it cannot be set here. null while the idea is open, and again if that article is deleted.
idea.createdAt string (date-time) yes When the idea was created, as an ISO 8601 UTC date-time.
idea.updatedAt string (date-time) yes When the idea was last changed, as an ISO 8601 UTC date-time.

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.ideas.create({
  workspaceId: "3f0c5a1e-8b2d-4c6e-9a7f-1d2e3f4a5b6c",
  body: {
    topic: "example",
  },
});
console.log(result);

pd.ideas.update(input, init?)

Update a content idea

PATCH /api/workspaces/{workspaceId}/ideas/{ideaId}

Changes the fields sent and keeps the others; null clears searchIntent and projectId. Requires articles.update, checked against the new projectId when one is sent and against the idea's current project and article: 403 for a caller who is not a member of a restricted project, 409 when that project is archived. 404 when the idea is not in the workspace. articleId cannot be changed here: only creating an article from the idea sets it.

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.
ideaId path string (uuid) yes Id of the idea, in the workspace workspaceId. 404 when it is not.
body body object no
body.topic body string no The subject to write about, 1 to 300 characters. Absent: unchanged.
body.title body string no A working headline for the article, up to 300 characters. Absent: unchanged.
body.primaryKeyword body string no The main search phrase the idea targets, up to 200 characters. Absent: unchanged.
body.searchIntent body "informational" | "commercial" | "transactional" | "navigational" | null no What a reader searching for this is after: informational (to learn), commercial (to compare options before choosing), transactional (to act or buy) or navigational (to reach a specific site or page). null clears it; absent: unchanged.
body.contentCluster body string no Label of the group of related topics the idea belongs to, up to 200 characters. Absent: unchanged.
body.priority body integer no Rank from 1 (write first) to 5 (last). Absent: unchanged.
body.projectId body string (uuid) | null no Id of the project the idea is planned for, under the rules of ideas.create: in this workspace (404 otherwise), not archived (409), and the caller needs the permission on it. null makes it a workspace-level idea; absent: 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
idea object yes The idea as stored after the request.
idea.id string (uuid) yes Id of the idea.
idea.workspaceId string (uuid) yes Id of the workspace that owns the idea.
idea.projectId string (uuid) | null yes Id of the project the idea is planned for. null for an idea that belongs to the workspace rather than to a project.
idea.topic string yes The subject to write about, in up to 300 characters. For a suggested idea (ideas.generate, or an onboarding draft) it equals title.
idea.title string yes Working headline for the article, up to 300 characters. An empty string when none was given.
idea.primaryKeyword string yes The main search phrase the idea targets. An empty string when none was given.
idea.searchIntent "informational" | "commercial" | "transactional" | "navigational" | null yes What a reader searching for this is after: informational (to learn), commercial (to compare options before choosing), transactional (to act or buy) or navigational (to reach a specific site or page). null when not set.
idea.contentCluster string yes Label of the group of related topics the idea belongs to, used to keep ideas on one theme together. An empty string when none was given.
idea.priority integer yes Rank from 1 (write first) to 5 (last). ideas.list returns lower numbers first; 3 when none was given.
idea.articleId string (uuid) | null yes Id of the article written from the idea. The server sets it when an article is created with this idea's ideaId (articles.create); it cannot be set here. null while the idea is open, and again if that article is deleted.
idea.createdAt string (date-time) yes When the idea was created, as an ISO 8601 UTC date-time.
idea.updatedAt string (date-time) yes When the idea was last changed, as an ISO 8601 UTC date-time.

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.ideas.update({
  workspaceId: "3f0c5a1e-8b2d-4c6e-9a7f-1d2e3f4a5b6c",
  ideaId: "3f0c5a1e-8b2d-4c6e-9a7f-1d2e3f4a5b6c",
});
console.log(result);

pd.ideas.delete(input, init?)

Delete a content idea

DELETE /api/workspaces/{workspaceId}/ideas/{ideaId}

Deletes the idea. Requires articles.delete, on the idea's project and article when it has them (403 for a caller who is not a member of a restricted project, 409 when it is archived). An article written from it is untouched, and a stored brief that named it keeps its content and loses the link. 404 when the idea is not in the workspace.

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.
ideaId path string (uuid) yes Id of the idea, in the workspace workspaceId. 404 when it is not.
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. A resource that does not exist answers 404 instead.

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.ideas.delete({
  workspaceId: "3f0c5a1e-8b2d-4c6e-9a7f-1d2e3f4a5b6c",
  ideaId: "3f0c5a1e-8b2d-4c6e-9a7f-1d2e3f4a5b6c",
});
console.log(result);

pd.ideas.generate(input, init?)

Suggest content ideas for a project

POST /api/projects/{projectId}/ideas/generate

Asks the model for up to 8 article ideas drawn from the project's profile (name, description, industry, audience, website and language) and stores them as ideas of the project with priority 3. The 60 most recent titles the project already has, as ideas or articles, are not repeated. Search volume and difficulty are never invented. Requires articles.create on the project. Costs 1 credit, reserved before the model is called, charged when at least one idea is stored, and released when none comes back or the call fails: 402 INSUFFICIENT_CREDITS when the balance cannot cover it, 429 QUOTA_EXCEEDED when the ai_operations quota is used up. Answers 201, with an empty ideas list when nothing new came back.

Input

Name In Type Required Description
projectId path string (uuid) yes Id of the project. The workspace is read from the project, never from the request; a caller who is not a member of it gets 404 RESOURCE_NOT_FOUND.
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
ideas object[] yes The ideas the model suggested and the server stored on the project, with priority 3 and no articleId. Empty when the batch brought nothing new.
ideas[].id string (uuid) yes Id of the idea.
ideas[].workspaceId string (uuid) yes Id of the workspace that owns the idea.
ideas[].projectId string (uuid) | null yes Id of the project the idea is planned for. null for an idea that belongs to the workspace rather than to a project.
ideas[].topic string yes The subject to write about, in up to 300 characters. For a suggested idea (ideas.generate, or an onboarding draft) it equals title.
ideas[].title string yes Working headline for the article, up to 300 characters. An empty string when none was given.
ideas[].primaryKeyword string yes The main search phrase the idea targets. An empty string when none was given.
ideas[].searchIntent "informational" | "commercial" | "transactional" | "navigational" | null yes What a reader searching for this is after: informational (to learn), commercial (to compare options before choosing), transactional (to act or buy) or navigational (to reach a specific site or page). null when not set.
ideas[].contentCluster string yes Label of the group of related topics the idea belongs to, used to keep ideas on one theme together. An empty string when none was given.
ideas[].priority integer yes Rank from 1 (write first) to 5 (last). ideas.list returns lower numbers first; 3 when none was given.
ideas[].articleId string (uuid) | null yes Id of the article written from the idea. The server sets it when an article is created with this idea's ideaId (articles.create); it cannot be set here. null while the idea is open, and again if that article is deleted.
ideas[].createdAt string (date-time) yes When the idea was created, as an ISO 8601 UTC date-time.
ideas[].updatedAt string (date-time) yes When the idea was last changed, as an ISO 8601 UTC date-time.
credits integer yes Credits charged for the batch: 1, or 0 when no idea came back.

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.ideas.generate({
  projectId: "3f0c5a1e-8b2d-4c6e-9a7f-1d2e3f4a5b6c",
});
console.log(result);