PrismDraft SDK

projects

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

Methods

pd.projects.list(input, init?)

List a workspace's projects

GET /api/workspaces/{workspaceId}/projects

Needs projects.read in the workspace. Newest first. Archived projects are left out unless includeArchived=true. A project that has members is listed only to them, and to a caller who holds projects.members.manage in the workspace, who administers it; a project with no members is listed to everyone. A member whose project role does not grant projects.read does not see the project either. An API key has no project membership, so it lists the open projects, and the restricted ones too when its role holds projects.members.manage. A platform administrator reading a workspace they do not belong to sees every project. A project left out of the list answers 403 when opened; one listed only because the caller manages members is likewise refused on read until they are a member, but its members can still be managed.

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.
includeArchived query string no true to list archived projects too (see status on each). Defaults to false: only active projects. Accepts true/false, 1/0, yes/no, on/off.
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
projects object[] yes The workspace's projects, newest first; archived ones only with includeArchived.
projects[].id string (uuid) yes Id of the project, used in every /projects/{projectId} route.
projects[].workspaceId string (uuid) yes Id of the workspace that owns the project.
projects[].name string yes Display name of the project, 1 to 120 characters.
projects[].slug string yes URL-safe identifier, unique within the workspace. Generated from name when not sent at creation, and never changed afterwards.
projects[].description string yes Free-text description of the project, up to 2000 characters; empty when unset.
projects[].settings Record<string, unknown> yes The stored settings object, with the keys exactly as they were sent. The only key the server reads is images (image-generation settings); imageSettings is that key with its defaults filled in.
projects[].websiteUrl string | null yes Address of the website the project writes for; null when none was given.
projects[].iconUrl string | null yes Address of the site's icon, copied to the media host: found by the website analysis, or fetched when websiteUrl is set or changed and by POST .../icon/refresh. null until one is found. No request sets it directly.
projects[].industry string yes Free-text industry of the site, up to 200 characters; empty when unset.
projects[].audience string yes Free-text description of who the articles are written for, up to 500 characters; empty when unset. The app starts a new article's audience from it.
projects[].language string yes The project's default language, a language tag such as en or pt-BR: where a new article starts. Always one of languages.
projects[].languages string[] yes Every language the project publishes in, as language tags, with the default language first. Articles are written in one of these.
projects[].defaultTone string yes Tone a new article starts from, one of professional, conversational, authoritative, practical, persuasive. Each article can change it.
projects[].defaultWordCount integer yes Target length in words a new article starts from, from 200 to 10000. Each article can change it.
projects[].status "active" | "archived" yes active, or archived: read-only until POST /api/workspaces/{workspaceId}/projects/{projectId}/restore makes it active again.
projects[].createdAt string (date-time) yes When the project was created, as an ISO 8601 timestamp.
projects[].updatedAt string (date-time) yes When the project row last changed (an update, an archive or a restore), as an ISO 8601 timestamp.
projects[].imageSettings object yes The project's image-generation settings as generation uses them: settings.images with every default filled in. A stored value that no longer validates reads as the defaults.
projects[].imageSettings.styleDescription string | null yes The project's style description, appended to every image prompt; null when none is set.
projects[].imageSettings.neverDepict string[] yes The subjects no image may show, in force: the project's own list, or the default list (official documents, seals and emblems, flags, identifiable real people) when it has none. Empty when the project excluded nothing.
projects[].imageSettings.hero object yes Cover (hero) image settings, defaults filled in.
projects[].imageSettings.hero.style "photorealistic" | "editorial" | "minimalist-vector" | "3d-render" | "watercolor" | "corporate-tech" | "cinematic" | "illustration" | null yes Style for cover images; null when unset, in which case the article's imageStyle applies. Values: photorealistic (natural-light documentary photograph, realistic textures, no stylisation), editorial (modern editorial illustration or photograph, clean composition, restrained palette), minimalist-vector (flat vector illustration, few shapes, solid colours, plenty of empty space), 3d-render (soft studio 3D render, smooth matte materials, simple forms), watercolor (loose watercolour painting, soft edges, muted washes), corporate-tech (clean technology visual in cool blues and greys, geometric shapes), cinematic (cinematic still, dramatic lighting, strong atmosphere, wide framing), illustration (hand-drawn illustration, confident linework, warm friendly palette).
projects[].imageSettings.hero.aspect "16:9" | "1200x630" yes Shape of cover images: 16:9 or 1200x630 (the social-card size).
projects[].imageSettings.hero.prompt string | null yes Standing direction for cover images; null when none is set.
projects[].imageSettings.inline object yes Inline image settings, defaults filled in.
projects[].imageSettings.inline.style "photorealistic" | "editorial" | "minimalist-vector" | "3d-render" | "watercolor" | "corporate-tech" | "cinematic" | "illustration" | null yes Style for inline images; null when unset, in which case the article's imageStyle applies. Values: photorealistic (natural-light documentary photograph, realistic textures, no stylisation), editorial (modern editorial illustration or photograph, clean composition, restrained palette), minimalist-vector (flat vector illustration, few shapes, solid colours, plenty of empty space), 3d-render (soft studio 3D render, smooth matte materials, simple forms), watercolor (loose watercolour painting, soft edges, muted washes), corporate-tech (clean technology visual in cool blues and greys, geometric shapes), cinematic (cinematic still, dramatic lighting, strong atmosphere, wide framing), illustration (hand-drawn illustration, confident linework, warm friendly palette).
projects[].imageSettings.inline.aspect "4:3" | "1:1" yes Shape of inline images: 4:3 or 1:1.

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

pd.projects.create(input, init?)

Create a project

POST /api/workspaces/{workspaceId}/projects

