Management API

Intents

Create documents, clusters and categories through drafts you confirm.

Documents, clusters and categories are created through drafts, called intents. Start one with the fields you know, fill in the rest over as many requests as you need, then confirm it. Confirming checks every field and either creates the record or lists every problem at once.

  • Each token has its own drafts. Other tokens’ drafts answer 404.
  • Drafts never expire. Discard the ones you don’t need.
  • A token can have at most 100 unfinished drafts per project.
  • Send fields at the top level of the body. null clears a field.

Fields#

Document intents#

titlestring | null
statusstring | null
slugstring | null
markdownstring | null
briefobject | null
assigneeIdstring | null
categoryIdstring | null
clusterIdstring | null
dueDatestring | null

Cluster intents#

namestring | null
descriptionstring | null
keywordsstring[] | null

A project can have at most 200 clusters.

Category intents#

namestring | null
slugstring | null
descriptionstring | null
categoryIdstring | null

Endpoints#

The endpoints are the same for every kind. Replace {kind} with document, cluster or category, as in /document-intents.

Create a draft#

POST/{kind}-intents

Starts a draft with the fields you send. Only types and lengths are checked now; everything else is checked when you confirm. Answers 201.

Path parameters
kindstringrequired
Errors
BadRequest422
HttpApiDecodeError400
curl -X POST "https://api.pmkin.io/document-intents" \
-H "Authorization: Bearer $PMKIN_MANAGEMENT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"brief": {
"intent": "commercial",
"keyword": "headless cms pricing"
},
"clusterId": "6702d4e5f6a7b8c9d0e1f2a3",
"status": "idea",
"title": "Headless CMS pricing"
}'
Response: 201 Created
{
"createdAt": "2026-10-09T08:00:00.000Z",
"createdBy": {
"name": "Writing agent",
"type": "token"
},
"fields": {
"brief": {
"intent": "commercial",
"keyword": "headless cms pricing"
},
"clusterId": "6702d4e5f6a7b8c9d0e1f2a3",
"status": "idea",
"title": "Headless CMS pricing"
},
"id": "6705e6f7a8b9c0d1e2f3a4b5",
"kind": "document",
"updatedAt": "2026-10-09T08:00:00.000Z"
}

List drafts#

GET/{kind}-intents

Lists the calling token’s drafts of this kind, most recently updated first, at most 100. Document drafts leave out markdown; get one draft to read it.

Path parameters
kindstringrequired
curl "https://api.pmkin.io/document-intents" \
-H "Authorization: Bearer $PMKIN_MANAGEMENT_TOKEN"
Response: 200 OK
[
{
"createdAt": "2026-10-09T08:00:00.000Z",
"createdBy": {
"name": "Writing agent",
"type": "token"
},
"fields": {
"brief": {
"intent": "commercial",
"keyword": "headless cms pricing"
},
"clusterId": "6702d4e5f6a7b8c9d0e1f2a3",
"status": "idea",
"title": "Headless CMS pricing"
},
"id": "6705e6f7a8b9c0d1e2f3a4b5",
"kind": "document",
"updatedAt": "2026-10-09T08:00:00.000Z"
}
]

Get a draft#

GET/{kind}-intents/:id

Returns one draft with every field.

Path parameters
kindstringrequired
idstringrequired
Errors
NotFound404
curl "https://api.pmkin.io/document-intents/6705e6f7a8b9c0d1e2f3a4b5" \
-H "Authorization: Bearer $PMKIN_MANAGEMENT_TOKEN"
Response: 200 OK
{
"createdAt": "2026-10-09T08:00:00.000Z",
"createdBy": {
"name": "Writing agent",
"type": "token"
},
"fields": {
"brief": {
"intent": "commercial",
"keyword": "headless cms pricing"
},
"clusterId": "6702d4e5f6a7b8c9d0e1f2a3",
"status": "idea",
"title": "Headless CMS pricing"
},
"id": "6705e6f7a8b9c0d1e2f3a4b5",
"kind": "document",
"updatedAt": "2026-10-09T08:00:00.000Z"
}

