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- The document’s id.
titlestring- The title.
slugstring- The URL slug. Empty until you set one.
statusstring- idea, planned, drafting, review, scheduled or published.
contentstring- The draft, as markdown.
versioninteger- The draft’s version. It goes up with every content write. Send it as baseVersion.
isPublishedboolean- Whether the document is live on your site.
publishedMarkdownstring- The markdown readers see.
publishedVersioninteger- The version that’s live, or 0.
hasUnpublishedChangesboolean- True when the document is published and the draft has changed since.
wordCountinteger- The words in the draft.
assigneeId, categoryId, clusterIdstring | null- Who the document is assigned to, its category and its cluster.
dueDatestring | null- The due date, YYYY-MM-DD.
subtitle, excerpt, coverImageUrl, metaTitle, metaDescriptionstring- Subtitle, excerpt, cover image and SEO fields. excerpt is left out until it’s set.
publishedAt, publishAt, scheduledVersionoptional- The publish date your site shows, and the time a scheduled document publishes, with the version it will publish.
contentUpdatedBy, contentUpdatedAtoptional- Who last changed the content (a user, a token or the system, with the agent’s name for MCP clients), and when.
briefobject- The brief, when the document has one. See Briefs.
reviewobject- The latest submission for review: who submitted it and their message, and the reviewer’s feedback.
authorId, projectId, teamIdstring- The ids of the author, project and team.
updatedAtstring- When the document last changed.
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#
/documentsLists the project’s documents as summaries, without content. Deleted documents are left out. Filters combine: a document must match all of them.
statusstring- Statuses separated by commas:
idea,planned,drafting,review,scheduled,published. assigneeIdstring- A team member’s id, or
nonefor unassigned documents. categoryIdstring- A category id, or
nonefor documents without one. clusterIdstring- A cluster id, or
nonefor documents without one. briefStatestring- Brief states separated by commas:
none,ready,claimed,drafted.noneincludes documents without a brief. dueAfterstring- Due on or after this date,
YYYY-MM-DD. dueBeforestring- Due on or before this date,
YYYY-MM-DD. qstring- Text to find in titles, ignoring case. At most 200 characters.
limitinteger- How many to return, 1 to 100. Defaults to 100.
offsetinteger- How many to skip, 0 to 100,000. Defaults to 0.
HttpApiDecodeError400- A filter or paging value is invalid, such as
limit=500ordueAfter=next week.
curl "https://api.pmkin.io/documents?limit=20&status=drafting,review" \-H "Authorization: Bearer $PMKIN_MANAGEMENT_TOKEN"
[{"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#
/documents/:idReturns the whole document: its draft content, the publishedMarkdown readers see, and version, which you pass as baseVersion to your next content write.
idstringrequired- The document’s id.
NotFound404- No document with this id in the token’s project, or it was deleted.
curl "https://api.pmkin.io/documents/6704a1f0c2b3d4e5f6a7b8c9" \-H "Authorization: Bearer $PMKIN_MANAGEMENT_TOKEN"
{"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#
/documents/:idChanges the fields you send and leaves the rest alone. It doesn’t touch the content and doesn’t write a revision.
idstringrequired- The document’s id.
assigneeIdstring | null- A team member’s id from
GET /members.nullunassigns the document. clusterIdstring | null- A cluster’s id from
GET /clusters.nulltakes the document out of its cluster. dueDatestring | null- The due date,
YYYY-MM-DD.nullclears it. statusstringidea,plannedordrafting. Use the workflow endpoints for review, scheduling and publishing. Moving a document in review back to one of these works like requesting changes.categoryIdstring | null- The category’s id from
GET /categories.nulltakes the document out of its category. excerptstring- A short summary for lists and previews.
publishedAtstring- The publish date your site shows, as an ISO 8601 timestamp.
slugstring- The document’s URL slug.
subtitlestring- A subtitle shown under the title.
titlestring- The document’s title.
StatusLocked409- Changing the status of a published or scheduled document. Unpublish or unschedule it first.
StatusRequiresReview422- Setting
statustoreview. UsePOST /documents/:id/submit. StatusRequiresPublish422- Setting
statustopublishedorscheduled. Use publish, approve or schedule. StatusInvalid422statusisn’t a known status.ScheduledNeedsTitleAndSlug422- Clearing the title or slug of a scheduled document.
BadRequest422- The assignee isn’t on the project’s team, or the category or cluster isn’t in this project. The message says which.
NotFound404- No document with this id in the token’s project, or it was deleted.
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"}'
{"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#
/documents/:id/metadataSets the cover image and SEO fields. Fields you leave out stay as they are.
idstringrequired- The document’s id.
coverImageUrlstring | null- The cover image’s URL.
nullremoves it. Upload images in pmkin or with the MCP image tools. metaDescriptionstring- The description search engines show.
metaTitlestring- The title search engines show.
NotFound404- No document with this id in the token’s project, or it was deleted.
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"}'
{"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#
/documents/:idMoves 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.
idstringrequired- The document’s id.
NotFound404- No document with this id in the token’s project, or it was deleted.
curl -X DELETE "https://api.pmkin.io/documents/6704a1f0c2b3d4e5f6a7b8c9" \-H "Authorization: Bearer $PMKIN_MANAGEMENT_TOKEN"
{"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#
/documents/:id/restoreRestores a deleted document.
idstringrequired- The document’s id.
NotFound404- No deleted document with this id in the token’s project.
curl -X POST "https://api.pmkin.io/documents/6704a1f0c2b3d4e5f6a7b8c9/restore" \-H "Authorization: Bearer $PMKIN_MANAGEMENT_TOKEN"
{"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}
POST /documents/:id/restore. Until then it’s left out of lists and the delivery API.