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