Management API

Workflow

Move documents through review, scheduling and publishing.

Documents move through six statuses: idea, planned, drafting, review, scheduled and published. You can set the first three with a plain update. Review, scheduling and publishing each have their own endpoint, because they do more than change the status.

Transitions#

FromToHow
idea, planned, drafting, reviewidea, planned or draftingPATCH /documents/:id with status
any but scheduledreviewPOST …/submit
reviewdraftingPOST …/request-changes
reviewpublished, or scheduled with a future publishAtPOST …/approve
planned, drafting, review, publishedpublished, or scheduled with a future publishAtPOST …/publish
planned, drafting, review, published, scheduledscheduledPOST …/schedule
scheduleddrafting or reviewPOST …/unschedule
scheduledpublishedPMKIN, within a minute of publishAt
published, scheduleddraftingPOST …/unpublish

Publishing, approving and scheduling need a title and a slug.

Published is more than a status
isPublished says whether the document is live, separately from status. A published document you edit keeps serving the published version, and hasUnpublishedChanges turns true until you publish again.

Endpoints#

Submit for review#

POST/documents/:id/submit

Sends the document to review. A claimed brief becomes drafted. Works from any status except scheduled.

Path parameters
idstringrequired
Body
messagestring
Errors
ContentRequired422
SubmitNotAllowed409
NotFound404
curl -X POST "https://api.pmkin.io/documents/6704a1f0c2b3d4e5f6a7b8c9/submit" \
-H "Authorization: Bearer $PMKIN_MANAGEMENT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"message": "Ready for review. I left the pricing table for last."
}'
Response: 200 OK
{
"assigneeId": "66f0b2c4d5e6f7a8b9c0d1f0",
"authorId": "66f0b2c4d5e6f7a8b9c0d1f0",
"categoryId": "6701c3d4e5f6a7b8c9d0e1f2",
"clusterId": "6702d4e5f6a7b8c9d0e1f2a3",
"content": "# Headless CMS pricing\n\nWhat each plan costs, and when an upgrade pays off.\n",
"contentUpdatedAt": "2026-10-08T09:12:44.000Z",
"contentUpdatedBy": {
"agent": "Claude Code",
"id": "6703f6a7b8c9d0e1f2a3b4c5",
"name": "Writing agent",
"type": "token"
},
"coverImageUrl": null,
"dueDate": "2026-10-20",
"hasUnpublishedChanges": false,
"id": "6704a1f0c2b3d4e5f6a7b8c9",
"isPublished": false,
"metaDescription": "",
"metaTitle": "",
"projectId": "66f0b2c4d5e6f7a8b9c0d1e2",
"publishedMarkdown": "",
"publishedVersion": 0,
"slug": "headless-cms-pricing",
"status": "review",
"subtitle": "",
"teamId": "66f0b2c4d5e6f7a8b9c0d1e1",
"title": "Headless CMS pricing",
"updatedAt": "2026-10-08T09:12:44.000Z",
"version": 7,
"wordCount": 11,
"review": {
"feedback": null,
"feedbackAt": null,
"feedbackBy": null,
"message": "Ready for review. I left the pricing table for last.",
"submittedAt": "2026-10-09T11:00:00.000Z",
"submittedBy": {
"agent": "Claude Code",
"id": "6703f6a7b8c9d0e1f2a3b4c5",
"name": "Writing agent",
"type": "token"
}
}
}

Request changes#

POST/documents/:id/request-changes

Sends a document in review back to drafting, with feedback for the writer in review.feedback.