Needs projects.create. Creates an active project with no members, so it is open to every workspace member who holds the permissions. Counts against the workspace's projects quota: 429 QUOTA_EXCEEDED when the plan's limit is reached. Records a projects.created audit entry and answers 201. With a websiteUrl, queues a fetch of the site's icon.

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 of the project, 1 to 120 characters. Required to create one.
body.slug body string no Wanted URL slug, 1 to 120 characters, normalised to lowercase words joined by hyphens. Taken from name when omitted. When another project of the workspace already has it, a short random suffix is appended. Cannot be changed afterwards, so an update does not accept it.
body.description body string no Free-text description of the project, up to 2000 characters. Empty when omitted on create; unchanged when omitted on update.
body.settings body object no Free-form settings object; any keys are stored as sent. Only images (image-generation settings) is read by the server, and it is validated. On create, omitted means {}. On update the keys sent replace the stored keys of the same name (images is replaced as a whole, not merged field by field) and keys not sent are kept.
body.settings.images body object no The project's image settings. On update this replaces the stored images value as a whole, not field by field: a field left out is unset.
body.settings.images.styleDescription body string no Free-text description of the project's visual identity, up to 400 characters (for example a palette or a mood). It is given to the model that writes each image prompt and appended to the prompt as Style: …. Absent or empty: none.
body.settings.images.neverDepict body string[] no Subjects no generated image may show: up to 20 entries of 1 to 80 characters, at most 600 characters together once joined by , . They are appended to every image prompt as Never depict: …. Absent: the default list (official documents, seals and emblems, flags, identifiable real people). An empty array: nothing is excluded.
body.settings.images.hero body object no Settings for the project's cover (hero) images: style, aspect and a standing prompt. Absent: covers use the article's imageStyle, the 16:9 aspect and no standing prompt.
body.settings.images.hero.style body "photorealistic" | "editorial" | "minimalist-vector" | "3d-render" | "watercolor" | "corporate-tech" | "cinematic" | "illustration" no Style of this project's cover images, replacing the article's imageStyle for covers. Absent: the article's imageStyle applies. Values: photorealistic (natural-light documentary photograph, realistic textures, no stylisation), editorial (modern editorial illustration or photograph, clean composition, restrained palette), minimalist-vector (flat vector illustration, few shapes, solid colours, plenty of empty space), 3d-render (soft studio 3D render, smooth matte materials, simple forms), watercolor (loose watercolour painting, soft edges, muted washes), corporate-tech (clean technology visual in cool blues and greys, geometric shapes), cinematic (cinematic still, dramatic lighting, strong atmosphere, wide framing), illustration (hand-drawn illustration, confident linework, warm friendly palette).
body.settings.images.hero.aspect body "16:9" | "1200x630" no Shape of cover images (default 16:9). 16:9 is a wide banner; 1200x630 is the size social networks show for a shared link. Default: "16:9".
body.settings.images.hero.prompt body string no Standing direction for every cover image, up to 600 characters, given to the model that writes the cover prompt (for example a recurring motif). Absent or empty: none.
body.settings.images.inline body object no Settings for the images placed in the article body.
body.settings.images.inline.style body "photorealistic" | "editorial" | "minimalist-vector" | "3d-render" | "watercolor" | "corporate-tech" | "cinematic" | "illustration" no Style of this project's inline images, replacing the article's imageStyle for them. Absent: the article's imageStyle applies. Values: photorealistic (natural-light documentary photograph, realistic textures, no stylisation), editorial (modern editorial illustration or photograph, clean composition, restrained palette), minimalist-vector (flat vector illustration, few shapes, solid colours, plenty of empty space), 3d-render (soft studio 3D render, smooth matte materials, simple forms), watercolor (loose watercolour painting, soft edges, muted washes), corporate-tech (clean technology visual in cool blues and greys, geometric shapes), cinematic (cinematic still, dramatic lighting, strong atmosphere, wide framing), illustration (hand-drawn illustration, confident linework, warm friendly palette).
body.settings.images.inline.aspect body "4:3" | "1:1" no Shape of inline images (default 4:3): 4:3 landscape or 1:1 square. Default: "4:3".
body.websiteUrl body string (uri) | null no Address of the website the project writes for, an absolute http or https URL of up to 2000 characters, stored as given. A new address must point at a public host: a private, local or unresolvable one answers 400 INVALID_REQUEST. Setting it, on create or to a new address on update, queues a fetch of the site's icon (see iconUrl). null (the default on create) clears it; omitted on update keeps the current value.
body.industry body string no Free-text industry of the site, up to 200 characters. Empty when omitted on create; unchanged when omitted on update.
body.audience body string no Free-text description of who the articles are written for, up to 500 characters. The app starts a new article's audience from it. Empty when omitted on create; unchanged when omitted on update.
body.language body string no Default language of the project, a language tag such as en or pt-BR: where a new article starts. Defaults to en on create. Changing it on update adds the new default to languages when it is not there yet.
body.languages body string[] no Every language the project publishes in, as language tags: 1 to 10 entries. The default language is always added if missing and listed first, and more than 10 languages once it is added answers 400. Defaults to only the default language on create. On update the list replaces the stored one; removing a language that articles of the project are written in answers 409 CONFLICT, with those languages in details.inUse.
body.defaultTone body "professional" | "conversational" | "authoritative" | "practical" | "persuasive" no Tone a new article starts from; each article can change it. professional is the default on create. The values: professional, conversational, authoritative, practical and persuasive.
body.defaultWordCount body integer no Target length in words a new article starts from, from 200 to 10000; each article can change it. Defaults to 1200 on create.
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
project object yes The project, as it is after the request.
project.id string (uuid) yes Id of the project, used in every /projects/{projectId} route.
project.workspaceId string (uuid) yes Id of the workspace that owns the project.
project.name string yes Display name of the project, 1 to 120 characters.
project.slug string yes URL-safe identifier, unique within the workspace. Generated from name when not sent at creation, and never changed afterwards.
project.description string yes Free-text description of the project, up to 2000 characters; empty when unset.
project.settings Record<string, unknown> yes The stored settings object, with the keys exactly as they were sent. The only key the server reads is images (image-generation settings); imageSettings is that key with its defaults filled in.
project.websiteUrl string | null yes Address of the website the project writes for; null when none was given.
project.iconUrl string | null yes Address of the site's icon, copied to the media host: found by the website analysis, or fetched when websiteUrl is set or changed and by POST .../icon/refresh. null until one is found. No request sets it directly.
project.industry string yes Free-text industry of the site, up to 200 characters; empty when unset.
project.audience string yes Free-text description of who the articles are written for, up to 500 characters; empty when unset. The app starts a new article's audience from it.
project.language string yes The project's default language, a language tag such as en or pt-BR: where a new article starts. Always one of languages.
project.languages string[] yes Every language the project publishes in, as language tags, with the default language first. Articles are written in one of these.
project.defaultTone string yes Tone a new article starts from, one of professional, conversational, authoritative, practical, persuasive. Each article can change it.
project.defaultWordCount integer yes Target length in words a new article starts from, from 200 to 10000. Each article can change it.
project.status "active" | "archived" yes active, or archived: read-only until POST /api/workspaces/{workspaceId}/projects/{projectId}/restore makes it active again.
project.createdAt string (date-time) yes When the project was created, as an ISO 8601 timestamp.
project.updatedAt string (date-time) yes When the project row last changed (an update, an archive or a restore), as an ISO 8601 timestamp.
project.imageSettings object yes The project's image-generation settings as generation uses them: settings.images with every default filled in. A stored value that no longer validates reads as the defaults.
project.imageSettings.styleDescription string | null yes The project's style description, appended to every image prompt; null when none is set.
project.imageSettings.neverDepict string[] yes The subjects no image may show, in force: the project's own list, or the default list (official documents, seals and emblems, flags, identifiable real people) when it has none. Empty when the project excluded nothing.
project.imageSettings.hero object yes Cover (hero) image settings, defaults filled in.
project.imageSettings.hero.style "photorealistic" | "editorial" | "minimalist-vector" | "3d-render" | "watercolor" | "corporate-tech" | "cinematic" | "illustration" | null yes Style for cover images; null when unset, in which case the article's imageStyle applies. Values: photorealistic (natural-light documentary photograph, realistic textures, no stylisation), editorial (modern editorial illustration or photograph, clean composition, restrained palette), minimalist-vector (flat vector illustration, few shapes, solid colours, plenty of empty space), 3d-render (soft studio 3D render, smooth matte materials, simple forms), watercolor (loose watercolour painting, soft edges, muted washes), corporate-tech (clean technology visual in cool blues and greys, geometric shapes), cinematic (cinematic still, dramatic lighting, strong atmosphere, wide framing), illustration (hand-drawn illustration, confident linework, warm friendly palette).
project.imageSettings.hero.aspect "16:9" | "1200x630" yes Shape of cover images: 16:9 or 1200x630 (the social-card size).
project.imageSettings.hero.prompt string | null yes Standing direction for cover images; null when none is set.
project.imageSettings.inline object yes Inline image settings, defaults filled in.
project.imageSettings.inline.style "photorealistic" | "editorial" | "minimalist-vector" | "3d-render" | "watercolor" | "corporate-tech" | "cinematic" | "illustration" | null yes Style for inline images; null when unset, in which case the article's imageStyle applies. Values: photorealistic (natural-light documentary photograph, realistic textures, no stylisation), editorial (modern editorial illustration or photograph, clean composition, restrained palette), minimalist-vector (flat vector illustration, few shapes, solid colours, plenty of empty space), 3d-render (soft studio 3D render, smooth matte materials, simple forms), watercolor (loose watercolour painting, soft edges, muted washes), corporate-tech (clean technology visual in cool blues and greys, geometric shapes), cinematic (cinematic still, dramatic lighting, strong atmosphere, wide framing), illustration (hand-drawn illustration, confident linework, warm friendly palette).
project.imageSettings.inline.aspect "4:3" | "1:1" yes Shape of inline images: 4:3 or 1:1.

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

pd.projects.get(input, init?)

Read a project

GET /api/workspaces/{workspaceId}/projects/{projectId}

Needs projects.read on the project: 404 when it is not in the workspace, 403 when it has members and the caller is not one. Carries the stored settings and imageSettings, the same with its defaults filled in. Works on archived projects.

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 path string (uuid) yes Id of a project of workspaceId. A project of another workspace answers 404 RESOURCE_NOT_FOUND, as if it did not exist. When the project has members, a workspace member who is not one of them answers 403 FORBIDDEN, and a project role can only narrow the permissions the member's workspace roles grant.
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
project object yes The project, as it is after the request.
project.id string (uuid) yes Id of the project, used in every /projects/{projectId} route.
project.workspaceId string (uuid) yes Id of the workspace that owns the project.
project.name string yes Display name of the project, 1 to 120 characters.
project.slug string yes URL-safe identifier, unique within the workspace. Generated from name when not sent at creation, and never changed afterwards.
project.description string yes Free-text description of the project, up to 2000 characters; empty when unset.
project.settings Record<string, unknown> yes The stored settings object, with the keys exactly as they were sent. The only key the server reads is images (image-generation settings); imageSettings is that key with its defaults filled in.
project.websiteUrl string | null yes Address of the website the project writes for; null when none was given.
project.iconUrl string | null yes Address of the site's icon, copied to the media host: found by the website analysis, or fetched when websiteUrl is set or changed and by POST .../icon/refresh. null until one is found. No request sets it directly.
project.industry string yes Free-text industry of the site, up to 200 characters; empty when unset.
project.audience string yes Free-text description of who the articles are written for, up to 500 characters; empty when unset. The app starts a new article's audience from it.
project.language string yes The project's default language, a language tag such as en or pt-BR: where a new article starts. Always one of languages.
project.languages string[] yes Every language the project publishes in, as language tags, with the default language first. Articles are written in one of these.
project.defaultTone string yes Tone a new article starts from, one of professional, conversational, authoritative, practical, persuasive. Each article can change it.
project.defaultWordCount integer yes Target length in words a new article starts from, from 200 to 10000. Each article can change it.
project.status "active" | "archived" yes active, or archived: read-only until POST /api/workspaces/{workspaceId}/projects/{projectId}/restore makes it active again.
project.createdAt string (date-time) yes When the project was created, as an ISO 8601 timestamp.
project.updatedAt string (date-time) yes When the project row last changed (an update, an archive or a restore), as an ISO 8601 timestamp.
project.imageSettings object yes The project's image-generation settings as generation uses them: settings.images with every default filled in. A stored value that no longer validates reads as the defaults.
project.imageSettings.styleDescription string | null yes The project's style description, appended to every image prompt; null when none is set.
project.imageSettings.neverDepict string[] yes The subjects no image may show, in force: the project's own list, or the default list (official documents, seals and emblems, flags, identifiable real people) when it has none. Empty when the project excluded nothing.
project.imageSettings.hero object yes Cover (hero) image settings, defaults filled in.
project.imageSettings.hero.style "photorealistic" | "editorial" | "minimalist-vector" | "3d-render" | "watercolor" | "corporate-tech" | "cinematic" | "illustration" | null yes Style for cover images; null when unset, in which case the article's imageStyle applies. Values: photorealistic (natural-light documentary photograph, realistic textures, no stylisation), editorial (modern editorial illustration or photograph, clean composition, restrained palette), minimalist-vector (flat vector illustration, few shapes, solid colours, plenty of empty space), 3d-render (soft studio 3D render, smooth matte materials, simple forms), watercolor (loose watercolour painting, soft edges, muted washes), corporate-tech (clean technology visual in cool blues and greys, geometric shapes), cinematic (cinematic still, dramatic lighting, strong atmosphere, wide framing), illustration (hand-drawn illustration, confident linework, warm friendly palette).
project.imageSettings.hero.aspect "16:9" | "1200x630" yes Shape of cover images: 16:9 or 1200x630 (the social-card size).
project.imageSettings.hero.prompt string | null yes Standing direction for cover images; null when none is set.
project.imageSettings.inline object yes Inline image settings, defaults filled in.
project.imageSettings.inline.style "photorealistic" | "editorial" | "minimalist-vector" | "3d-render" | "watercolor" | "corporate-tech" | "cinematic" | "illustration" | null yes Style for inline images; null when unset, in which case the article's imageStyle applies. Values: photorealistic (natural-light documentary photograph, realistic textures, no stylisation), editorial (modern editorial illustration or photograph, clean composition, restrained palette), minimalist-vector (flat vector illustration, few shapes, solid colours, plenty of empty space), 3d-render (soft studio 3D render, smooth matte materials, simple forms), watercolor (loose watercolour painting, soft edges, muted washes), corporate-tech (clean technology visual in cool blues and greys, geometric shapes), cinematic (cinematic still, dramatic lighting, strong atmosphere, wide framing), illustration (hand-drawn illustration, confident linework, warm friendly palette).
project.imageSettings.inline.aspect "4:3" | "1:1" yes Shape of inline images: 4:3 or 1:1.

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

