Developers
Documents API
List, read, create and update documents, and avoid overwriting a newer edit.
ReferenceContent reviewed
On this page
Use the Documentation API to list, read, create and update documents. Establish a session first.
Access requirements#
| Endpoint | Component gate | Additional requirement |
|---|---|---|
GET /api/documentation/documents | docs.documents: view | Only accessible records are returned. |
GET /api/documentation/documents/:id | view | Read access to the document. |
POST /api/documentation/documents | write | Destination access and permitted fields. |
PUT /api/documentation/documents/:id | write | Document write access; audience changes can require admin access. |
DELETE /api/documentation/documents/:id | write | Administrative access to this document. |
GET /api/documentation/documents/:id/versions | view | Access to the document. |
POST /api/documentation/documents/:id/versions/:versionNumber/restore | write | Access required to restore the document. |
GET /api/documentation/folders | view | Only accessible folders are returned. |
All levels refer to docs.documents. See Permissions.
List documents#
GET /api/documentation/documents
| Query | Meaning |
|---|---|
page | Defaults to 1; minimum 1. |
limit | Defaults to 20; constrained to 1–200. |
status | draft, review, published or archived. |
visibility | private, department, project or public. |
search | Search titles and text. |
tags | Comma-separated tags. |
departmentId | Restrict to a department within your accessible scope. |
sortBy | created_at, updated_at, title or status; default updated_at. |
sortOrder | asc or desc; default desc. |
includeContent | Include bodies when true; false by default. |
const response = await fetch(
"/api/documentation/documents?status=published&limit=20",
{ credentials: "same-origin" },
);
if (!response.ok) throw new Error(`Document list: ${response.status}`);
const { documents, pagination } = await response.json();Use pagination.hasMore to check for another page. Do not assume the default response includes an exact total.
Create a document#
POST /api/documentation/documents requires a title.
| Field | Type | Meaning |
|---|---|---|
title | string | Document title. |
content | string | Body. |
content_type | string | html, markdown or plain. |
summary | string | Short description. |
status | string | Lifecycle state, subject to workflow checks. |
visibility | string | Intended audience, subject to access checks. |
folder_id | string | Destination folder identifier. |
tags | string array | Labels. |
This function uses the caller's content to create a private draft.
async function createDraft(title, markdown) {
const response = await fetch("/api/documentation/documents", {
method: "POST",
credentials: "same-origin",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
title, content: markdown, content_type: "markdown",
status: "draft", visibility: "private",
}),
});
const result = await response.json();
if (!response.ok) throw new Error(result.error ?? "Create failed");
return result;
}Success returns HTTP 201 and the created document. Verify its identifier, audience and content. Internal public visibility does not mean internet publication; see Website guides.
Update without overwriting a newer edit#
Read the document first. Send its last-read updated_at as baseUpdatedAt.
async function updateTitle(document, title) {
const response = await fetch(
`/api/documentation/documents/${encodeURIComponent(document.id)}`,
{
method: "PUT",
credentials: "same-origin",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
title, baseUpdatedAt: document.updated_at,
}),
},
);
const result = await response.json();
if (response.status === 409 && result.code === "DOCUMENT_CONFLICT") {
return { conflict: true, currentUpdatedAt: result.currentUpdatedAt };
}
if (!response.ok) throw new Error(result.error ?? "Update failed");
return { conflict: false, document: result };
}Recover from DOCUMENT_CONFLICT#
| HTTP 409 field | Value or type |
|---|---|
success | false |
code | DOCUMENT_CONFLICT |
error | Description of the concurrent modification. |
currentUpdatedAt | Current timestamp, or null if unavailable. |
- Preserve your unsaved changes.
- Fetch the latest document.
- Reconcile your changes with the latest content.
- Send the merged update with the new document's
updated_at. - Handle another conflict if someone saves again.
Do not only replace the timestamp and resend stale content; that discards the other person's changes.
Deletion and failures#
Deletion requires administrative access to the target document. Confirm the target and child-document implications before calling it. A 403 can mean missing component access or insufficient document access. Read Errors and rate limits before adding automatic retries.
Need more help?
Can’t find what you need? Talk to the team.
To report a problem with this guide, include its title and the step that blocked you.