Path parameters
idstringrequired
Body
feedbackstring
Errors
NotInReview409
NotFound404
curl -X POST "https://api.pmkin.io/documents/6704a1f0c2b3d4e5f6a7b8c9/request-changes" \
-H "Authorization: Bearer $PMKIN_MANAGEMENT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"feedback": "Add a pricing table and cite the survey."
}'
Response: 200 OK
{
"assigneeId": "66f0b2c4d5e6f7a8b9c0d1f0",
"authorId": "66f0b2c4d5e6f7a8b9c0d1f0",
"categoryId": "6701c3d4e5f6a7b8c9d0e1f2",
"clusterId": "6702d4e5f6a7b8c9d0e1f2a3",
"content": "# Headless CMS pricing\n\nWhat each plan costs, and when an upgrade pays off.\n",
"contentUpdatedAt": "2026-10-08T09:12:44.000Z",
"contentUpdatedBy": {
"agent": "Claude Code",
"id": "6703f6a7b8c9d0e1f2a3b4c5",
"name": "Writing agent",
"type": "token"
},
"coverImageUrl": null,
"dueDate": "2026-10-20",
"hasUnpublishedChanges": false,
"id": "6704a1f0c2b3d4e5f6a7b8c9",
"isPublished": false,
"metaDescription": "",
"metaTitle": "",
"projectId": "66f0b2c4d5e6f7a8b9c0d1e2",
"publishedMarkdown": "",
"publishedVersion": 0,
"slug": "headless-cms-pricing",
"status": "drafting",
"subtitle": "",
"teamId": "66f0b2c4d5e6f7a8b9c0d1e1",
"title": "Headless CMS pricing",
"updatedAt": "2026-10-08T09:12:44.000Z",
"version": 7,
"wordCount": 11,
"review": {
"feedback": "Add a pricing table and cite the survey.",
"feedbackAt": "2026-10-09T15:30:00.000Z",
"feedbackBy": {
"id": "66f0b2c4d5e6f7a8b9c0d1f0",
"name": "Maja Lind",
"type": "user"
},
"message": "Ready for review. I left the pricing table for last.",
"submittedAt": "2026-10-09T11:00:00.000Z",
"submittedBy": {
"agent": "Claude Code",
"id": "6703f6a7b8c9d0e1f2a3b4c5",
"name": "Writing agent",
"type": "token"
}
}
}

Approve#

POST/documents/:id/approve

Approves a document in review: publishes it now, or schedules it when publishAt is in the future. The document needs a title and a slug.

Path parameters
idstringrequired
Body
publishAtstring | null
Errors
NotInReview409
TitleRequired422
SlugRequired422
PublishAtInvalid422
NotFound404
curl -X POST "https://api.pmkin.io/documents/6704a1f0c2b3d4e5f6a7b8c9/approve" \
-H "Authorization: Bearer $PMKIN_MANAGEMENT_TOKEN" \
-H "Content-Type: application/json" \
-d '{}'
Response: 200 OK
{
"assigneeId": "66f0b2c4d5e6f7a8b9c0d1f0",
"authorId": "66f0b2c4d5e6f7a8b9c0d1f0",
"categoryId": "6701c3d4e5f6a7b8c9d0e1f2",
"clusterId": "6702d4e5f6a7b8c9d0e1f2a3",
"content": "# Headless CMS pricing\n\nWhat each plan costs, and when an upgrade pays off.\n",
"contentUpdatedAt": "2026-10-08T09:12:44.000Z",
"contentUpdatedBy": {
"agent": "Claude Code",
"id": "6703f6a7b8c9d0e1f2a3b4c5",
"name": "Writing agent",
"type": "token"
},
"coverImageUrl": null,
"dueDate": "2026-10-20",
"hasUnpublishedChanges": false,
"id": "6704a1f0c2b3d4e5f6a7b8c9",
"isPublished": true,
"metaDescription": "",
"metaTitle": "",
"projectId": "66f0b2c4d5e6f7a8b9c0d1e2",
"publishedMarkdown": "# Headless CMS pricing\n\nWhat each plan costs, and when an upgrade pays off.\n",
"publishedVersion": 7,
"slug": "headless-cms-pricing",
"status": "published",
"subtitle": "",
"teamId": "66f0b2c4d5e6f7a8b9c0d1e1",
"title": "Headless CMS pricing",
"updatedAt": "2026-10-08T09:12:44.000Z",
"version": 7,
"wordCount": 11,
"publishedAt": "2026-10-09T16:00:00.000Z"
}

Publish#

POST/documents/:id/publish

