Wiki
The project knowledge base — spaces, the page tree, version history, edit locks, comments, attachments, full-text search and the trash.
The wiki is the project's internal knowledge base. It is organised into spaces, and each space holds a tree of pages. Every save that changes a page's title or content creates a new version. Deleted pages go to the trash and can be restored together with their sub-pages.
Two people editing the same page are coordinated by an edit lock: a short-lived claim that an editor renews while the page is open. The lock is advisory. Saving does not check it, so a client that edits pages should acquire it first.
Field types follow the field notation.
Access
Every endpoint on this page requires both the projects and wiki OAuth scopes. The user must be a member of the
project, and the owner's subscription must be active. Otherwise the endpoint returns 404 RES_NOT_FOUND. The project
owner bypasses permission checks.
| Permission | Grants |
|---|---|
can_view_wiki |
Read spaces, pages, versions, attachments, search and the trash |
can_edit_wiki |
Create, edit, move, delete and restore spaces and pages; manage locks and attachments |
can_view_wiki_comment |
Read comments (together with can_view_wiki) |
can_edit_wiki_comment |
Write comments (together with can_view_wiki) |
Space Object
Space Structure
| Field | Type | Description |
|---|---|---|
| uuid | uuid | Space ID |
| owner_uuid | uuid | Who owns the space; initially its creator |
| name | string | Name, 1–255 characters |
| description | string | Description |
| page_count | integer | Number of pages, not counting the trash. Only in List Spaces |
| created_at | ISO8601 datetime | When the space was created |
| updated_at | ISO8601 datetime | When the space was last changed |
List Spaces
GET /api/v1/projects/{project.uuid}/wiki/spaces
Returns the project's spaces, sorted by name. Requires can_view_wiki.
Get Space
GET /api/v1/projects/{project.uuid}/wiki/spaces/{space.uuid}
Requires can_view_wiki.
Create Space
POST /api/v1/projects/{project.uuid}/wiki/spaces
| Field | Type | Description |
|---|---|---|
| name | string | 1–255 characters |
| description? | string | Default "" |
201 Created with {"uuid": "..."}. Requires can_edit_wiki.
Modify Space
PATCH /api/v1/projects/{project.uuid}/wiki/spaces/{space.uuid}
Updates any of name, description, owner_uuid (a project member). At least one must be present. PUT requires all
three. An owner_uuid that is not a member fails with 400 RES_NOT_FOUND.
204 No Content. Requires can_edit_wiki.
Delete Space
DELETE /api/v1/projects/{project.uuid}/wiki/spaces/{space.uuid}
Deletes the space and moves all its pages to the trash. A deleted space cannot be restored through the API, and its
pages no longer appear in the trash or in search. 204 No Content. Requires can_edit_wiki.
Page Object
Page Structure
| Field | Type | Description |
|---|---|---|
| uuid | uuid | Page ID |
| space_uuid | uuid | The space. Only in Get Page |
| parent_uuid | ?uuid | Parent page; null for a top-level page |
| title | string | Title, 1–512 characters |
| slug | string | URL-friendly title, unique within the space; regenerated when the title changes |
| content | string | Page body as Markdown. Only in Get Page |
| position | integer | Order among siblings, ascending |
| author_uuid | uuid | Who created the page |
| updated_by_uuid | uuid | Who last changed it |
| breadcrumbs | array | {uuid, title} from the top-level ancestor down to this page. Only in Get Page |
| created_at | ISO8601 datetime | When the page was created |
| updated_at | ISO8601 datetime | When the page was last changed |
Example Page
{
"uuid": "0199ad49-6071-7283-9405-a6b7c8d9e0f1",
"space_uuid": "0199ad40-0000-7000-8000-000000000001",
"parent_uuid": "0199ad48-0000-7000-8000-000000000001",
"title": "Cutting fabric",
"slug": "cutting-fabric",
"content": "## Allowances\n\nAdd 200 mm to the height for the roll.",
"position": 0,
"author_uuid": "0198e7aa-91f0-7c22-a4d1-0f9e8d7c6b5a",
"updated_by_uuid": "0198e7aa-91f0-7c22-a4d1-0f9e8d7c6b5a",
"breadcrumbs": [
{
"uuid": "0199ad48-0000-7000-8000-000000000001",
"title": "Production"
},
{
"uuid": "0199ad49-6071-7283-9405-a6b7c8d9e0f1",
"title": "Cutting fabric"
}
],
"created_at": "2026-09-02T10:00:00.000Z",
"updated_at": "2026-09-15T13:20:00.000Z"
}
List Space Pages
GET /api/v1/projects/{project.uuid}/wiki/spaces/{space.uuid}/pages
Returns every page of the space as a flat list, without content, sorted by position then title. Build the tree
from parent_uuid. Requires can_view_wiki.
Get Page
GET /api/v1/projects/{project.uuid}/wiki/pages/{page.uuid}
Returns the full page with content and breadcrumbs. Requires can_view_wiki.
Create Page
POST /api/v1/projects/{project.uuid}/wiki/spaces/{space.uuid}/pages
Creates a page and its first version. Requires can_edit_wiki.
JSON Params
| Field | Type | Description |
|---|---|---|
| title | string | 1–512 characters |
| content? | string | Markdown. Default "" |
| parent_uuid? | ?uuid | Parent page in the same space. Default null (top level) |
| position? | integer | Default: after the last sibling |
Response
201 Created with {"uuid": "..."}.
Modify Page
PATCH /api/v1/projects/{project.uuid}/wiki/pages/{page.uuid}
Updates any of title, content, parent_uuid, position. At least one must be present. A new version is created
only if the title or content actually changed. A new parent must be in the same space and cannot be the page itself or
one of its descendants.
Acquire the edit lock before saving.
PUT on the same path requires all four fields; parent_uuid may be null.
204 No Content. Requires can_edit_wiki.
Move Page
POST /api/v1/projects/{project.uuid}/wiki/pages/{page.uuid}/move
Moves a page within its space. Its sub-pages move with it. Does not create a version.
| Field | Type | Description |
|---|---|---|
| parent_uuid | ?uuid | New parent, or null for the top level. Required |
| position? | integer | Default: after the last sibling under the new parent |
Positions of other pages are not shifted; send explicit positions for every sibling you reorder.
204 No Content. Requires can_edit_wiki.
Delete Page
DELETE /api/v1/projects/{project.uuid}/wiki/pages/{page.uuid}
Moves the page and all its sub-pages to the trash. 204 No Content. Requires can_edit_wiki.
Trash
List Trash
GET /api/v1/projects/{project.uuid}/wiki/trash
Returns the pages deleted directly, newest first. Their sub-pages are in the trash too, but are not listed: they come
back with their parent. Pages of deleted spaces are not included. Requires can_view_wiki.
[
{
"uuid": "0199ad49-6071-7283-9405-a6b7c8d9e0f1",
"title": "Cutting fabric",
"space_uuid": "0199ad40-0000-7000-8000-000000000001",
"space_name": "Production",
"deleted_at": "2026-09-30T08:00:00.000Z",
"deleted_by_name": "Anna Petrova"
}
]
Restore Page
POST /api/v1/projects/{project.uuid}/wiki/pages/{page.uuid}/restore
Restores a page from the trash together with its deleted sub-pages. If its parent is still deleted, the page is
restored to the top level of the space. Requires can_edit_wiki.
200 OK with the restored page uuids:
{
"restored": [
"0199ad49-6071-7283-9405-a6b7c8d9e0f1",
"0199ad4a-0000-7000-8000-000000000002"
]
}
Versions
Version Structure
| Field | Type | Description |
|---|---|---|
| version_number | integer | 1, 2, 3, … |
| title | string | Title at that version |
| content | string | Content at that version. Only in Get Page Version |
| editor_uuid | uuid | Who saved it |
| editor_name | string | Their full name |
| created_at | ISO8601 datetime | When it was saved |
List Page Versions
GET /api/v1/projects/{project.uuid}/wiki/pages/{page.uuid}/versions
Returns versions newest first, without content. Requires can_view_wiki.
Get Page Version
GET /api/v1/projects/{project.uuid}/wiki/pages/{page.uuid}/versions/{version_number}
Requires can_view_wiki.
Restore Page Version
POST /api/v1/projects/{project.uuid}/wiki/pages/{page.uuid}/versions/{version_number}/restore
Sets the page's title and content to those of the version. History is not rewritten: this saves a new version
with that content. Requires can_edit_wiki.
200 OK:
{
"version_number": 8
}
Edit Lock
A lock lasts 45 seconds. An editor should acquire it when opening a page for editing, renew it more often than every 45 seconds while editing, and release it when done. A lock that is not renewed expires on its own.
Acquire Edit Lock
POST /api/v1/projects/{project.uuid}/wiki/pages/{page.uuid}/lock
Acquires the lock, or renews it if the user already holds it. Requires can_edit_wiki.
200 OK:
{
"expires_in": 45000
}
expires_in is in milliseconds. If another user holds the lock, the response is 409 WIKI_PAGE_LOCKED with the
holder:
{
"id": 5003,
"code": "WIKI_PAGE_LOCKED",
"message": "This wiki page is currently being edited by another user.",
"holder": {
"user_uuid": "0198f0b2-3c4d-7e5f-8a6b-7c8d9e0f1a2b",
"user_name": "Ivan Sidorov",
"acquired_at": 1790871200000
}
}
acquired_at is a Unix timestamp in milliseconds.
Release Edit Lock
DELETE /api/v1/projects/{project.uuid}/wiki/pages/{page.uuid}/lock
Releases the lock if the user holds it; otherwise does nothing. 204 No Content. Requires can_edit_wiki.
Comments
Comment Structure
| Field | Type | Description |
|---|---|---|
| uuid | uuid | Comment ID |
| body | string | Text, 1–4000 characters |
| user_uuid | uuid | Author |
| user_name | string | Author's full name |
| created_at | ISO8601 datetime | When it was written |
| updated_at | ISO8601 datetime | When it was last changed |
List Page Comments
GET /api/v1/projects/{project.uuid}/wiki/pages/{page.uuid}/comments
Returns comments oldest first. Requires can_view_wiki and can_view_wiki_comment.
Create Page Comment
POST /api/v1/projects/{project.uuid}/wiki/pages/{page.uuid}/comments
| Field | Type | Description |
|---|---|---|
| body | string | 1–4000 characters |
201 Created with {"uuid": "..."}. Requires can_view_wiki and can_edit_wiki_comment.
Delete Page Comment
DELETE /api/v1/projects/{project.uuid}/wiki/pages/{page.uuid}/comments/{comment.uuid}
Deletes the user's own comment. 204 No Content.
Attachments
Files attached to a page. Upload the file first with Upload File into this project, then attach it.
Attachment Structure
| Field | Type | Description |
|---|---|---|
| uuid | uuid | File ID |
| name | string | File name |
| mime_type | string | MIME type |
| size | integer | Size in bytes |
| url | string | Relative URL, /uploads/{uuid} |
| created_at | ISO8601 datetime | When the file was uploaded |
List Page Attachments
GET /api/v1/projects/{project.uuid}/wiki/pages/{page.uuid}/files
Returns attachments, newest first. Requires can_view_wiki.
Attach File
POST /api/v1/projects/{project.uuid}/wiki/pages/{page.uuid}/files
| Field | Type | Description |
|---|---|---|
| file_uuid | uuid | A file uploaded into this project |
201 Created with the attachment. Attaching the same file twice is not an error. Requires
can_edit_wiki.
Detach File
DELETE /api/v1/projects/{project.uuid}/wiki/pages/{page.uuid}/files/{file.uuid}
Removes the attachment. The file itself is not deleted. 204 No Content. Requires can_edit_wiki.
Search Wiki
GET /api/v1/projects/{project.uuid}/wiki/search?q={query}
Full-text search across all pages of the project, up to 20 results, best match first. Pages in the trash and in
deleted spaces are excluded. An empty q returns []. Requires can_view_wiki.
[
{
"uuid": "0199ad49-6071-7283-9405-a6b7c8d9e0f1",
"title": "Cutting fabric",
"space_uuid": "0199ad40-0000-7000-8000-000000000001",
"space_name": "Production",
"snippet": "Add 200 mm to the height for the \u0001roll\u0002.",
"rank": 0.0607927
}
]
snippet is plain text from the page with each match wrapped in the control characters U+0001 (start) and U+0002
(end). Split on them to highlight matches; do not render the snippet as HTML.
Errors
| Status | Code | When |
|---|---|---|
| 400 | REQ_VALIDATION_FAILED |
The body does not match the schema; a parent is in another space, deleted, or a descendant of the page; a version number is not a positive integer |
| 400 | REQ_NO_DATA_PROVIDED |
Modify: the body has no fields |
| 403 | AUTH_INSUFFICIENT_SCOPE |
The token lacks projects or wiki |
| 403 | AUTH_NO_PROJECT_ACCESS |
The user's role lacks the permission the endpoint needs |
| 404 | RES_NOT_FOUND |
The project, space, page, version, comment or file does not exist; the page is in the trash; a file to attach is not in this project |
| 409 | WIKI_PAGE_LOCKED |
Acquire Edit Lock: another user holds the lock |