integrations
The methods of pd.integrations. Inputs and outputs are described in Conventions; every method can also fail as described in Errors.
Methods
pd.integrations.list(input, init?)
List publishing integrations
GET /api/workspaces/{workspaceId}/integrations
Requires integrations.read. Returns every integration of the workspace, active or not, newest first. The stored config holds credentials and is never returned.
Input
| Name | In | Type | Required | Description |
|---|---|---|---|---|
workspaceId |
path | string (uuid) |
yes | Id of the workspace the request works in. The caller must be a member of it, or hold an API key issued by it. For anyone else, an unknown id and an id they do not belong to both answer 404 RESOURCE_NOT_FOUND, so membership cannot be probed. |
init |
init | { signal?: AbortSignal; timeoutMs?: number } |
no | The second argument: signal aborts the call, timeoutMs overrides the client's per-attempt timeout. |
Returns 200 OK
| Field | Type | Required | Description |
|---|---|---|---|
integrations |
object[] |
yes | Every integration of the workspace, active or not, newest first. |
integrations[].id |
string (uuid) |
yes | Integration id. |
integrations[].workspaceId |
string (uuid) |
yes | Workspace that owns the integration. |
integrations[].projectId |
string (uuid) | null |
yes | Project the integration is scoped to. Null: used for every project of the workspace; a project's own integration is preferred over a workspace-wide one. |
integrations[].type |
"wordpress" | "webflow" | "ghost" | "shopify" | "webhook" |
yes | Publishing target: wordpress, webflow, ghost or shopify publish through that CMS's API; webhook sends each published article as a signed POST to a URL you run. |
integrations[].name |
string |
yes | Label chosen when the integration was connected. |
integrations[].active |
boolean |
yes | False: the integration is skipped when choosing where to publish an article. |
integrations[].lastPublishedAt |
string (date-time) | null |
yes | When an article was last published through it. Null if none has been. |
integrations[].createdAt |
string (date-time) |
yes | When the integration was connected. |
integrations[].updatedAt |
string (date-time) |
yes | When the integration was last changed. |
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.integrations.list({
workspaceId: "3f0c5a1e-8b2d-4c6e-9a7f-1d2e3f4a5b6c",
});
console.log(result);
pd.integrations.create(input, init?)
Connect a publishing target
POST /api/workspaces/{workspaceId}/integrations
Requires integrations.create; answers 201 and records an integrations.created audit entry. The provider-specific config is validated, and any URL in it is checked against private address ranges before a credential is stored; either failure answers 400, and a projectId outside the workspace answers 404. The config is never echoed back. The integration starts active.
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.type |
body | "wordpress" | "ghost" | "webflow" | "shopify" | "webhook" |
yes | Publishing target to connect: wordpress, ghost, webflow or shopify publish through that CMS's API; webhook sends each published article as a signed POST to a URL you run. config must match it. |
body.name |
body | string |
yes | Label for the integration, 1-120 characters. |
body.projectId |
body | string (uuid) | null |
no | Project to scope the integration to; it must belong to the workspace (404 otherwise). null or omitted: used for every project of the workspace. A project's own integration is preferred over a workspace-wide one. |
body.config |
body | Record<string, unknown> |
yes | Provider settings and credentials, checked against type (400 when a field is missing or malformed). Write-only: it is stored but never returned by any call. wordpress: siteUrl, username, applicationPassword (a WordPress application password, not the account password), optional status (publish, the default, or draft). ghost: siteUrl, adminApiKey (the Admin API key, id:secret), optional status (published, the default, or draft). webflow: apiToken, collectionId, optional live (boolean, default true). shopify: shopDomain, accessToken, blogId, optional apiVersion (default 2025-01). webhook: url and secret (at least 16 characters), which signs each delivery. A siteUrl or url is checked against private address ranges before anything is stored. |
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 |
|---|---|---|---|
integration |
object |
yes | The new integration, reduced to its id, type and name; the config is not echoed back. |
integration.id |
string (uuid) |
yes | Id of the new integration. |
integration.type |
"wordpress" | "webflow" | "ghost" | "shopify" | "webhook" |
yes | Publishing target: wordpress, webflow, ghost or shopify publish through that CMS's API; webhook sends each published article as a signed POST to a URL you run. |
integration.name |
string |
yes | Label of the new integration. |
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.integrations.create({
workspaceId: "3f0c5a1e-8b2d-4c6e-9a7f-1d2e3f4a5b6c",
body: {
type: "wordpress",
name: "example",
config: {},
},
});
console.log(result);
pd.integrations.update(input, init?)
Update an integration
PATCH /api/workspaces/{workspaceId}/integrations/{integrationId}
Requires integrations.update. Only the fields sent change; an unknown integration, or one of another workspace, answers 404. A config sent is merged into the stored one and validated as on integrations.create (400 INVALID_REQUEST when it is not valid for the integration's type, or an address in it is private); the record of earlier publishes is kept, with one exception: when the stored credentials cannot be opened (the server could not decrypt them), the config sent replaces the stored one entirely, so it must be complete, and the record of published articles is lost, so each of them is published again as a new post. The type and projectId cannot be changed; sending a type has no effect. Records an integrations.updated audit entry that lists the field names changed, not their values.
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. |
integrationId |
path | string (uuid) |
yes | Id of the publishing integration, from integrations.list. |
body |
body | object |
no | |
body.name |
body | string |
no | New label, 1-120 characters. |
body.active |
body | boolean |
no | False stops the integration being chosen when an article is published; true makes it eligible again. Omit to leave it as it is. |
body.config |
body | Record<string, unknown> |
no | Connection settings to change, in the shape described on integrations.create for the integration's type. Fields sent replace the stored values of the same name; fields left out keep theirs, so a secret you do not send stays as it is and one you send is stored in its place. The result is checked as on create (400 when it is not valid for the type, or when a siteUrl or url you send points at a private address), and nothing is stored then. The integration's record of articles it has published is kept and cannot be set from here, so a published article is updated in the CMS, not published again as a new post; the exception is an integration whose stored credentials cannot be opened: the config sent then replaces the stored one entirely, and the record is lost. Write-only: never returned. Omit to keep the stored config. |
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 |
|---|---|---|---|
integration |
object |
yes | The integration as stored after the update. |
integration.id |
string (uuid) |
yes | Integration id. |
integration.workspaceId |
string (uuid) |
yes | Workspace that owns the integration. |
integration.projectId |
string (uuid) | null |
yes | Project the integration is scoped to. Null: used for every project of the workspace; a project's own integration is preferred over a workspace-wide one. |
integration.type |
"wordpress" | "webflow" | "ghost" | "shopify" | "webhook" |
yes | Publishing target: wordpress, webflow, ghost or shopify publish through that CMS's API; webhook sends each published article as a signed POST to a URL you run. |
integration.name |
string |
yes | Label chosen when the integration was connected. |
integration.active |
boolean |
yes | False: the integration is skipped when choosing where to publish an article. |
integration.lastPublishedAt |
string (date-time) | null |
yes | When an article was last published through it. Null if none has been. |
integration.createdAt |
string (date-time) |
yes | When the integration was connected. |
integration.updatedAt |
string (date-time) |
yes | When the integration was last changed. |
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.integrations.update({
workspaceId: "3f0c5a1e-8b2d-4c6e-9a7f-1d2e3f4a5b6c",
integrationId: "3f0c5a1e-8b2d-4c6e-9a7f-1d2e3f4a5b6c",
});
console.log(result);
pd.integrations.delete(input, init?)
Disconnect an integration
DELETE /api/workspaces/{workspaceId}/integrations/{integrationId}
Requires integrations.delete; an unknown integration, or one of another workspace, answers 404. Posts already published to the CMS are not touched. Records an integrations.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. |
integrationId |
path | string (uuid) |
yes | Id of the publishing integration, from integrations.list. |
init |
init | { signal?: AbortSignal; timeoutMs?: number } |
no | The second argument: signal aborts the call, timeoutMs overrides the client's per-attempt timeout. |
Returns 200 OK
| Field | Type | Required | Description |
|---|---|---|---|
ok |
boolean |
yes | Always true; a failure is an error response. |
Errors 400 invalid input, 401 missing or invalid key, 403 the key's roles lack the permission, 404 not found, 429 rate limited or out of quota. See Errors.
Example
import { PrismDraft } from "@prism-draft/sdk";
const pd = new PrismDraft({ apiKey: process.env.PRISMDRAFT_API_KEY! });
const result = await pd.integrations.delete({
workspaceId: "3f0c5a1e-8b2d-4c6e-9a7f-1d2e3f4a5b6c",
integrationId: "3f0c5a1e-8b2d-4c6e-9a7f-1d2e3f4a5b6c",
});
console.log(result);