Publishes the current draft without review, setting the details you send first. Works from planned, drafting, review and published, so publishing again pushes new changes live.

Path parameters
idstringrequired
Body
titlestringrequired
slugstringrequired
publishAtstring | null
categoryIdstring | null
excerptstring
publishedAtstring
subtitlestring
Errors
PublishNotAllowed409
PublishAtPast422
PublishAtInvalid422
HttpApiDecodeError400
NotFound404
curl -X POST "https://api.pmkin.io/documents/6704a1f0c2b3d4e5f6a7b8c9/publish" \
-H "Authorization: Bearer $PMKIN_MANAGEMENT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"slug": "headless-cms-pricing",
"title": "Headless CMS pricing"
}'
Response: 200 OK
{
"assigneeId": "66f0b2c4d5e6f7a8b9c0d1f0",
"authorId": "66f0b2c4d5e6f7a8b9c0d1f0",
"categoryId": "6701c3d4e5f6a7b8c9d0e1f2",
"clusterId": "6702d4e5f6a7b8c9d0e1f2a3",
"content": "# Headless CMS pricing\n\nWhat each plan costs, and when an upgrade pays off.\n",
"contentUpdatedAt": "2026-10-08T09:12:44.000Z",
"contentUpdatedBy": {
"agent": "Claude Code",
"id": "6703f6a7b8c9d0e1f2a3b4c5",
"name": "Writing agent",
"type": "token"
},
"coverImageUrl": null,
"dueDate": "2026-10-20",
"hasUnpublishedChanges": false,
"id": "6704a1f0c2b3d4e5f6a7b8c9",
"isPublished": true,
"metaDescription": "",
"metaTitle": "",
"projectId": "66f0b2c4d5e6f7a8b9c0d1e2",
"publishedMarkdown": "# Headless CMS pricing\n\nWhat each plan costs, and when an upgrade pays off.\n",
"publishedVersion": 7,
"slug": "headless-cms-pricing",
"status": "published",
"subtitle": "",
"teamId": "66f0b2c4d5e6f7a8b9c0d1e1",
"title": "Headless CMS pricing",
"updatedAt": "2026-10-08T09:12:44.000Z",
"version": 7,
"wordCount": 11,
"publishedAt": "2026-10-09T16:00:00.000Z"
}

Schedule#

POST/documents/:id/schedule

Schedules the current version to publish at publishAt. Later edits to the draft don’t change what publishes; schedule again to publish a newer version. Works from planned, drafting, review, published and scheduled. The document needs a title and a slug.

Path parameters
idstringrequired
Body
publishAtstringrequired
Errors
ScheduleNotAllowed409
PublishAtPast422
PublishAtInvalid422
TitleRequired422
NotFound404
curl -X POST "https://api.pmkin.io/documents/6704a1f0c2b3d4e5f6a7b8c9/schedule" \
-H "Authorization: Bearer $PMKIN_MANAGEMENT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"publishAt": "2026-10-20T09:00:00Z"
}'
Response: 200 OK
{
"assigneeId": "66f0b2c4d5e6f7a8b9c0d1f0",
"authorId": "66f0b2c4d5e6f7a8b9c0d1f0",
"categoryId": "6701c3d4e5f6a7b8c9d0e1f2",
"clusterId": "6702d4e5f6a7b8c9d0e1f2a3",
"content": "# Headless CMS pricing\n\nWhat each plan costs, and when an upgrade pays off.\n",
"contentUpdatedAt": "2026-10-08T09:12:44.000Z",
"contentUpdatedBy": {
"agent": "Claude Code",
"id": "6703f6a7b8c9d0e1f2a3b4c5",
"name": "Writing agent",
"type": "token"
},
"coverImageUrl": null,
"dueDate": "2026-10-20",
"hasUnpublishedChanges": false,
"id": "6704a1f0c2b3d4e5f6a7b8c9",
"isPublished": false,
"metaDescription": "",
"metaTitle": "",
"projectId": "66f0b2c4d5e6f7a8b9c0d1e2",
"publishedMarkdown": "",
"publishedVersion": 0,
"slug": "headless-cms-pricing",
"status": "scheduled",
"subtitle": "",
"teamId": "66f0b2c4d5e6f7a8b9c0d1e1",
"title": "Headless CMS pricing",
"updatedAt": "2026-10-08T09:12:44.000Z",
"version": 7,
"wordCount": 11,
"publishAt": "2026-10-20T09:00:00Z",
"scheduledVersion": 7
}