Update a draft#

PATCH/{kind}-intents/:id

Sets the fields you send and leaves the others alone. null clears a field.

Path parameters
kindstringrequired
idstringrequired
Errors
NotFound404
HttpApiDecodeError400
curl -X PATCH "https://api.pmkin.io/document-intents/6705e6f7a8b9c0d1e2f3a4b5" \
-H "Authorization: Bearer $PMKIN_MANAGEMENT_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"dueDate": "2026-10-20"
}'
Response: 200 OK
{
"createdAt": "2026-10-09T08:00:00.000Z",
"createdBy": {
"name": "Writing agent",
"type": "token"
},
"fields": {
"brief": {
"intent": "commercial",
"keyword": "headless cms pricing"
},
"clusterId": "6702d4e5f6a7b8c9d0e1f2a3",
"status": "idea",
"title": "Headless CMS pricing",
"dueDate": "2026-10-20"
},
"id": "6705e6f7a8b9c0d1e2f3a4b5",
"kind": "document",
"updatedAt": "2026-10-09T08:05:00.000Z"
}

Discard a draft#

DELETE/{kind}-intents/:id

Discards the draft and returns it.

Path parameters
kindstringrequired
idstringrequired
Errors
NotFound404
curl -X DELETE "https://api.pmkin.io/document-intents/6705e6f7a8b9c0d1e2f3a4b5" \
-H "Authorization: Bearer $PMKIN_MANAGEMENT_TOKEN"
Response: 200 OK
{
"createdAt": "2026-10-09T08:00:00.000Z",
"createdBy": {
"name": "Writing agent",
"type": "token"
},
"fields": {
"brief": {
"intent": "commercial",
"keyword": "headless cms pricing"
},
"clusterId": "6702d4e5f6a7b8c9d0e1f2a3",
"status": "idea",
"title": "Headless CMS pricing"
},
"id": "6705e6f7a8b9c0d1e2f3a4b5",
"kind": "document",
"updatedAt": "2026-10-09T08:00:00.000Z"
}

Confirm a draft#

POST/{kind}-intents/:id/confirm

Checks every field and creates the document, cluster or category. When anything is wrong, nothing changes, the draft stays, and the 422 lists every problem at once, sorted by field. On success the draft is deleted and the response, a 201, holds the new record under its kind (document, cluster or category) and intentId.

Path parameters
kindstringrequired
idstringrequired
Errors
IntentInvalid422
NotFound404
curl -X POST "https://api.pmkin.io/document-intents/6705e6f7a8b9c0d1e2f3a4b5/confirm" \
-H "Authorization: Bearer $PMKIN_MANAGEMENT_TOKEN"
Response: 201 Created
{
"document": {
"assigneeId": "66f0b2c4d5e6f7a8b9c0d1f0",
"authorId": "66f0b2c4d5e6f7a8b9c0d1f0",
"categoryId": "6701c3d4e5f6a7b8c9d0e1f2",
"clusterId": "6702d4e5f6a7b8c9d0e1f2a3",
"content": "",
"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": "idea",
"subtitle": "",
"teamId": "66f0b2c4d5e6f7a8b9c0d1e1",
"title": "Headless CMS pricing",
"updatedAt": "2026-10-08T09:12:44.000Z",
"version": 0,
"wordCount": 0,
"brief": {
"audience": "Marketing leads comparing headless CMS plans",
"claimedAt": null,
"claimedBy": null,
"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": "none",
"wordCount": "1,500–2,000"
}
},
"intentId": "6705e6f7a8b9c0d1e2f3a4b5"
}
A document with a brief is an idea
To plan work for agents, create document intents with a brief and status idea or planned, confirm them, then mark each brief ready.