pd.projects.update(input, init?)

Update a project

PATCH /api/workspaces/{workspaceId}/projects/{projectId}

Needs projects.update on the project. Only the fields sent change; slug cannot be changed. settings sets the keys it carries and keeps the others. settings.images configures image generation (style description, never-depict list, hero and inline aspect and style); the response's imageSettings is that with the defaults filled in. Removing a language that articles are written in answers 409 CONFLICT with those languages in details.inUse, unless deleteArticlesInRemovedLanguages is true. Allowed on an archived project too. Records a projects.updated audit entry listing the fields sent. Setting websiteUrl to a new address queues a fetch of the site's icon.

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 path string (uuid) yes Id of a project of workspaceId. A project of another workspace answers 404 RESOURCE_NOT_FOUND, as if it did not exist. When the project has members, a workspace member who is not one of them answers 403 FORBIDDEN, and a project role can only narrow the permissions the member's workspace roles grant.
body body object no
body.name body string no Display name of the project, 1 to 120 characters. Required to create one.
body.description body string no Free-text description of the project, up to 2000 characters. Empty when omitted on create; unchanged when omitted on update.
body.settings body object no Free-form settings object; any keys are stored as sent. Only images (image-generation settings) is read by the server, and it is validated. On create, omitted means {}. On update the keys sent replace the stored keys of the same name (images is replaced as a whole, not merged field by field) and keys not sent are kept.
body.settings.images body object no The project's image settings. On update this replaces the stored images value as a whole, not field by field: a field left out is unset.
body.settings.images.styleDescription body string no Free-text description of the project's visual identity, up to 400 characters (for example a palette or a mood). It is given to the model that writes each image prompt and appended to the prompt as Style: …. Absent or empty: none.
body.settings.images.neverDepict body string[] no Subjects no generated image may show: up to 20 entries of 1 to 80 characters, at most 600 characters together once joined by , . They are appended to every image prompt as Never depict: …. Absent: the default list (official documents, seals and emblems, flags, identifiable real people). An empty array: nothing is excluded.
body.settings.images.hero body object no Settings for the project's cover (hero) images: style, aspect and a standing prompt. Absent: covers use the article's imageStyle, the 16:9 aspect and no standing prompt.
body.settings.images.hero.style body "photorealistic" | "editorial" | "minimalist-vector" | "3d-render" | "watercolor" | "corporate-tech" | "cinematic" | "illustration" no Style of this project's cover images, replacing the article's imageStyle for covers. Absent: the article's imageStyle applies. Values: photorealistic (natural-light documentary photograph, realistic textures, no stylisation), editorial (modern editorial illustration or photograph, clean composition, restrained palette), minimalist-vector (flat vector illustration, few shapes, solid colours, plenty of empty space), 3d-render (soft studio 3D render, smooth matte materials, simple forms), watercolor (loose watercolour painting, soft edges, muted washes), corporate-tech (clean technology visual in cool blues and greys, geometric shapes), cinematic (cinematic still, dramatic lighting, strong atmosphere, wide framing), illustration (hand-drawn illustration, confident linework, warm friendly palette).
body.settings.images.hero.aspect body "16:9" | "1200x630" no Shape of cover images (default 16:9). 16:9 is a wide banner; 1200x630 is the size social networks show for a shared link. Default: "16:9".
body.settings.images.hero.prompt body string no Standing direction for every cover image, up to 600 characters, given to the model that writes the cover prompt (for example a recurring motif). Absent or empty: none.
body.settings.images.inline body object no Settings for the images placed in the article body.
body.settings.images.inline.style body "photorealistic" | "editorial" | "minimalist-vector" | "3d-render" | "watercolor" | "corporate-tech" | "cinematic" | "illustration" no Style of this project's inline images, replacing the article's imageStyle for them. Absent: the article's imageStyle applies. Values: photorealistic (natural-light documentary photograph, realistic textures, no stylisation), editorial (modern editorial illustration or photograph, clean composition, restrained palette), minimalist-vector (flat vector illustration, few shapes, solid colours, plenty of empty space), 3d-render (soft studio 3D render, smooth matte materials, simple forms), watercolor (loose watercolour painting, soft edges, muted washes), corporate-tech (clean technology visual in cool blues and greys, geometric shapes), cinematic (cinematic still, dramatic lighting, strong atmosphere, wide framing), illustration (hand-drawn illustration, confident linework, warm friendly palette).
body.settings.images.inline.aspect body "4:3" | "1:1" no Shape of inline images (default 4:3): 4:3 landscape or 1:1 square. Default: "4:3".
body.websiteUrl body string (uri) | null no Address of the website the project writes for, an absolute http or https URL of up to 2000 characters, stored as given. A new address must point at a public host: a private, local or unresolvable one answers 400 INVALID_REQUEST. Setting it, on create or to a new address on update, queues a fetch of the site's icon (see iconUrl). null (the default on create) clears it; omitted on update keeps the current value.
body.industry body string no Free-text industry of the site, up to 200 characters. Empty when omitted on create; unchanged when omitted on update.
body.audience body string no Free-text description of who the articles are written for, up to 500 characters. The app starts a new article's audience from it. Empty when omitted on create; unchanged when omitted on update.
body.language body string no Default language of the project, a language tag such as en or pt-BR: where a new article starts. Defaults to en on create. Changing it on update adds the new default to languages when it is not there yet.
body.languages body string[] no Every language the project publishes in, as language tags: 1 to 10 entries. The default language is always added if missing and listed first, and more than 10 languages once it is added answers 400. Defaults to only the default language on create. On update the list replaces the stored one; removing a language that articles of the project are written in answers 409 CONFLICT, with those languages in details.inUse.
body.defaultTone body "professional" | "conversational" | "authoritative" | "practical" | "persuasive" no Tone a new article starts from; each article can change it. professional is the default on create. The values: professional, conversational, authoritative, practical and persuasive.
body.defaultWordCount body integer no Target length in words a new article starts from, from 200 to 10000; each article can change it. Defaults to 1200 on create.
body.deleteArticlesInRemovedLanguages body boolean no With languages (or a new default language) that drops languages the project has articles in: permanently delete those articles in the same transaction instead of answering 409. Needs articles.delete on the project as well as projects.update. Published articles send article.unpublished (reason: "deleted"); each deleted article writes an articles.deleted audit entry. Default false: the 409 stands.
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
project object yes The project, as it is after the request.
project.id string (uuid) yes Id of the project, used in every /projects/{projectId} route.
project.workspaceId string (uuid) yes Id of the workspace that owns the project.
project.name string yes Display name of the project, 1 to 120 characters.
project.slug string yes URL-safe identifier, unique within the workspace. Generated from name when not sent at creation, and never changed afterwards.
project.description string yes Free-text description of the project, up to 2000 characters; empty when unset.
project.settings Record<string, unknown> yes The stored settings object, with the keys exactly as they were sent. The only key the server reads is images (image-generation settings); imageSettings is that key with its defaults filled in.
project.websiteUrl string | null yes Address of the website the project writes for; null when none was given.
project.iconUrl string | null yes Address of the site's icon, copied to the media host: found by the website analysis, or fetched when websiteUrl is set or changed and by POST .../icon/refresh. null until one is found. No request sets it directly.
project.industry string yes Free-text industry of the site, up to 200 characters; empty when unset.
project.audience string yes Free-text description of who the articles are written for, up to 500 characters; empty when unset. The app starts a new article's audience from it.
project.language string yes The project's default language, a language tag such as en or pt-BR: where a new article starts. Always one of languages.
project.languages string[] yes Every language the project publishes in, as language tags, with the default language first. Articles are written in one of these.
project.defaultTone string yes Tone a new article starts from, one of professional, conversational, authoritative, practical, persuasive. Each article can change it.
project.defaultWordCount integer yes Target length in words a new article starts from, from 200 to 10000. Each article can change it.
project.status "active" | "archived" yes active, or archived: read-only until POST /api/workspaces/{workspaceId}/projects/{projectId}/restore makes it active again.
project.createdAt string (date-time) yes When the project was created, as an ISO 8601 timestamp.
project.updatedAt string (date-time) yes When the project row last changed (an update, an archive or a restore), as an ISO 8601 timestamp.
project.imageSettings object yes The project's image-generation settings as generation uses them: settings.images with every default filled in. A stored value that no longer validates reads as the defaults.
project.imageSettings.styleDescription string | null yes The project's style description, appended to every image prompt; null when none is set.
project.imageSettings.neverDepict string[] yes The subjects no image may show, in force: the project's own list, or the default list (official documents, seals and emblems, flags, identifiable real people) when it has none. Empty when the project excluded nothing.
project.imageSettings.hero object yes Cover (hero) image settings, defaults filled in.
project.imageSettings.hero.style "photorealistic" | "editorial" | "minimalist-vector" | "3d-render" | "watercolor" | "corporate-tech" | "cinematic" | "illustration" | null yes Style for cover images; null when unset, in which case the article's imageStyle applies. Values: photorealistic (natural-light documentary photograph, realistic textures, no stylisation), editorial (modern editorial illustration or photograph, clean composition, restrained palette), minimalist-vector (flat vector illustration, few shapes, solid colours, plenty of empty space), 3d-render (soft studio 3D render, smooth matte materials, simple forms), watercolor (loose watercolour painting, soft edges, muted washes), corporate-tech (clean technology visual in cool blues and greys, geometric shapes), cinematic (cinematic still, dramatic lighting, strong atmosphere, wide framing), illustration (hand-drawn illustration, confident linework, warm friendly palette).
project.imageSettings.hero.aspect "16:9" | "1200x630" yes Shape of cover images: 16:9 or 1200x630 (the social-card size).
project.imageSettings.hero.prompt string | null yes Standing direction for cover images; null when none is set.
project.imageSettings.inline object yes Inline image settings, defaults filled in.
project.imageSettings.inline.style "photorealistic" | "editorial" | "minimalist-vector" | "3d-render" | "watercolor" | "corporate-tech" | "cinematic" | "illustration" | null yes Style for inline images; null when unset, in which case the article's imageStyle applies. Values: photorealistic (natural-light documentary photograph, realistic textures, no stylisation), editorial (modern editorial illustration or photograph, clean composition, restrained palette), minimalist-vector (flat vector illustration, few shapes, solid colours, plenty of empty space), 3d-render (soft studio 3D render, smooth matte materials, simple forms), watercolor (loose watercolour painting, soft edges, muted washes), corporate-tech (clean technology visual in cool blues and greys, geometric shapes), cinematic (cinematic still, dramatic lighting, strong atmosphere, wide framing), illustration (hand-drawn illustration, confident linework, warm friendly palette).
project.imageSettings.inline.aspect "4:3" | "1:1" yes Shape of inline images: 4:3 or 1:1.

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