Unschedule#

POST/documents/:id/unschedule

Cancels a schedule.

Path parameters
idstringrequired
Body
statusstring
Errors
NotScheduled409
UnscheduleStatusInvalid422
NotFound404
curl -X POST "https://api.pmkin.io/documents/6704a1f0c2b3d4e5f6a7b8c9/unschedule" \
-H "Authorization: Bearer $PMKIN_MANAGEMENT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"status": "review"
}'
Response: 200 OK
{
"assigneeId": "66f0b2c4d5e6f7a8b9c0d1f0",
"authorId": "66f0b2c4d5e6f7a8b9c0d1f0",
"categoryId": "6701c3d4e5f6a7b8c9d0e1f2",
"clusterId": "6702d4e5f6a7b8c9d0e1f2a3",
"content": "# Headless CMS pricing\n\nWhat each plan costs, and when an upgrade pays off.\n",
"contentUpdatedAt": "2026-10-08T09:12:44.000Z",
"contentUpdatedBy": {
"agent": "Claude Code",
"id": "6703f6a7b8c9d0e1f2a3b4c5",
"name": "Writing agent",
"type": "token"
},
"coverImageUrl": null,
"dueDate": "2026-10-20",
"hasUnpublishedChanges": false,
"id": "6704a1f0c2b3d4e5f6a7b8c9",
"isPublished": false,
"metaDescription": "",
"metaTitle": "",
"projectId": "66f0b2c4d5e6f7a8b9c0d1e2",
"publishedMarkdown": "",
"publishedVersion": 0,
"slug": "headless-cms-pricing",
"status": "review",
"subtitle": "",
"teamId": "66f0b2c4d5e6f7a8b9c0d1e1",
"title": "Headless CMS pricing",
"updatedAt": "2026-10-08T09:12:44.000Z",
"version": 7,
"wordCount": 11
}

Unpublish#

POST/documents/:id/unpublish

Takes the document off your site and moves it to drafting. A scheduled document loses its schedule too. The content stays.

Path parameters
idstringrequired
Errors
NotFound404
curl -X POST "https://api.pmkin.io/documents/6704a1f0c2b3d4e5f6a7b8c9/unpublish" \
-H "Authorization: Bearer $PMKIN_MANAGEMENT_TOKEN"
Response: 200 OK
{
"assigneeId": "66f0b2c4d5e6f7a8b9c0d1f0",
"authorId": "66f0b2c4d5e6f7a8b9c0d1f0",
"categoryId": "6701c3d4e5f6a7b8c9d0e1f2",
"clusterId": "6702d4e5f6a7b8c9d0e1f2a3",
"content": "# Headless CMS pricing\n\nWhat each plan costs, and when an upgrade pays off.\n",
"contentUpdatedAt": "2026-10-08T09:12:44.000Z",
"contentUpdatedBy": {
"agent": "Claude Code",
"id": "6703f6a7b8c9d0e1f2a3b4c5",
"name": "Writing agent",
"type": "token"
},
"coverImageUrl": null,
"dueDate": "2026-10-20",
"hasUnpublishedChanges": false,
"id": "6704a1f0c2b3d4e5f6a7b8c9",
"isPublished": false,
"metaDescription": "",
"metaTitle": "",
"projectId": "66f0b2c4d5e6f7a8b9c0d1e2",
"publishedMarkdown": "",
"publishedVersion": 0,
"slug": "headless-cms-pricing",
"status": "drafting",
"subtitle": "",
"teamId": "66f0b2c4d5e6f7a8b9c0d1e1",
"title": "Headless CMS pricing",
"updatedAt": "2026-10-08T09:12:44.000Z",
"version": 7,
"wordCount": 11
}