calendar
The methods of pd.calendar. Inputs and outputs are described in Conventions; every method can also fail as described in Errors.
Methods
pd.calendar.list(input, init?)
The content calendar over a date range
GET /api/workspaces/{workspaceId}/calendar
Returns the workspace's calendar items with each linked article's current title and status and the assignee's name. Month, week and list views are this one call over different from and to bounds. Requires articles.read; items of a restricted project the caller is not a member of are left out, and so are items that track an article of one, whichever project the item itself is in. Items are ordered by scheduledFor, earliest first, and are not paginated; an unscheduled item appears only when neither bound is sent, after the scheduled ones.
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. |
from |
query | string (date-time) |
no | Start of the range, inclusive, as an ISO 8601 UTC instant ending in Z. Compared with scheduledFor, so a view over a local month or week passes that zone's boundaries converted to UTC. Absent: no lower bound. |
to |
query | string (date-time) |
no | End of the range, inclusive, in the same format as from. Absent: no upper bound. |
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 |
|---|---|---|---|
items |
object[] |
yes | The items whose scheduledFor falls within the requested range, earliest first. Without from or to, every item, with unscheduled ones last; with either, unscheduled items are left out. |
items[].id |
string (uuid) |
yes | Id of the calendar item. |
items[].workspaceId |
string (uuid) |
yes | Id of the workspace that owns the item. |
items[].projectId |
string (uuid) | null |
yes | Id of the project the item is planned for. null for a workspace-level item. |
items[].articleId |
string (uuid) | null |
yes | Id of the article the item plans or tracks. null when none was linked, and again if that article is deleted: the item outlives it. |
items[].title |
string |
yes | What is planned, as shown on the calendar. Up to 300 characters. |
items[].status |
"idea" | "planned" | "writing" | "review" | "approved" | "scheduled" | "published" |
yes | The planning stage, one of idea, planned, writing, review, approved, scheduled or published. A label kept by the client: the server never advances it and it does not follow the article's own status. |
items[].scheduledFor |
string (date-time) | null |
yes | The planned date and time, an ISO 8601 UTC instant. null for an unscheduled item. Setting it does not publish anything outside a publishing plan. |
items[].assignedTo |
string | null |
yes | Who the item is assigned to: a user id, stored as the client sent it and not checked against the workspace's members. null when unassigned. |
items[].notes |
string |
yes | Free-form notes, up to 2000 characters. An empty string when none. |
items[].planId |
string (uuid) | null |
yes | Id of the publishing plan (plans.get) that made the item. null for an item added by hand, and again if the plan is deleted. |
items[].ideaId |
string (uuid) | null |
yes | Id of the idea the item was made from. null when none. |
items[].runState |
"pending" | "claimed" | "generating" | "publishing" | "translating" | "done" | "parked" | "skipped" | null |
yes | Where a plan's item is in its run: pending, claimed, generating, publishing, done, parked or skipped. null for an item that is not part of a plan. |
items[].parkedReason |
string | null |
yes | Why a parked item stopped; null otherwise. |
items[].createdAt |
string (date-time) |
yes | When the item was created, as an ISO 8601 UTC date-time. |
items[].updatedAt |
string (date-time) |
yes | When the item was last changed, as an ISO 8601 UTC date-time. |
items[].article |
object | null |
yes | The linked article; null when none, or when it was deleted. |
items[].article.id |
string (uuid) |
yes | Id of the linked article. |
items[].article.title |
string |
yes | Current title of the linked article. |
items[].article.status |
"DRAFT" | "QUEUED" | "PROCESSING" | "NEEDS_REVIEW" | "CHANGES_REQUESTED" | "APPROVED" | "PUBLISHED" |
yes | Current status of the linked article, read live: unlike the item's own status, it follows the article. |
items[].assignee |
object | null |
yes | Who the item is assigned to; null when assignedTo is null. |
items[].assignee.id |
string |
yes | The assignedTo value of the item. |
items[].assignee.name |
string | null |
yes | Null when the id is not a member of this workspace. |
items[].plan |
object | null |
yes | The plan the item belongs to; null for an item added by hand. |
items[].plan.id |
string (uuid) |
yes | Id of the plan. |
items[].plan.name |
string |
yes | Name of the plan. |
items[].plan.runTime |
string |
yes | Time of day of the plan's slots, HH:MM on the wall of timezone. |
items[].plan.timezone |
string |
yes | IANA time zone the plan's dates and runTime are read in. |
items[].localDate |
string | null |
yes | For a plan's item, the day of scheduledFor on the wall of the plan's time zone, YYYY-MM-DD; a client places the item on this day. null for any other item. |
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.calendar.list({
workspaceId: "3f0c5a1e-8b2d-4c6e-9a7f-1d2e3f4a5b6c",
});
console.log(result);
pd.calendar.create(input, init?)
Add a calendar item
POST /api/workspaces/{workspaceId}/calendar
Adds an item to the content calendar. Requires articles.create in the workspace, and on the project when projectId is sent (404 for a foreign project, 409 for an archived one) and on the article's project when articleId is sent (404 for an article of another workspace). The item is a plan kept beside the article: its status is a label that nothing advances, and a scheduledFor date does not publish anything outside a publishing plan. Answers 201.
Input
| Name | In | Type | Required | Description |
|---|---|---|---|---|
workspaceId |
path | string (uuid) |
yes | Id of the workspace the request works in. The caller must be a member of it, or hold an API key issued by it. For anyone else, an unknown id and an id they do not belong to both answer 404 RESOURCE_NOT_FOUND, so membership cannot be probed. |
body |
body | object |
yes | |
body.title |
body | string |
yes | What is planned, as shown on the calendar, 1 to 300 characters. |
body.projectId |
body | string (uuid) | null |
no | Id of the project the item is planned for. It must be in this workspace (404 otherwise) and not archived (409). null or absent: a workspace-level item. |
body.articleId |
body | string (uuid) | null |
no | Id of the article the item plans or tracks. It must be in this workspace (404 otherwise), and the caller needs the permission on the article's project. null or absent: no article yet. |
body.status |
body | "idea" | "planned" | "writing" | "review" | "approved" | "scheduled" | "published" |
no | The planning stage, one of idea, planned, writing, review, approved, scheduled or published. Defaults to idea. A label the client keeps: the server never changes it, and neither it nor scheduledFor publishes or schedules the article. |
body.scheduledFor |
body | string (date-time) | null |
no | The planned date and time as an ISO 8601 UTC instant ending in Z, such as 2026-11-03T09:00:00Z; an offset such as +02:00 or a time without a zone is refused with 400. No time zone is stored: the client converts to and from its own. null or absent: unscheduled. |
body.assignedTo |
body | string | null |
no | Who the item is assigned to: a user id of up to 200 characters, stored as sent and not checked against the workspace's members. calendar.list shows the member's name when the id is one. null or absent: unassigned. |
body.notes |
body | string |
no | Free-form notes, up to 2000 characters. Stored as an empty string when absent. |
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 |
|---|---|---|---|
item |
object |
yes | The calendar item as stored after the request. |
item.id |
string (uuid) |
yes | Id of the calendar item. |
item.workspaceId |
string (uuid) |
yes | Id of the workspace that owns the item. |
item.projectId |
string (uuid) | null |
yes | Id of the project the item is planned for. null for a workspace-level item. |
item.articleId |
string (uuid) | null |
yes | Id of the article the item plans or tracks. null when none was linked, and again if that article is deleted: the item outlives it. |
item.title |
string |
yes | What is planned, as shown on the calendar. Up to 300 characters. |
item.status |
"idea" | "planned" | "writing" | "review" | "approved" | "scheduled" | "published" |
yes | The planning stage, one of idea, planned, writing, review, approved, scheduled or published. A label kept by the client: the server never advances it and it does not follow the article's own status. |
item.scheduledFor |
string (date-time) | null |
yes | The planned date and time, an ISO 8601 UTC instant. null for an unscheduled item. Setting it does not publish anything outside a publishing plan. |
item.assignedTo |
string | null |
yes | Who the item is assigned to: a user id, stored as the client sent it and not checked against the workspace's members. null when unassigned. |
item.notes |
string |
yes | Free-form notes, up to 2000 characters. An empty string when none. |
item.planId |
string (uuid) | null |
yes | Id of the publishing plan (plans.get) that made the item. null for an item added by hand, and again if the plan is deleted. |
item.ideaId |
string (uuid) | null |
yes | Id of the idea the item was made from. null when none. |
item.runState |
"pending" | "claimed" | "generating" | "publishing" | "translating" | "done" | "parked" | "skipped" | null |
yes | Where a plan's item is in its run: pending, claimed, generating, publishing, done, parked or skipped. null for an item that is not part of a plan. |
item.parkedReason |
string | null |
yes | Why a parked item stopped; null otherwise. |
item.createdAt |
string (date-time) |
yes | When the item was created, as an ISO 8601 UTC date-time. |
item.updatedAt |
string (date-time) |
yes | When the item was last changed, as an ISO 8601 UTC date-time. |
Errors 400 invalid input, 401 missing or invalid key, 403 the key's roles lack the permission, 404 not found, 429 rate limited or out of quota. See Errors.
Example
import { PrismDraft } from "@prism-draft/sdk";
const pd = new PrismDraft({ apiKey: process.env.PRISMDRAFT_API_KEY! });
const result = await pd.calendar.create({
workspaceId: "3f0c5a1e-8b2d-4c6e-9a7f-1d2e3f4a5b6c",
body: {
title: "example",
},
});
console.log(result);
pd.calendar.update(input, init?)
Update a calendar item
PATCH /api/workspaces/{workspaceId}/calendar/{itemId}
Changes the fields sent and keeps the others. null clears projectId, articleId, scheduledFor and assignedTo. Requires articles.update, checked against the projectId and articleId when sent and against the item's current project and article: 403 for a caller who is not a member of a restricted project, 409 when that project is archived. 404 when the item is not in the workspace.
Input
| Name | In | Type | Required | Description |
|---|---|---|---|---|
workspaceId |
path | string (uuid) |
yes | Id of the workspace the request works in. The caller must be a member of it, or hold an API key issued by it. For anyone else, an unknown id and an id they do not belong to both answer 404 RESOURCE_NOT_FOUND, so membership cannot be probed. |
itemId |
path | string (uuid) |
yes | Id of the calendar item, in the workspace workspaceId. 404 when it is not. |
body |
body | object |
no | |
body.title |
body | string |
no | What is planned, as shown on the calendar, 1 to 300 characters. Absent: unchanged. |
body.projectId |
body | string (uuid) | null |
no | Id of the project the item is planned for, under the rules of calendar.create: in this workspace (404 otherwise) and not archived (409). null makes it a workspace-level item; absent: unchanged. |
body.articleId |
body | string (uuid) | null |
no | Id of the article the item plans or tracks, under the rules of calendar.create: in this workspace (404 otherwise), and the caller needs the permission on the article's project. null detaches the article; absent: unchanged. |
body.status |
body | "idea" | "planned" | "writing" | "review" | "approved" | "scheduled" | "published" |
no | The planning stage, one of idea, planned, writing, review, approved, scheduled or published. Absent: unchanged. A label the client keeps: the server never changes it, and neither it nor scheduledFor publishes or schedules the article. |
body.scheduledFor |
body | string (date-time) | null |
no | The planned date and time as an ISO 8601 UTC instant ending in Z, such as 2026-11-03T09:00:00Z; an offset such as +02:00 or a time without a zone is refused with 400. No time zone is stored: the client converts to and from its own. null unschedules the item; absent: unchanged. |
body.assignedTo |
body | string | null |
no | Who the item is assigned to: a user id of up to 200 characters, stored as sent and not checked against the workspace's members. calendar.list shows the member's name when the id is one. null unassigns it; absent: unchanged. |
body.notes |
body | string |
no | Free-form notes, up to 2000 characters. Absent: unchanged; an empty string clears them. |
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 |
|---|---|---|---|
item |
object |
yes | The calendar item as stored after the request. |
item.id |
string (uuid) |
yes | Id of the calendar item. |
item.workspaceId |
string (uuid) |
yes | Id of the workspace that owns the item. |
item.projectId |
string (uuid) | null |
yes | Id of the project the item is planned for. null for a workspace-level item. |
item.articleId |
string (uuid) | null |
yes | Id of the article the item plans or tracks. null when none was linked, and again if that article is deleted: the item outlives it. |
item.title |
string |
yes | What is planned, as shown on the calendar. Up to 300 characters. |
item.status |
"idea" | "planned" | "writing" | "review" | "approved" | "scheduled" | "published" |
yes | The planning stage, one of idea, planned, writing, review, approved, scheduled or published. A label kept by the client: the server never advances it and it does not follow the article's own status. |
item.scheduledFor |
string (date-time) | null |
yes | The planned date and time, an ISO 8601 UTC instant. null for an unscheduled item. Setting it does not publish anything outside a publishing plan. |
item.assignedTo |
string | null |
yes | Who the item is assigned to: a user id, stored as the client sent it and not checked against the workspace's members. null when unassigned. |
item.notes |
string |
yes | Free-form notes, up to 2000 characters. An empty string when none. |
item.planId |
string (uuid) | null |
yes | Id of the publishing plan (plans.get) that made the item. null for an item added by hand, and again if the plan is deleted. |
item.ideaId |
string (uuid) | null |
yes | Id of the idea the item was made from. null when none. |
item.runState |
"pending" | "claimed" | "generating" | "publishing" | "translating" | "done" | "parked" | "skipped" | null |
yes | Where a plan's item is in its run: pending, claimed, generating, publishing, done, parked or skipped. null for an item that is not part of a plan. |
item.parkedReason |
string | null |
yes | Why a parked item stopped; null otherwise. |
item.createdAt |
string (date-time) |
yes | When the item was created, as an ISO 8601 UTC date-time. |
item.updatedAt |
string (date-time) |
yes | When the item was last changed, as an ISO 8601 UTC date-time. |
Errors 400 invalid input, 401 missing or invalid key, 403 the key's roles lack the permission, 404 not found, 429 rate limited or out of quota. See Errors.
Example
import { PrismDraft } from "@prism-draft/sdk";
const pd = new PrismDraft({ apiKey: process.env.PRISMDRAFT_API_KEY! });
const result = await pd.calendar.update({
workspaceId: "3f0c5a1e-8b2d-4c6e-9a7f-1d2e3f4a5b6c",
itemId: "3f0c5a1e-8b2d-4c6e-9a7f-1d2e3f4a5b6c",
});
console.log(result);
pd.calendar.delete(input, init?)
Remove a calendar item
DELETE /api/workspaces/{workspaceId}/calendar/{itemId}
Removes the item from the calendar; the article it was linked to is untouched. Requires articles.delete, on the item's project and article when it has them (403 for a caller who is not a member of a restricted project, 409 when it is archived). 404 when the item is not in the workspace.
Input
| Name | In | Type | Required | Description |
|---|---|---|---|---|
workspaceId |
path | string (uuid) |
yes | Id of the workspace the request works in. The caller must be a member of it, or hold an API key issued by it. For anyone else, an unknown id and an id they do not belong to both answer 404 RESOURCE_NOT_FOUND, so membership cannot be probed. |
itemId |
path | string (uuid) |
yes | Id of the calendar item, in the workspace workspaceId. 404 when it is not. |
init |
init | { signal?: AbortSignal; timeoutMs?: number } |
no | The second argument: signal aborts the call, timeoutMs overrides the client's per-attempt timeout. |
Returns 200 OK
| Field | Type | Required | Description |
|---|---|---|---|
ok |
true |
yes | Always true. A resource that does not exist answers 404 instead. |
Errors 400 invalid input, 401 missing or invalid key, 403 the key's roles lack the permission, 404 not found, 429 rate limited or out of quota. See Errors.
Example
import { PrismDraft } from "@prism-draft/sdk";
const pd = new PrismDraft({ apiKey: process.env.PRISMDRAFT_API_KEY! });
const result = await pd.calendar.delete({
workspaceId: "3f0c5a1e-8b2d-4c6e-9a7f-1d2e3f4a5b6c",
itemId: "3f0c5a1e-8b2d-4c6e-9a7f-1d2e3f4a5b6c",
});
console.log(result);