pd.projects.delete(input, init?)

Delete a project

DELETE /api/workspaces/{workspaceId}/projects/{projectId}

Needs projects.delete. Permanently deletes the project and the content that belongs to it, including its articles. It cannot be undone; archive the project to keep the content. Works on archived projects. Records a projects.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.
projectId path string (uuid) yes Id of a project of workspaceId. A project of another workspace answers 404 RESOURCE_NOT_FOUND, as if it did not exist. When the project has members, a workspace member who is not one of them answers 403 FORBIDDEN, and a project role can only narrow the permissions the member's workspace roles grant.
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 project or the membership was deleted.

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

pd.projects.archive(input, init?)

Archive a project

POST /api/workspaces/{workspaceId}/projects/{projectId}/archive

Needs projects.update. Makes the project read-only: every other write in it (articles, images, generation, members) answers 409 CONFLICT until it is restored, while reads and exports keep working. Updating and deleting the project itself stay allowed. 409 CONFLICT when it is already archived. Records a projects.archived 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.
projectId path string (uuid) yes Id of a project of workspaceId. A project of another workspace answers 404 RESOURCE_NOT_FOUND, as if it did not exist. When the project has members, a workspace member who is not one of them answers 403 FORBIDDEN, and a project role can only narrow the permissions the member's workspace roles grant.
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
project object yes The project, as it is after the request.
project.id string (uuid) yes Id of the project, used in every /projects/{projectId} route.
project.workspaceId string (uuid) yes Id of the workspace that owns the project.
project.name string yes Display name of the project, 1 to 120 characters.
project.slug string yes URL-safe identifier, unique within the workspace. Generated from name when not sent at creation, and never changed afterwards.
project.description string yes Free-text description of the project, up to 2000 characters; empty when unset.
project.settings Record<string, unknown> yes The stored settings object, with the keys exactly as they were sent. The only key the server reads is images (image-generation settings); imageSettings is that key with its defaults filled in.
project.websiteUrl string | null yes Address of the website the project writes for; null when none was given.
project.iconUrl string | null yes Address of the site's icon, copied to the media host: found by the website analysis, or fetched when websiteUrl is set or changed and by POST .../icon/refresh. null until one is found. No request sets it directly.
project.industry string yes Free-text industry of the site, up to 200 characters; empty when unset.
project.audience string yes Free-text description of who the articles are written for, up to 500 characters; empty when unset. The app starts a new article's audience from it.
project.language string yes The project's default language, a language tag such as en or pt-BR: where a new article starts. Always one of languages.
project.languages string[] yes Every language the project publishes in, as language tags, with the default language first. Articles are written in one of these.
project.defaultTone string yes Tone a new article starts from, one of professional, conversational, authoritative, practical, persuasive. Each article can change it.
project.defaultWordCount integer yes Target length in words a new article starts from, from 200 to 10000. Each article can change it.
project.status "active" | "archived" yes active, or archived: read-only until POST /api/workspaces/{workspaceId}/projects/{projectId}/restore makes it active again.
project.createdAt string (date-time) yes When the project was created, as an ISO 8601 timestamp.
project.updatedAt string (date-time) yes When the project row last changed (an update, an archive or a restore), as an ISO 8601 timestamp.
project.imageSettings object yes The project's image-generation settings as generation uses them: settings.images with every default filled in. A stored value that no longer validates reads as the defaults.
project.imageSettings.styleDescription string | null yes The project's style description, appended to every image prompt; null when none is set.
project.imageSettings.neverDepict string[] yes The subjects no image may show, in force: the project's own list, or the default list (official documents, seals and emblems, flags, identifiable real people) when it has none. Empty when the project excluded nothing.
project.imageSettings.hero object yes Cover (hero) image settings, defaults filled in.
project.imageSettings.hero.style "photorealistic" | "editorial" | "minimalist-vector" | "3d-render" | "watercolor" | "corporate-tech" | "cinematic" | "illustration" | null yes Style for cover images; null when unset, in which case the article's imageStyle applies. Values: photorealistic (natural-light documentary photograph, realistic textures, no stylisation), editorial (modern editorial illustration or photograph, clean composition, restrained palette), minimalist-vector (flat vector illustration, few shapes, solid colours, plenty of empty space), 3d-render (soft studio 3D render, smooth matte materials, simple forms), watercolor (loose watercolour painting, soft edges, muted washes), corporate-tech (clean technology visual in cool blues and greys, geometric shapes), cinematic (cinematic still, dramatic lighting, strong atmosphere, wide framing), illustration (hand-drawn illustration, confident linework, warm friendly palette).
project.imageSettings.hero.aspect "16:9" | "1200x630" yes Shape of cover images: 16:9 or 1200x630 (the social-card size).
project.imageSettings.hero.prompt string | null yes Standing direction for cover images; null when none is set.
project.imageSettings.inline object yes Inline image settings, defaults filled in.
project.imageSettings.inline.style "photorealistic" | "editorial" | "minimalist-vector" | "3d-render" | "watercolor" | "corporate-tech" | "cinematic" | "illustration" | null yes Style for inline images; null when unset, in which case the article's imageStyle applies. Values: photorealistic (natural-light documentary photograph, realistic textures, no stylisation), editorial (modern editorial illustration or photograph, clean composition, restrained palette), minimalist-vector (flat vector illustration, few shapes, solid colours, plenty of empty space), 3d-render (soft studio 3D render, smooth matte materials, simple forms), watercolor (loose watercolour painting, soft edges, muted washes), corporate-tech (clean technology visual in cool blues and greys, geometric shapes), cinematic (cinematic still, dramatic lighting, strong atmosphere, wide framing), illustration (hand-drawn illustration, confident linework, warm friendly palette).
project.imageSettings.inline.aspect "4:3" | "1:1" yes Shape of inline images: 4:3 or 1:1.

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

pd.projects.restore(input, init?)

Restore an archived project

POST /api/workspaces/{workspaceId}/projects/{projectId}/restore

