Management API

Documents

List, read, update, delete and restore documents.

A document is one piece of content: a blog post, a guide, a landing page. It has a draft you edit (content) and, once published, the version readers see (publishedMarkdown). Both are GitHub Flavored Markdown. To create a document, confirm a document intent.

The document object#

idstring
titlestring
slugstring
statusstring
contentstring
versioninteger
isPublishedboolean
publishedMarkdownstring
publishedVersioninteger
hasUnpublishedChangesboolean
wordCountinteger
assigneeId, categoryId, clusterIdstring | null
dueDatestring | null
subtitle, excerpt, coverImageUrl, metaTitle, metaDescriptionstring
publishedAt, publishAt, scheduledVersionoptional
contentUpdatedBy, contentUpdatedAtoptional
briefobject
reviewobject
authorId, projectId, teamIdstring
updatedAtstring

Lists return summaries instead: id, title, slug, status, isPublished, wordCount, assigneeId, categoryId, clusterId, dueDate, and when present briefState, publishAt, contentUpdatedBy and updatedAt.

Endpoints#

List documents#

GET/documents

Lists the project’s documents as summaries, without content. Deleted documents are left out. Filters combine: a document must match all of them.

Query parameters
statusstring
assigneeIdstring
categoryIdstring
clusterIdstring
briefStatestring
dueAfterstring
dueBeforestring
qstring
limitinteger
offsetinteger
Errors
HttpApiDecodeError400
curl "https://api.pmkin.io/documents?limit=20&status=drafting,review" \
-H "Authorization: Bearer $PMKIN_MANAGEMENT_TOKEN"
Response: 200 OK
[
{
"assigneeId": "66f0b2c4d5e6f7a8b9c0d1f0",
"briefState": "claimed",
"categoryId": "6701c3d4e5f6a7b8c9d0e1f2",
"clusterId": "6702d4e5f6a7b8c9d0e1f2a3",
"contentUpdatedBy": {
"agent": "Claude Code",
"id": "6703f6a7b8c9d0e1f2a3b4c5",
"name": "Writing agent",
"type": "token"
},
"dueDate": "2026-10-20",
"id": "6704a1f0c2b3d4e5f6a7b8c9",
"isPublished": false,
"slug": "headless-cms-pricing",
"status": "drafting",
"title": "Headless CMS pricing",
"updatedAt": "2026-10-08T09:12:44.000Z",
"wordCount": 11
}
]

Get a document#

GET/documents/:id

Returns the whole document: its draft content, the publishedMarkdown readers see, and version, which you pass as baseVersion to your next content write.

Path parameters
idstringrequired
Errors
NotFound404
curl "https://api.pmkin.io/documents/6704a1f0c2b3d4e5f6a7b8c9" \
-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,
"brief": {
"audience": "Marketing leads comparing headless CMS plans",
"claimedAt": "2026-10-07T10:04:00.000Z",
"claimedBy": {
"agent": "Claude Code",
"id": "6703f6a7b8c9d0e1f2a3b4c5",
"name": "Writing agent",
"type": "token"
},
"intent": "commercial",
"internalLinks": [
"66fe91a2b3c4d5e6f7a8b9c0"
],
"keyword": "headless cms pricing",
"notes": "Use list prices from October 2026.",
"outline": "Who each plan is for\nWhat it costs as you grow\nWhen to upgrade",
"referenceUrls": [
"https://example.com/cms-pricing-survey"
],
"state": "claimed",
"wordCount": "1,500–2,000"
}
}

Update a document#

PATCH/documents/:id

Changes the fields you send and leaves the rest alone. It doesn’t touch the content and doesn’t write a revision.

Path parameters
idstringrequired
Body
assigneeIdstring | null
clusterIdstring | null
dueDatestring | null
statusstring
categoryIdstring | null
excerptstring
publishedAtstring
slugstring
subtitlestring
titlestring
Errors
StatusLocked409
StatusRequiresReview422
StatusRequiresPublish422
StatusInvalid422
ScheduledNeedsTitleAndSlug422
BadRequest422
NotFound404
curl -X PATCH "https://api.pmkin.io/documents/6704a1f0c2b3d4e5f6a7b8c9" \
-H "Authorization: Bearer $PMKIN_MANAGEMENT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"assigneeId": "66f0b2c4d5e6f7a8b9c0d1f0",
"dueDate": "2026-10-20",
"status": "planned"
}'
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": "planned",
"subtitle": "",
"teamId": "66f0b2c4d5e6f7a8b9c0d1e1",
"title": "Headless CMS pricing",
"updatedAt": "2026-10-08T09:12:44.000Z",
"version": 7,
"wordCount": 11
}

Update metadata#

PATCH/documents/:id/metadata

Sets the cover image and SEO fields. Fields you leave out stay as they are.

Path parameters
idstringrequired
Body
coverImageUrlstring | null
metaDescriptionstring
metaTitlestring
Errors
NotFound404
curl -X PATCH "https://api.pmkin.io/documents/6704a1f0c2b3d4e5f6a7b8c9/metadata" \
-H "Authorization: Bearer $PMKIN_MANAGEMENT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"metaDescription": "What each headless CMS plan costs, and when an upgrade pays off.",
"metaTitle": "Headless CMS pricing compared"
}'
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": "What each headless CMS plan costs, and when an upgrade pays off.",
"metaTitle": "Headless CMS pricing compared",
"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
}

Delete a document#

DELETE/documents/:id

Moves the document to the trash. It leaves every list and the delivery API until you restore it. A scheduled document loses its schedule and goes back to drafting.

The response is the deleted document, with deletedAt.

Path parameters
idstringrequired
Errors
NotFound404
curl -X DELETE "https://api.pmkin.io/documents/6704a1f0c2b3d4e5f6a7b8c9" \
-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,
"deletedAt": "2026-10-09T16:20:00.000Z"
}

Restore a deleted document#

POST/documents/:id/restore

Restores a deleted document.

Path parameters
idstringrequired
Errors
NotFound404
curl -X POST "https://api.pmkin.io/documents/6704a1f0c2b3d4e5f6a7b8c9/restore" \
-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
}
Deleted documents
A deleted document isn’t gone: restore it with POST /documents/:id/restore. Until then it’s left out of lists and the delivery API.