Needs projects.update; one of the few writes an archived project accepts. Makes the project active again, with its content as it was. 409 CONFLICT when the project is not archived. Records a projects.restored 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.
projectId path string (uuid) yes Id of a project of workspaceId. A project of another workspace answers 404 RESOURCE_NOT_FOUND, as if it did not exist. When the project has members, a workspace member who is not one of them answers 403 FORBIDDEN, and a project role can only narrow the permissions the member's workspace roles grant.
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
project object yes The project, as it is after the request.
project.id string (uuid) yes Id of the project, used in every /projects/{projectId} route.
project.workspaceId string (uuid) yes Id of the workspace that owns the project.
project.name string yes Display name of the project, 1 to 120 characters.
project.slug string yes URL-safe identifier, unique within the workspace. Generated from name when not sent at creation, and never changed afterwards.
project.description string yes Free-text description of the project, up to 2000 characters; empty when unset.
project.settings Record<string, unknown> yes The stored settings object, with the keys exactly as they were sent. The only key the server reads is images (image-generation settings); imageSettings is that key with its defaults filled in.
project.websiteUrl string | null yes Address of the website the project writes for; null when none was given.
project.iconUrl string | null yes Address of the site's icon, copied to the media host: found by the website analysis, or fetched when websiteUrl is set or changed and by POST .../icon/refresh. null until one is found. No request sets it directly.
project.industry string yes Free-text industry of the site, up to 200 characters; empty when unset.
project.audience string yes Free-text description of who the articles are written for, up to 500 characters; empty when unset. The app starts a new article's audience from it.
project.language string yes The project's default language, a language tag such as en or pt-BR: where a new article starts. Always one of languages.
project.languages string[] yes Every language the project publishes in, as language tags, with the default language first. Articles are written in one of these.
project.defaultTone string yes Tone a new article starts from, one of professional, conversational, authoritative, practical, persuasive. Each article can change it.
project.defaultWordCount integer yes Target length in words a new article starts from, from 200 to 10000. Each article can change it.
project.status "active" | "archived" yes active, or archived: read-only until POST /api/workspaces/{workspaceId}/projects/{projectId}/restore makes it active again.
project.createdAt string (date-time) yes When the project was created, as an ISO 8601 timestamp.
project.updatedAt string (date-time) yes When the project row last changed (an update, an archive or a restore), as an ISO 8601 timestamp.
project.imageSettings object yes The project's image-generation settings as generation uses them: settings.images with every default filled in. A stored value that no longer validates reads as the defaults.
project.imageSettings.styleDescription string | null yes The project's style description, appended to every image prompt; null when none is set.
project.imageSettings.neverDepict string[] yes The subjects no image may show, in force: the project's own list, or the default list (official documents, seals and emblems, flags, identifiable real people) when it has none. Empty when the project excluded nothing.
project.imageSettings.hero object yes Cover (hero) image settings, defaults filled in.
project.imageSettings.hero.style "photorealistic" | "editorial" | "minimalist-vector" | "3d-render" | "watercolor" | "corporate-tech" | "cinematic" | "illustration" | null yes Style for cover images; null when unset, in which case the article's imageStyle applies. Values: photorealistic (natural-light documentary photograph, realistic textures, no stylisation), editorial (modern editorial illustration or photograph, clean composition, restrained palette), minimalist-vector (flat vector illustration, few shapes, solid colours, plenty of empty space), 3d-render (soft studio 3D render, smooth matte materials, simple forms), watercolor (loose watercolour painting, soft edges, muted washes), corporate-tech (clean technology visual in cool blues and greys, geometric shapes), cinematic (cinematic still, dramatic lighting, strong atmosphere, wide framing), illustration (hand-drawn illustration, confident linework, warm friendly palette).
project.imageSettings.hero.aspect "16:9" | "1200x630" yes Shape of cover images: 16:9 or 1200x630 (the social-card size).
project.imageSettings.hero.prompt string | null yes Standing direction for cover images; null when none is set.
project.imageSettings.inline object yes Inline image settings, defaults filled in.
project.imageSettings.inline.style "photorealistic" | "editorial" | "minimalist-vector" | "3d-render" | "watercolor" | "corporate-tech" | "cinematic" | "illustration" | null yes Style for inline images; null when unset, in which case the article's imageStyle applies. Values: photorealistic (natural-light documentary photograph, realistic textures, no stylisation), editorial (modern editorial illustration or photograph, clean composition, restrained palette), minimalist-vector (flat vector illustration, few shapes, solid colours, plenty of empty space), 3d-render (soft studio 3D render, smooth matte materials, simple forms), watercolor (loose watercolour painting, soft edges, muted washes), corporate-tech (clean technology visual in cool blues and greys, geometric shapes), cinematic (cinematic still, dramatic lighting, strong atmosphere, wide framing), illustration (hand-drawn illustration, confident linework, warm friendly palette).
project.imageSettings.inline.aspect "4:3" | "1:1" yes Shape of inline images: 4:3 or 1:1.

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

pd.projects.refreshIcon(input, init?)

Refetch a project's website icon

POST /api/workspaces/{workspaceId}/projects/{projectId}/icon/refresh

Needs projects.update on the project. Queues a fetch of the icon of the project's websiteUrl and answers 202 at once. When the fetch finds a readable icon (PNG, ICO, JPEG, GIF or WebP; SVG is never used), the project's iconUrl changes to a new address; when it finds none, the current icon stays. 409 CONFLICT when the project has no websiteUrl. A request made while a fetch for the project is waiting or running joins it rather than queueing a second. Allowed on an archived project, as updating it is. Records a projects.icon_refreshed 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.
projectId path string (uuid) yes Id of a project of workspaceId. A project of another workspace answers 404 RESOURCE_NOT_FOUND, as if it did not exist. When the project has members, a workspace member who is not one of them answers 403 FORBIDDEN, and a project role can only narrow the permissions the member's workspace roles grant.
init init { signal?: AbortSignal; timeoutMs?: number } no The second argument: signal aborts the call, timeoutMs overrides the client's per-attempt timeout.

Returns 202 Accepted

Field Type Required Description
queued true yes Always true: the fetch is queued. When it finds an icon, the project's iconUrl changes to a new address; when it finds none, the current icon stays.

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

pd.projects.listMembers(input, init?)

List a project's members

GET /api/workspaces/{workspaceId}/projects/{projectId}/members

Needs projects.read on the project. A project with no members is open to every workspace member; once it has any, only its members (and holders of projects.members.manage, for administration only) can open 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 path string (uuid) yes Id of a project of workspaceId. A project of another workspace answers 404 RESOURCE_NOT_FOUND, as if it did not exist. When the project has members, a workspace member who is not one of them answers 403 FORBIDDEN, and a project role can only narrow the permissions the member's workspace roles grant.
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
members object[] yes The project's members. Empty means the project is open to every workspace member.
members[].id string (uuid) yes Id of this project membership (projectMemberId), used to change or remove it. Not the workspace membership id.
members[].workspaceMemberId string (uuid) yes Id of the member's workspace membership: memberId in GET .../members.
members[].userId string yes Id of the member's user account.
members[].name string yes The member's display name.
members[].email string yes The member's email address.
members[].roleId string (uuid) | null yes Id of the workspace role the member holds in this project, which narrows what they can do here to the permissions both that role and their workspace roles grant. null means no narrowing: their workspace roles apply unchanged.
members[].roleName string | null yes Name of the role roleId points to; null when roleId is null.

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

pd.projects.addMember(input, init?)

Add a member to a project

POST /api/workspaces/{workspaceId}/projects/{projectId}/members

Needs projects.members.manage, which does not require being on the project. Adding the first member makes an open project restricted: from then on only its members can open it, so add yourself if you still need access. The member must belong to the workspace and roleId, when given, to the same workspace (400 INVALID_REQUEST); a member already on the project answers 409 CONFLICT, as does an archived project. Records a projects.members_changed audit entry and 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.
projectId path string (uuid) yes Id of a project of workspaceId. A project of another workspace answers 404 RESOURCE_NOT_FOUND, as if it did not exist. When the project has members, a workspace member who is not one of them answers 403 FORBIDDEN, and a project role can only narrow the permissions the member's workspace roles grant.
body body object yes
body.workspaceMemberId body string (uuid) yes Id of the workspace membership to add (memberId in GET /api/workspaces/{workspaceId}/members). It must belong to the project's workspace, else 400 INVALID_REQUEST; already being on the project answers 409 CONFLICT.
body.roleId body string (uuid) | null no Id of a role of the workspace (GET /api/workspaces/{workspaceId}/roles) that narrows what the member can do in this project to the permissions both it and their workspace roles grant. Omitted or null: no narrowing. A role of another workspace answers 400 INVALID_REQUEST.
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
projectMemberId string (uuid) yes Id of the new project membership, as id in GET .../members.

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

pd.projects.setMemberRole(input, init?)

Change a project member's role

PATCH /api/workspaces/{workspaceId}/projects/{projectId}/members/{projectMemberId}

Needs projects.members.manage. Replaces the member's project role in one update; null falls back to their workspace roles. 404 RESOURCE_NOT_FOUND when the member is not on the project, 409 CONFLICT when the project is archived. Records a projects.members_changed audit entry with the previous and new role.

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 path string (uuid) yes Id of a project of workspaceId. A project of another workspace answers 404 RESOURCE_NOT_FOUND, as if it did not exist. When the project has members, a workspace member who is not one of them answers 403 FORBIDDEN, and a project role can only narrow the permissions the member's workspace roles grant.
projectMemberId path string (uuid) yes Id of a membership of this project, as id in GET .../members (not the workspace membership id). A membership of another project answers 404 RESOURCE_NOT_FOUND.
body body object yes
body.roleId body string (uuid) | null yes Id of the workspace role that becomes the member's project role, replacing the current one, or null to remove it so their workspace roles apply unchanged. Required: sending nothing is a 400, not a no-op. A role of another workspace answers 400 INVALID_REQUEST.
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
member object yes The membership after the change.
member.id string (uuid) yes Id of this project membership (projectMemberId), used to change or remove it. Not the workspace membership id.
member.workspaceMemberId string (uuid) yes Id of the member's workspace membership: memberId in GET .../members.
member.userId string yes Id of the member's user account.
member.name string yes The member's display name.
member.email string yes The member's email address.
member.roleId string (uuid) | null yes Id of the workspace role the member holds in this project, which narrows what they can do here to the permissions both that role and their workspace roles grant. null means no narrowing: their workspace roles apply unchanged.
member.roleName string | null yes Name of the role roleId points to; null when roleId is null.

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.projects.setMemberRole({
  workspaceId: "3f0c5a1e-8b2d-4c6e-9a7f-1d2e3f4a5b6c",
  projectId: "3f0c5a1e-8b2d-4c6e-9a7f-1d2e3f4a5b6c",
  projectMemberId: "3f0c5a1e-8b2d-4c6e-9a7f-1d2e3f4a5b6c",
  body: {
    roleId: "3f0c5a1e-8b2d-4c6e-9a7f-1d2e3f4a5b6c",
  },
});
console.log(result);

pd.projects.removeMember(input, init?)

Remove a member from a project

DELETE /api/workspaces/{workspaceId}/projects/{projectId}/members/{projectMemberId}

Needs projects.members.manage. Removing the last member makes the project open to every workspace member again. 404 RESOURCE_NOT_FOUND when the membership is not on the project, 409 CONFLICT when the project is archived. Records a projects.members_changed 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.
projectId path string (uuid) yes Id of a project of workspaceId. A project of another workspace answers 404 RESOURCE_NOT_FOUND, as if it did not exist. When the project has members, a workspace member who is not one of them answers 403 FORBIDDEN, and a project role can only narrow the permissions the member's workspace roles grant.
projectMemberId path string (uuid) yes Id of a membership of this project, as id in GET .../members (not the workspace membership id). A membership of another project answers 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 200 OK

Field Type Required Description
ok true yes Always true: the project or the membership was deleted.

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

pd.projects.detectImageStyle(input, init?)

Detect the project's image style from its website

POST /api/workspaces/{workspaceId}/projects/{projectId}/image-style/detect

Needs projects.update on the project. Starts a detect run and answers 202 with it: the service reads the homepage and up to 3 article pages, takes up to 8 of their images (cover images first), and has a vision model name the closest preset and describe the style. The website must be set: without websiteUrl the answer is 409 CONFLICT. A site with fewer than 2 readable images of at least 200 × 200 ends failed. A run already queued or running of the same kind for this project is answered instead of a new one. A workspace may start 10 runs in any 24 hours, detections and proposals together (the detection onboarding starts on its own is outside the cap); past that the answer is 429 RATE_LIMITED with Retry-After (seconds until the oldest run of the window is 24 hours old) and details { retryAfterSeconds, limit, used }. Runs cost no credits. Follow the run with GET .../image-style/runs/latest until it is succeeded or failed, then apply a suggestion with POST .../image-style/apply.

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 path string (uuid) yes Id of a project of workspaceId. A project of another workspace answers 404 RESOURCE_NOT_FOUND, as if it did not exist. When the project has members, a workspace member who is not one of them answers 403 FORBIDDEN, and a project role can only narrow the permissions the member's workspace roles grant.
init init { signal?: AbortSignal; timeoutMs?: number } no The second argument: signal aborts the call, timeoutMs overrides the client's per-attempt timeout.

Returns 202 Accepted

Field Type Required Description
run object yes The run: a new one, queued, or the one of the same kind still running for this project.
run.id string (uuid) yes Id of the run, the runId that applyImageStyle takes.
run.workspaceId string (uuid) yes Id of the workspace that owns the project.
run.projectId string (uuid) yes Id of the project the run is for.
run.kind "detect" | "propose" yes detect: read the style of the website's images. propose: three alternatives that suit the site.
run.status "queued" | "running" | "succeeded" | "failed" yes queued, then running, then succeeded (with result) or failed (with error). A run that has not moved for 10 minutes is marked failed when the runs are read.
run.result object<variant 1> | object<variant 2> | null yes Once succeeded: for detect, { suggestion, observations, sampledImages }; for propose, { suggestions } (three). null before then and when failed.
run.result<variant 1>.suggestion object yes The style read from the website's images.
run.result<variant 1>.suggestion.name string yes A short name for the style, 1 to 60 characters, for example Warm editorial.
run.result<variant 1>.suggestion.preset "photorealistic" | "editorial" | "minimalist-vector" | "3d-render" | "watercolor" | "corporate-tech" | "cinematic" | "illustration" yes The preset closest to the style. Applying the suggestion sets it as the project's hero.style and inline.style. Values: photorealistic (natural-light documentary photograph, realistic textures, no stylisation), editorial (modern editorial illustration or photograph, clean composition, restrained palette), minimalist-vector (flat vector illustration, few shapes, solid colours, plenty of empty space), 3d-render (soft studio 3D render, smooth matte materials, simple forms), watercolor (loose watercolour painting, soft edges, muted washes), corporate-tech (clean technology visual in cool blues and greys, geometric shapes), cinematic (cinematic still, dramatic lighting, strong atmosphere, wide framing), illustration (hand-drawn illustration, confident linework, warm friendly palette).
run.result<variant 1>.suggestion.styleDescription string yes The style in words, 1 to 400 characters: medium, palette, lighting, composition and mood. Applying the suggestion sets it as the project's styleDescription.
run.result<variant 1>.suggestion.neverDepict string[] no Subjects images in this style should not show, within the limits of the project's neverDepict (up to 20 entries of 1 to 80 characters, 600 together). Absent: applying the suggestion keeps the project's current list.
run.result<variant 1>.observations string yes What the images have in common, in a few sentences, up to 1000 characters.
run.result<variant 1>.sampledImages integer yes How many of the website's images were read, from 2 to 8.
run.result<variant 2>.suggestions object[] yes Exactly three styles: the first refines the current or detected style, the other two are clearly different.
run.result<variant 2>.suggestions[].name string yes A short name for the style, 1 to 60 characters, for example Warm editorial.
run.result<variant 2>.suggestions[].preset "photorealistic" | "editorial" | "minimalist-vector" | "3d-render" | "watercolor" | "corporate-tech" | "cinematic" | "illustration" yes The preset closest to the style. Applying the suggestion sets it as the project's hero.style and inline.style. Values: photorealistic (natural-light documentary photograph, realistic textures, no stylisation), editorial (modern editorial illustration or photograph, clean composition, restrained palette), minimalist-vector (flat vector illustration, few shapes, solid colours, plenty of empty space), 3d-render (soft studio 3D render, smooth matte materials, simple forms), watercolor (loose watercolour painting, soft edges, muted washes), corporate-tech (clean technology visual in cool blues and greys, geometric shapes), cinematic (cinematic still, dramatic lighting, strong atmosphere, wide framing), illustration (hand-drawn illustration, confident linework, warm friendly palette).
run.result<variant 2>.suggestions[].styleDescription string yes The style in words, 1 to 400 characters: medium, palette, lighting, composition and mood. Applying the suggestion sets it as the project's styleDescription.
run.result<variant 2>.suggestions[].neverDepict string[] no Subjects images in this style should not show, within the limits of the project's neverDepict (up to 20 entries of 1 to 80 characters, 600 together). Absent: applying the suggestion keeps the project's current list.
run.error string | null yes Why the run failed, a sentence meant for people; null unless failed.
run.requestedBy string | null yes Id of the user who started the run (for an API key, the user who created the key); null for the run onboarding starts on its own, and once that user's account is deleted.
run.appliedAt string (date-time) | null yes When a suggestion of this run was last applied to the project; null if never.
run.createdAt string (date-time) yes When the run was started, as an ISO 8601 timestamp.
run.updatedAt string (date-time) yes When the run last changed, as an ISO 8601 timestamp.

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

pd.projects.proposeImageStyles(input, init?)

Propose three image styles for the project

POST /api/workspaces/{workspaceId}/projects/{projectId}/image-style/proposals

Needs projects.update on the project. Starts a propose run and answers 202 with it: a text model proposes three styles from the project's industry, audience, language, default brand voice, current image settings and latest detection, when there is one. The first refines the current or detected style; the other two are clearly different. Works without a website. A run already queued or running of the same kind for this project is answered instead of a new one. A workspace may start 10 runs in any 24 hours, detections and proposals together (the detection onboarding starts on its own is outside the cap); past that the answer is 429 RATE_LIMITED with Retry-After (seconds until the oldest run of the window is 24 hours old) and details { retryAfterSeconds, limit, used }. Runs cost no credits. Follow the run with GET .../image-style/runs/latest until it is succeeded or failed, then apply a suggestion with POST .../image-style/apply.

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 path string (uuid) yes Id of a project of workspaceId. A project of another workspace answers 404 RESOURCE_NOT_FOUND, as if it did not exist. When the project has members, a workspace member who is not one of them answers 403 FORBIDDEN, and a project role can only narrow the permissions the member's workspace roles grant.
init init { signal?: AbortSignal; timeoutMs?: number } no The second argument: signal aborts the call, timeoutMs overrides the client's per-attempt timeout.

Returns 202 Accepted

Field Type Required Description
run object yes The run: a new one, queued, or the one of the same kind still running for this project.
run.id string (uuid) yes Id of the run, the runId that applyImageStyle takes.
run.workspaceId string (uuid) yes Id of the workspace that owns the project.
run.projectId string (uuid) yes Id of the project the run is for.
run.kind "detect" | "propose" yes detect: read the style of the website's images. propose: three alternatives that suit the site.
run.status "queued" | "running" | "succeeded" | "failed" yes queued, then running, then succeeded (with result) or failed (with error). A run that has not moved for 10 minutes is marked failed when the runs are read.
run.result object<variant 1> | object<variant 2> | null yes Once succeeded: for detect, { suggestion, observations, sampledImages }; for propose, { suggestions } (three). null before then and when failed.
run.result<variant 1>.suggestion object yes The style read from the website's images.
run.result<variant 1>.suggestion.name string yes A short name for the style, 1 to 60 characters, for example Warm editorial.
run.result<variant 1>.suggestion.preset "photorealistic" | "editorial" | "minimalist-vector" | "3d-render" | "watercolor" | "corporate-tech" | "cinematic" | "illustration" yes The preset closest to the style. Applying the suggestion sets it as the project's hero.style and inline.style. Values: photorealistic (natural-light documentary photograph, realistic textures, no stylisation), editorial (modern editorial illustration or photograph, clean composition, restrained palette), minimalist-vector (flat vector illustration, few shapes, solid colours, plenty of empty space), 3d-render (soft studio 3D render, smooth matte materials, simple forms), watercolor (loose watercolour painting, soft edges, muted washes), corporate-tech (clean technology visual in cool blues and greys, geometric shapes), cinematic (cinematic still, dramatic lighting, strong atmosphere, wide framing), illustration (hand-drawn illustration, confident linework, warm friendly palette).
run.result<variant 1>.suggestion.styleDescription string yes The style in words, 1 to 400 characters: medium, palette, lighting, composition and mood. Applying the suggestion sets it as the project's styleDescription.
run.result<variant 1>.suggestion.neverDepict string[] no Subjects images in this style should not show, within the limits of the project's neverDepict (up to 20 entries of 1 to 80 characters, 600 together). Absent: applying the suggestion keeps the project's current list.
run.result<variant 1>.observations string yes What the images have in common, in a few sentences, up to 1000 characters.
run.result<variant 1>.sampledImages integer yes How many of the website's images were read, from 2 to 8.
run.result<variant 2>.suggestions object[] yes Exactly three styles: the first refines the current or detected style, the other two are clearly different.
run.result<variant 2>.suggestions[].name string yes A short name for the style, 1 to 60 characters, for example Warm editorial.
run.result<variant 2>.suggestions[].preset "photorealistic" | "editorial" | "minimalist-vector" | "3d-render" | "watercolor" | "corporate-tech" | "cinematic" | "illustration" yes The preset closest to the style. Applying the suggestion sets it as the project's hero.style and inline.style. Values: photorealistic (natural-light documentary photograph, realistic textures, no stylisation), editorial (modern editorial illustration or photograph, clean composition, restrained palette), minimalist-vector (flat vector illustration, few shapes, solid colours, plenty of empty space), 3d-render (soft studio 3D render, smooth matte materials, simple forms), watercolor (loose watercolour painting, soft edges, muted washes), corporate-tech (clean technology visual in cool blues and greys, geometric shapes), cinematic (cinematic still, dramatic lighting, strong atmosphere, wide framing), illustration (hand-drawn illustration, confident linework, warm friendly palette).
run.result<variant 2>.suggestions[].styleDescription string yes The style in words, 1 to 400 characters: medium, palette, lighting, composition and mood. Applying the suggestion sets it as the project's styleDescription.
run.result<variant 2>.suggestions[].neverDepict string[] no Subjects images in this style should not show, within the limits of the project's neverDepict (up to 20 entries of 1 to 80 characters, 600 together). Absent: applying the suggestion keeps the project's current list.
run.error string | null yes Why the run failed, a sentence meant for people; null unless failed.
run.requestedBy string | null yes Id of the user who started the run (for an API key, the user who created the key); null for the run onboarding starts on its own, and once that user's account is deleted.
run.appliedAt string (date-time) | null yes When a suggestion of this run was last applied to the project; null if never.
run.createdAt string (date-time) yes When the run was started, as an ISO 8601 timestamp.
run.updatedAt string (date-time) yes When the run last changed, as an ISO 8601 timestamp.

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

pd.projects.latestImageStyleRuns(input, init?)

Read the project's latest image style runs

GET /api/workspaces/{workspaceId}/projects/{projectId}/image-style/runs/latest

Needs projects.update on the project. Answers the most recent detect run and the most recent propose run, each null when there is none. A run that has not moved for 10 minutes is marked failed when it is read, with error "The run stopped before it finished", so a lost run never stays queued or running.

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 path string (uuid) yes Id of a project of workspaceId. A project of another workspace answers 404 RESOURCE_NOT_FOUND, as if it did not exist. When the project has members, a workspace member who is not one of them answers 403 FORBIDDEN, and a project role can only narrow the permissions the member's workspace roles grant.
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
detect object | null yes The project's most recent detect run; null when it has none.
detect.id string (uuid) yes Id of the run, the runId that applyImageStyle takes.
detect.workspaceId string (uuid) yes Id of the workspace that owns the project.
detect.projectId string (uuid) yes Id of the project the run is for.
detect.kind "detect" | "propose" yes detect: read the style of the website's images. propose: three alternatives that suit the site.
detect.status "queued" | "running" | "succeeded" | "failed" yes queued, then running, then succeeded (with result) or failed (with error). A run that has not moved for 10 minutes is marked failed when the runs are read.
detect.result object<variant 1> | object<variant 2> | null yes Once succeeded: for detect, { suggestion, observations, sampledImages }; for propose, { suggestions } (three). null before then and when failed.
detect.result<variant 1>.suggestion object yes The style read from the website's images.
detect.result<variant 1>.suggestion.name string yes A short name for the style, 1 to 60 characters, for example Warm editorial.
detect.result<variant 1>.suggestion.preset "photorealistic" | "editorial" | "minimalist-vector" | "3d-render" | "watercolor" | "corporate-tech" | "cinematic" | "illustration" yes The preset closest to the style. Applying the suggestion sets it as the project's hero.style and inline.style. Values: photorealistic (natural-light documentary photograph, realistic textures, no stylisation), editorial (modern editorial illustration or photograph, clean composition, restrained palette), minimalist-vector (flat vector illustration, few shapes, solid colours, plenty of empty space), 3d-render (soft studio 3D render, smooth matte materials, simple forms), watercolor (loose watercolour painting, soft edges, muted washes), corporate-tech (clean technology visual in cool blues and greys, geometric shapes), cinematic (cinematic still, dramatic lighting, strong atmosphere, wide framing), illustration (hand-drawn illustration, confident linework, warm friendly palette).
detect.result<variant 1>.suggestion.styleDescription string yes The style in words, 1 to 400 characters: medium, palette, lighting, composition and mood. Applying the suggestion sets it as the project's styleDescription.
detect.result<variant 1>.suggestion.neverDepict string[] no Subjects images in this style should not show, within the limits of the project's neverDepict (up to 20 entries of 1 to 80 characters, 600 together). Absent: applying the suggestion keeps the project's current list.
detect.result<variant 1>.observations string yes What the images have in common, in a few sentences, up to 1000 characters.
detect.result<variant 1>.sampledImages integer yes How many of the website's images were read, from 2 to 8.
detect.result<variant 2>.suggestions object[] yes Exactly three styles: the first refines the current or detected style, the other two are clearly different.
detect.result<variant 2>.suggestions[].name string yes A short name for the style, 1 to 60 characters, for example Warm editorial.
detect.result<variant 2>.suggestions[].preset "photorealistic" | "editorial" | "minimalist-vector" | "3d-render" | "watercolor" | "corporate-tech" | "cinematic" | "illustration" yes The preset closest to the style. Applying the suggestion sets it as the project's hero.style and inline.style. Values: photorealistic (natural-light documentary photograph, realistic textures, no stylisation), editorial (modern editorial illustration or photograph, clean composition, restrained palette), minimalist-vector (flat vector illustration, few shapes, solid colours, plenty of empty space), 3d-render (soft studio 3D render, smooth matte materials, simple forms), watercolor (loose watercolour painting, soft edges, muted washes), corporate-tech (clean technology visual in cool blues and greys, geometric shapes), cinematic (cinematic still, dramatic lighting, strong atmosphere, wide framing), illustration (hand-drawn illustration, confident linework, warm friendly palette).
detect.result<variant 2>.suggestions[].styleDescription string yes The style in words, 1 to 400 characters: medium, palette, lighting, composition and mood. Applying the suggestion sets it as the project's styleDescription.
detect.result<variant 2>.suggestions[].neverDepict string[] no Subjects images in this style should not show, within the limits of the project's neverDepict (up to 20 entries of 1 to 80 characters, 600 together). Absent: applying the suggestion keeps the project's current list.
detect.error string | null yes Why the run failed, a sentence meant for people; null unless failed.
detect.requestedBy string | null yes Id of the user who started the run (for an API key, the user who created the key); null for the run onboarding starts on its own, and once that user's account is deleted.
detect.appliedAt string (date-time) | null yes When a suggestion of this run was last applied to the project; null if never.
detect.createdAt string (date-time) yes When the run was started, as an ISO 8601 timestamp.
detect.updatedAt string (date-time) yes When the run last changed, as an ISO 8601 timestamp.
propose object | null yes The project's most recent propose run; null when it has none.
propose.id string (uuid) yes Id of the run, the runId that applyImageStyle takes.
propose.workspaceId string (uuid) yes Id of the workspace that owns the project.
propose.projectId string (uuid) yes Id of the project the run is for.
propose.kind "detect" | "propose" yes detect: read the style of the website's images. propose: three alternatives that suit the site.
propose.status "queued" | "running" | "succeeded" | "failed" yes queued, then running, then succeeded (with result) or failed (with error). A run that has not moved for 10 minutes is marked failed when the runs are read.
propose.result object<variant 1> | object<variant 2> | null yes Once succeeded: for detect, { suggestion, observations, sampledImages }; for propose, { suggestions } (three). null before then and when failed.
propose.result<variant 1>.suggestion object yes The style read from the website's images.
propose.result<variant 1>.suggestion.name string yes A short name for the style, 1 to 60 characters, for example Warm editorial.
propose.result<variant 1>.suggestion.preset "photorealistic" | "editorial" | "minimalist-vector" | "3d-render" | "watercolor" | "corporate-tech" | "cinematic" | "illustration" yes The preset closest to the style. Applying the suggestion sets it as the project's hero.style and inline.style. Values: photorealistic (natural-light documentary photograph, realistic textures, no stylisation), editorial (modern editorial illustration or photograph, clean composition, restrained palette), minimalist-vector (flat vector illustration, few shapes, solid colours, plenty of empty space), 3d-render (soft studio 3D render, smooth matte materials, simple forms), watercolor (loose watercolour painting, soft edges, muted washes), corporate-tech (clean technology visual in cool blues and greys, geometric shapes), cinematic (cinematic still, dramatic lighting, strong atmosphere, wide framing), illustration (hand-drawn illustration, confident linework, warm friendly palette).
propose.result<variant 1>.suggestion.styleDescription string yes The style in words, 1 to 400 characters: medium, palette, lighting, composition and mood. Applying the suggestion sets it as the project's styleDescription.
propose.result<variant 1>.suggestion.neverDepict string[] no Subjects images in this style should not show, within the limits of the project's neverDepict (up to 20 entries of 1 to 80 characters, 600 together). Absent: applying the suggestion keeps the project's current list.
propose.result<variant 1>.observations string yes What the images have in common, in a few sentences, up to 1000 characters.
propose.result<variant 1>.sampledImages integer yes How many of the website's images were read, from 2 to 8.
propose.result<variant 2>.suggestions object[] yes Exactly three styles: the first refines the current or detected style, the other two are clearly different.
propose.result<variant 2>.suggestions[].name string yes A short name for the style, 1 to 60 characters, for example Warm editorial.
propose.result<variant 2>.suggestions[].preset "photorealistic" | "editorial" | "minimalist-vector" | "3d-render" | "watercolor" | "corporate-tech" | "cinematic" | "illustration" yes The preset closest to the style. Applying the suggestion sets it as the project's hero.style and inline.style. Values: photorealistic (natural-light documentary photograph, realistic textures, no stylisation), editorial (modern editorial illustration or photograph, clean composition, restrained palette), minimalist-vector (flat vector illustration, few shapes, solid colours, plenty of empty space), 3d-render (soft studio 3D render, smooth matte materials, simple forms), watercolor (loose watercolour painting, soft edges, muted washes), corporate-tech (clean technology visual in cool blues and greys, geometric shapes), cinematic (cinematic still, dramatic lighting, strong atmosphere, wide framing), illustration (hand-drawn illustration, confident linework, warm friendly palette).
propose.result<variant 2>.suggestions[].styleDescription string yes The style in words, 1 to 400 characters: medium, palette, lighting, composition and mood. Applying the suggestion sets it as the project's styleDescription.
propose.result<variant 2>.suggestions[].neverDepict string[] no Subjects images in this style should not show, within the limits of the project's neverDepict (up to 20 entries of 1 to 80 characters, 600 together). Absent: applying the suggestion keeps the project's current list.
propose.error string | null yes Why the run failed, a sentence meant for people; null unless failed.
propose.requestedBy string | null yes Id of the user who started the run (for an API key, the user who created the key); null for the run onboarding starts on its own, and once that user's account is deleted.
propose.appliedAt string (date-time) | null yes When a suggestion of this run was last applied to the project; null if never.
propose.createdAt string (date-time) yes When the run was started, as an ISO 8601 timestamp.
propose.updatedAt string (date-time) yes When the run last changed, as an ISO 8601 timestamp.

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

pd.projects.applyImageStyle(input, init?)

Apply a detected or proposed image style

POST /api/workspaces/{workspaceId}/projects/{projectId}/image-style/apply

Needs projects.update on the project. Writes the chosen suggestion into settings.images: its preset becomes hero.style and inline.style, its styleDescription the style description, and its neverDepict, when it has one, the never-depict list. Aspects, the hero prompt and the other settings keys stay. The result is validated as PATCH validates settings.images, and the run's appliedAt is set. Images generated or regenerated afterwards follow it. Records a projects.image_style_applied audit entry and answers the project.

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 path string (uuid) yes Id of a project of workspaceId. A project of another workspace answers 404 RESOURCE_NOT_FOUND, as if it did not exist. When the project has members, a workspace member who is not one of them answers 403 FORBIDDEN, and a project role can only narrow the permissions the member's workspace roles grant.
body body object yes
body.runId body string (uuid) yes Id of a succeeded run of this project, from GET .../image-style/runs/latest. A run of another project answers 404; one that has not succeeded, 409.
body.index body integer no Which suggestion to apply: 0 to 2 for a propose run, 0 (the default) for a detect run, which has one. Out of range for the run answers 400. Default: 0.
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
project object yes The project, as it is after the request.
project.id string (uuid) yes Id of the project, used in every /projects/{projectId} route.
project.workspaceId string (uuid) yes Id of the workspace that owns the project.
project.name string yes Display name of the project, 1 to 120 characters.
project.slug string yes URL-safe identifier, unique within the workspace. Generated from name when not sent at creation, and never changed afterwards.
project.description string yes Free-text description of the project, up to 2000 characters; empty when unset.
project.settings Record<string, unknown> yes The stored settings object, with the keys exactly as they were sent. The only key the server reads is images (image-generation settings); imageSettings is that key with its defaults filled in.
project.websiteUrl string | null yes Address of the website the project writes for; null when none was given.
project.iconUrl string | null yes Address of the site's icon, copied to the media host: found by the website analysis, or fetched when websiteUrl is set or changed and by POST .../icon/refresh. null until one is found. No request sets it directly.
project.industry string yes Free-text industry of the site, up to 200 characters; empty when unset.
project.audience string yes Free-text description of who the articles are written for, up to 500 characters; empty when unset. The app starts a new article's audience from it.
project.language string yes The project's default language, a language tag such as en or pt-BR: where a new article starts. Always one of languages.
project.languages string[] yes Every language the project publishes in, as language tags, with the default language first. Articles are written in one of these.
project.defaultTone string yes Tone a new article starts from, one of professional, conversational, authoritative, practical, persuasive. Each article can change it.
project.defaultWordCount integer yes Target length in words a new article starts from, from 200 to 10000. Each article can change it.
project.status "active" | "archived" yes active, or archived: read-only until POST /api/workspaces/{workspaceId}/projects/{projectId}/restore makes it active again.
project.createdAt string (date-time) yes When the project was created, as an ISO 8601 timestamp.
project.updatedAt string (date-time) yes When the project row last changed (an update, an archive or a restore), as an ISO 8601 timestamp.
project.imageSettings object yes The project's image-generation settings as generation uses them: settings.images with every default filled in. A stored value that no longer validates reads as the defaults.
project.imageSettings.styleDescription string | null yes The project's style description, appended to every image prompt; null when none is set.
project.imageSettings.neverDepict string[] yes The subjects no image may show, in force: the project's own list, or the default list (official documents, seals and emblems, flags, identifiable real people) when it has none. Empty when the project excluded nothing.
project.imageSettings.hero object yes Cover (hero) image settings, defaults filled in.
project.imageSettings.hero.style "photorealistic" | "editorial" | "minimalist-vector" | "3d-render" | "watercolor" | "corporate-tech" | "cinematic" | "illustration" | null yes Style for cover images; null when unset, in which case the article's imageStyle applies. Values: photorealistic (natural-light documentary photograph, realistic textures, no stylisation), editorial (modern editorial illustration or photograph, clean composition, restrained palette), minimalist-vector (flat vector illustration, few shapes, solid colours, plenty of empty space), 3d-render (soft studio 3D render, smooth matte materials, simple forms), watercolor (loose watercolour painting, soft edges, muted washes), corporate-tech (clean technology visual in cool blues and greys, geometric shapes), cinematic (cinematic still, dramatic lighting, strong atmosphere, wide framing), illustration (hand-drawn illustration, confident linework, warm friendly palette).
project.imageSettings.hero.aspect "16:9" | "1200x630" yes Shape of cover images: 16:9 or 1200x630 (the social-card size).
project.imageSettings.hero.prompt string | null yes Standing direction for cover images; null when none is set.
project.imageSettings.inline object yes Inline image settings, defaults filled in.
project.imageSettings.inline.style "photorealistic" | "editorial" | "minimalist-vector" | "3d-render" | "watercolor" | "corporate-tech" | "cinematic" | "illustration" | null yes Style for inline images; null when unset, in which case the article's imageStyle applies. Values: photorealistic (natural-light documentary photograph, realistic textures, no stylisation), editorial (modern editorial illustration or photograph, clean composition, restrained palette), minimalist-vector (flat vector illustration, few shapes, solid colours, plenty of empty space), 3d-render (soft studio 3D render, smooth matte materials, simple forms), watercolor (loose watercolour painting, soft edges, muted washes), corporate-tech (clean technology visual in cool blues and greys, geometric shapes), cinematic (cinematic still, dramatic lighting, strong atmosphere, wide framing), illustration (hand-drawn illustration, confident linework, warm friendly palette).
project.imageSettings.inline.aspect "4:3" | "1:1" yes Shape of inline images: 4:3 or 1:1.

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