Skip to content

Pages ​

Docs and wiki pages, their version history, and who a comment on one can name. A page belongs to a project or to the workspace. A private page is its author's alone; any other page is open to whoever can see its project. A page the caller cannot see answers the same as one that does not exist.

List pages ​

GET /api/v2/pages · beta

Lists pages, without their bodies.

Any signed-in member of the workspace may call it. It reads projectId (id), taskId (id, which wins over projectId) and scope (all, shared or trash) from the query; with none of them it lists the workspace's pages that belong to no project. A malformed id answers a failed status. Only pages the caller may read are listed: a private page is its author's, a project's pages go to those who can see the project, and a page shared with the caller by name is included except in the trash. Answers with data: the pages ordered by order, each with an excerpt of up to 160 characters in place of its body.

AuthSession or API token with the read scope
Token limited to projectsRefused

Query parameters

NameTypeRequiredDescription
projectIdidThe pages of that project.
taskIdidThe pages linked to that task. It wins over projectId.
scopestringall lists every page the caller can see. trash lists the deleted ones.

Request

http
GET /api/v2/pages?projectId=<project id>
Authorization: Bearer <token>
companyid: <company id>

Response

json
{
  "status": true,
  "statusText": "Pages fetched.",
  "data": [
    {
      "_id": "<page id>",
      "title": "Release checklist",
      "ProjectID": "<project id>",
      "visibility": "project",
      "isWiki": false,
      "linkedTasks": [],
      "createdBy": "<user id>",
      "updatedBy": "<user id>",
      "createdAt": "2026-10-01T09:30:00.000Z",
      "updatedAt": "2026-10-01T09:30:00.000Z",
      "order": 1759311000000,
      "excerpt": "Before every release, check that",
      "reviewState": "none"
    }
  ]
}

With no parameter, the list holds the workspace's own pages: the ones that belong to no project.

excerpt is the first 160 characters of the page's text. reviewState is none, verified, due or stale.

Paging

None. The whole list is returned, in the pages' own order.

Errors

StatusWhen
400projectId or taskId is not an id.
401No token, a token that is invalid, expired or revoked, or no valid companyid header.
403The token lacks the read scope, or its person is no longer a member of the workspace. A token limited to projects is refused here.
429Too many requests from this address. Wait retryAfter seconds and send it again.

Create a page ​

POST /api/v2/pages · beta

Creates a page in a project, or in the workspace when no project is named.

Any signed-in member of the workspace may call it, except the guest role, which cannot add pages; a page in a project also needs edit rights on that project (403 without them, 404 when the project cannot be seen), and a parent page needs edit rights too. Reads title (string, required), projectId, parentPageId (ids), visibility (string), linkedTasks (id list of tasks the caller can open), contentBlocks (list), isWiki (boolean), ownerId (id) and reviewDate from the body. Answers with data: the saved page.

AuthSession or API token with the write scope
Token limited to projectsRefused
PermissionWith a projectId, the caller must be able to edit that project

Body

FieldTypeRequiredDescription
titlestringyesUp to 200 characters.
projectIdidThe project the page belongs to.
parentPageIdidThe page this one sits under.
contentBlocksarrayThe body, as a list of blocks: { type, data }. Types include header, paragraph, list, checklist, code, quote, table, callout, delimiter, image and embed. The body can be at most 512 KB.
visibilitystringproject (the default) or private.
linkedTasksid[]Tasks the page is attached to. Each must be a task the caller can open.
isWikibooleanMarks the page as a wiki page, which has an owner and a review date.
ownerIdidThe wiki page's owner. The caller when left out.
reviewDatedateWhen the wiki page is next due for review. Three months from now when left out.
createdByAgentbooleanMarks the page as a draft that a person approves. A page an agent token creates is always one, under the token's own name.

Request

http
POST /api/v2/pages
Authorization: Bearer <token>
companyid: <company id>
Content-Type: application/json

{
  "title": "Release checklist",
  "projectId": "<project id>",
  "contentBlocks": [
    { "type": "header", "data": { "text": "Before every release", "level": 2 } },
    { "type": "paragraph", "data": { "text": "Check that the changelog is up to date." } }
  ]
}

Response

json
{
  "status": true,
  "statusText": "Page created.",
  "data": {
    "_id": "<page id>",
    "title": "Release checklist",
    "ProjectID": "<project id>",
    "visibility": "project",
    "isWiki": false,
    "linkedTasks": [],
    "createdBy": "<user id>",
    "updatedBy": "<user id>",
    "createdAt": "2026-10-01T09:30:00.000Z",
    "updatedAt": "2026-10-01T09:30:00.000Z",
    "content": {
      "html": "<h2>Before every release</h2><p>Check that the changelog is up to date.</p>",
      "blocks": { "time": 1759311000000, "blocks": [], "version": "2.30.7" }
    },
    "rawText": "Before every release Check that the changelog is up to date."
  }
}

data is the stored page. content.blocks.blocks holds the blocks that were sent; the example leaves them out.

Errors

StatusWhen
400No title, a title over 200 characters, an id that is not an id, a review date that is not a date, or a body that is too large.
401No token, a token that is invalid, expired or revoked, or no valid companyid header.
403The token lacks the write scope, or its person is no longer a member of the workspace. A token limited to projects is refused here.
404The project or the parent page does not exist, or the caller may not use it.
429Too many requests from this address. Wait retryAfter seconds and send it again.

Read a page ​

GET /api/v2/pages/:id · beta

Returns one page with its body.

Any signed-in member of the workspace who may read the page. A page the caller may not read answers the same way as one that does not exist, with a failed status and Page not found.. Answers with data: the page with its body, and the flags canEdit, canChangeProperties and canManageShares as they apply to the caller.

AuthSession or API token with the read scope
Token limited to projectsRefused

Path parameters

NameTypeDescription
ididThe page.

Request

http
GET /api/v2/pages/<id>
Authorization: Bearer <token>
companyid: <company id>

Response

json
{
  "status": true,
  "statusText": "Page fetched.",
  "data": {
    "_id": "<page id>",
    "title": "Release checklist",
    "ProjectID": "<project id>",
    "visibility": "project",
    "isWiki": false,
    "linkedTasks": [],
    "createdBy": "<user id>",
    "updatedBy": "<user id>",
    "createdAt": "2026-10-01T09:30:00.000Z",
    "updatedAt": "2026-10-01T09:30:00.000Z",
    "content": {
      "html": "<h2>Before every release</h2>",
      "blocks": {
        "time": 1759311000000,
        "blocks": [{ "type": "header", "data": { "text": "Before every release", "level": 2 } }],
        "version": "2.30.7"
      }
    },
    "rawText": "Before every release",
    "reviewState": "none"
  }
}

Errors

StatusWhen
400The id is not an id.
401No token, a token that is invalid, expired or revoked, or no valid companyid header.
403The token lacks the read scope, or its person is no longer a member of the workspace. A token limited to projects is refused here.
404The page does not exist, or the caller cannot see it.
429Too many requests from this address. Wait retryAfter seconds and send it again.

Change a page ​

PUT /api/v2/pages/:id · beta

Changes a page's title, body or properties. Only the keys sent are changed.

When the title or the body changes, the state before the change is kept as a version.

AuthSession or API token with the write scope
Token limited to projectsRefused
PermissionThe caller must be able to edit the page

Path parameters

NameTypeDescription
ididThe page.

Body

FieldTypeRequiredDescription
titlestringUp to 200 characters.
contentBlocksarrayThe new body, as a list of blocks.
contentHtmlstringThe new body, as HTML. Send one of the two.
visibilitystringproject or private. Only the author can make a page private.
linkedTasksid[]Replaces the tasks the page is attached to. A task added here must be one the caller can open.
isWikibooleanMarks or unmarks the page as a wiki page.
ownerIdidThe wiki page's owner.
reviewDatedateWhen the wiki page is next due for review.

Request

http
PUT /api/v2/pages/<id>
Authorization: Bearer <token>
companyid: <company id>
Content-Type: application/json

{ "title": "Release checklist (2026)" }

Response

json
{
  "status": true,
  "statusText": "Page saved.",
  "data": {
    "_id": "<page id>",
    "title": "Release checklist (2026)",
    "ProjectID": "<project id>",
    "visibility": "project",
    "isWiki": false,
    "linkedTasks": [],
    "createdBy": "<user id>",
    "updatedBy": "<user id>",
    "createdAt": "2026-10-01T09:30:00.000Z",
    "updatedAt": "2026-10-01T09:30:00.000Z"
  }
}

data is the whole stored page after the change; the example shows some of its fields.

Errors

StatusWhen
400A title over 200 characters, an id that is not an id, a review date that is not a date, or a body that is too large.
401No token, a token that is invalid, expired or revoked, or no valid companyid header.
403The token lacks the write scope, or its person is no longer a member of the workspace. A token limited to projects is refused here. Someone other than the author tried to make the page private.
404The page does not exist, or the caller may not change it.
429Too many requests from this address. Wait retryAfter seconds and send it again.

Delete a page ​

DELETE /api/v2/pages/:id · beta

Moves a page to the trash, together with the pages under it that the caller can see.

Allowed for the author of a private page and for owners and admins; for a page in a project, for those with edit rights on that project; for a workspace page, for any member. The guest role cannot delete pages. Answers 404 when the page cannot be seen and 403 when it can be seen but not deleted. Answers with data.deleted: the number of pages moved to the trash.

AuthSession or API token with the write scope
Token limited to projectsRefused
PermissionA private page goes only by its author, an owner or an admin. Any other page needs edit rights on its project

Path parameters

NameTypeDescription
ididThe page.

Request

http
DELETE /api/v2/pages/<id>
Authorization: Bearer <token>
companyid: <company id>

Response

json
{ "status": true, "statusText": "Page deleted.", "data": { "deleted": 3 } }

deleted counts the page and the pages under it that went with it.

Errors

StatusWhen
400The id is not an id.
401No token, a token that is invalid, expired or revoked, or no valid companyid header.
403The token lacks the write scope, or its person is no longer a member of the workspace. A token limited to projects is refused here. The caller can see the page's project but may not edit it.
404The page does not exist, or the caller cannot see it.
429Too many requests from this address. Wait retryAfter seconds and send it again.

Restore a page ​

PUT /api/v2/pages/:id/restore · beta

Takes a page back out of the trash. Only the page itself: the pages that went with it are restored one by one.

Needs edit rights on the page as reached without a share by name, and the guest role is excluded. The page must be in the trash, else the answer is a failed status with Page not found in trash.. Answers with data: the restored page.

AuthSession or API token with the write scope
Token limited to projectsRefused
PermissionThe caller must be able to edit the page

Path parameters

NameTypeDescription
ididThe page.

Request

http
PUT /api/v2/pages/<id>/restore
Authorization: Bearer <token>
companyid: <company id>

Response

json
{
  "status": true,
  "statusText": "Page restored.",
  "data": {
    "_id": "<page id>",
    "title": "Release checklist",
    "ProjectID": "<project id>",
    "visibility": "project",
    "isWiki": false,
    "linkedTasks": [],
    "createdBy": "<user id>",
    "updatedBy": "<user id>",
    "createdAt": "2026-10-01T09:30:00.000Z",
    "updatedAt": "2026-10-01T09:30:00.000Z"
  }
}

Errors

StatusWhen
400The id is not an id.
401No token, a token that is invalid, expired or revoked, or no valid companyid header.
403The token lacks the write scope, or its person is no longer a member of the workspace. A token limited to projects is refused here.
404The page is not in the trash, or the caller may not change it.
429Too many requests from this address. Wait retryAfter seconds and send it again.

List a page's versions ​

GET /api/v2/pages/:id/versions · beta

Lists the versions kept for a page, newest first, without their bodies.

Any signed-in member of the workspace who may read the page; a page the caller may not read answers 404 Page not found.. Answers with data: the versions the caller may see, newest first, without their bodies.

AuthSession or API token with the read scope
Token limited to projectsRefused

Path parameters

NameTypeDescription
ididThe page.

Request

http
GET /api/v2/pages/<id>/versions
Authorization: Bearer <token>
companyid: <company id>

Response

json
{
  "status": true,
  "statusText": "Versions fetched.",
  "data": [
    {
      "_id": "<version id>",
      "pageId": "<page id>",
      "title": "Release checklist",
      "name": "Before the rewrite",
      "reason": "manual",
      "savedBy": "<user id>",
      "savedAt": "2026-10-01T09:30:00.000Z",
      "visibility": "project"
    }
  ]
}

reason says why the version was kept: manual (someone saved it), author (someone else was about to change the page), interval (ten minutes had passed since the last version), restore (the state before a restore) or legacy. name is empty for a version nobody named. A version kept while the page was private is shown only to the page's author.

Paging

None. A page keeps at most 100 unnamed and 30 named versions.

Errors

StatusWhen
401No token, a token that is invalid, expired or revoked, or no valid companyid header.
403The token lacks the read scope, or its person is no longer a member of the workspace. A token limited to projects is refused here.
404The page does not exist, or the caller cannot see it.
429Too many requests from this address. Wait retryAfter seconds and send it again.

Save a version ​

POST /api/v2/pages/:id/versions · beta

Keeps the page as it is now as a version, with a name when one is given.

Needs edit rights on the page. Reads name (string, up to 80 characters, optional) from the body. A page with no content answers 400, a page too large to keep answers 400, and a page may hold a limited number of named versions. When the latest version already matches the page, no new version is made and the answer names or returns that one. Answers with data: the version.

AuthSession or API token with the write scope
Token limited to projectsRefused
PermissionThe caller must be able to edit the page

Path parameters

NameTypeDescription
ididThe page.

Body

FieldTypeRequiredDescription
namestringA name for the version, up to 80 characters.

Request

http
POST /api/v2/pages/<id>/versions
Authorization: Bearer <token>
companyid: <company id>
Content-Type: application/json

{ "name": "Before the rewrite" }

Response

json
{
  "status": true,
  "statusText": "Version saved.",
  "data": {
    "_id": "<version id>",
    "pageId": "<page id>",
    "title": "Release checklist",
    "name": "Before the rewrite",
    "reason": "manual",
    "savedBy": "<user id>",
    "savedAt": "2026-10-01T09:30:00.000Z",
    "visibility": "project"
  }
}

When the newest version already holds this state, no new version is made: the answer is that version, named if a name was sent.

Errors

StatusWhen
400The name is not text or is over 80 characters, the page is empty, the page already has 30 named versions, or the page is too large to keep.
401No token, a token that is invalid, expired or revoked, or no valid companyid header.
403The token lacks the write scope, or its person is no longer a member of the workspace. A token limited to projects is refused here. The caller can see the page but may not change it.
404The page does not exist, or the caller cannot see it.
429Too many requests from this address. Wait retryAfter seconds and send it again.

Read a version ​

GET /api/v2/pages/:id/versions/:versionId · beta

Returns one version with its body.

Any signed-in member of the workspace who may read the page and that version; otherwise 404 with Version not found. or Page not found.. Answers with data: the version with its title and body.

AuthSession or API token with the read scope
Token limited to projectsRefused

Path parameters

NameTypeDescription
ididThe page.
versionIdidThe version.

Request

http
GET /api/v2/pages/<id>/versions/<versionId>
Authorization: Bearer <token>
companyid: <company id>

Response

json
{
  "status": true,
  "statusText": "Version fetched.",
  "data": {
    "_id": "<version id>",
    "pageId": "<page id>",
    "title": "Release checklist",
    "name": "Before the rewrite",
    "reason": "manual",
    "savedBy": "<user id>",
    "savedAt": "2026-10-01T09:30:00.000Z",
    "visibility": "project",
    "blocks": [{ "type": "header", "data": { "text": "Before every release", "level": 2 } }],
    "rawText": "Before every release"
  }
}

Errors

StatusWhen
401No token, a token that is invalid, expired or revoked, or no valid companyid header.
403The token lacks the read scope, or its person is no longer a member of the workspace. A token limited to projects is refused here.
404The page or the version does not exist, or the caller cannot see it.
429Too many requests from this address. Wait retryAfter seconds and send it again.

Name a version ​

PUT /api/v2/pages/:id/versions/:versionId · beta

Names a version, or clears its name.

Needs edit rights on the page. Reads name (string, up to 80 characters) from the body; an empty name clears it, and naming one more version than the limit allows answers 400. Answers with data: the version.

AuthSession or API token with the write scope
Token limited to projectsRefused
PermissionThe caller must be able to edit the page

Path parameters

NameTypeDescription
ididThe page.
versionIdidThe version.

Body

FieldTypeRequiredDescription
namestringThe name, up to 80 characters. An empty name clears it.

Request

http
PUT /api/v2/pages/<id>/versions/<versionId>
Authorization: Bearer <token>
companyid: <company id>
Content-Type: application/json

{ "name": "Signed off" }

Response

json
{
  "status": true,
  "statusText": "Version named.",
  "data": {
    "_id": "<version id>",
    "pageId": "<page id>",
    "title": "Release checklist",
    "name": "Signed off",
    "reason": "manual",
    "savedBy": "<user id>",
    "savedAt": "2026-10-01T09:30:00.000Z",
    "visibility": "project"
  }
}

Errors

StatusWhen
400The name is not text or is over 80 characters, or the page already has 30 named versions.
401No token, a token that is invalid, expired or revoked, or no valid companyid header.
403The token lacks the write scope, or its person is no longer a member of the workspace. A token limited to projects is refused here. The caller can see the page but may not change it.
404The page or the version does not exist, or the caller cannot see it.
429Too many requests from this address. Wait retryAfter seconds and send it again.

Restore a version ​

POST /api/v2/pages/:id/versions/:versionId/restore · beta

Puts a version's title and body back on the page. The page as it was is kept as a version first.

Needs edit rights on the page. The page as it is now is kept as a version first, then the version's title and body replace it. Answers with data: the page as it is now.

AuthSession or API token with the write scope
Token limited to projectsRefused
PermissionThe caller must be able to edit the page

Path parameters

NameTypeDescription
ididThe page.
versionIdidThe version.

Request

http
POST /api/v2/pages/<id>/versions/<versionId>/restore
Authorization: Bearer <token>
companyid: <company id>

Response

json
{
  "status": true,
  "statusText": "Version restored.",
  "data": {
    "_id": "<page id>",
    "title": "Release checklist",
    "ProjectID": "<project id>",
    "visibility": "project",
    "isWiki": false,
    "linkedTasks": [],
    "createdBy": "<user id>",
    "updatedBy": "<user id>",
    "createdAt": "2026-10-01T09:30:00.000Z",
    "updatedAt": "2026-10-01T09:30:00.000Z",
    "reviewState": "none"
  }
}

data is the whole stored page after the restore; the example shows some of its fields.

Errors

StatusWhen
401No token, a token that is invalid, expired or revoked, or no valid companyid header.
403The token lacks the write scope, or its person is no longer a member of the workspace. A token limited to projects is refused here. The caller can see the page but may not change it.
404The page or the version does not exist, or the caller cannot see it.
429Too many requests from this address. Wait retryAfter seconds and send it again.

List who can be mentioned on a page ​

GET /api/v2/pages/:id/comments/people · beta

Lists the ids of the people a comment on a page may mention or be assigned to.

These are the active members who can read the page.

AuthSession or API token with the read scope
Token limited to projectsRefused
PermissionThe caller must be able to read the page

Path parameters

NameTypeDescription
ididThe page.

Request

http
GET /api/v2/pages/<id>/comments/people
Authorization: Bearer <token>
companyid: <company id>

Response

json
{ "status": true, "statusText": "People fetched.", "data": ["<user id>"] }

Paging

None.

Errors

StatusWhen
401No token, a token that is invalid, expired or revoked, or no valid companyid header.
403The token lacks the read scope, or its person is no longer a member of the workspace. A token limited to projects is refused here.
404The page does not exist, or the caller cannot read it.
429Too many requests from this address. Wait retryAfter seconds and send it again.

Assign a page comment ​

PUT /api/v2/pages/:id/comments/:commentId/assign · beta

Assigns a comment thread to a person, or clears the assignment.

Assigning a thread reopens it. The assignee is told once, unless they assigned it to themselves.

AuthSession or API token with the write scope
Token limited to projectsRefused
PermissionThe caller must be able to read the page. Once a thread is assigned, only its author, the person who assigned it, its assignee, an owner or an admin can change the assignment

Path parameters

NameTypeDescription
ididThe page.
commentIdidThe comment.

Body

FieldTypeRequiredDescription
assigneeIdidAn active member who can read the page. Empty, or left out, clears the assignment.

Request

http
PUT /api/v2/pages/<id>/comments/<commentId>/assign
Authorization: Bearer <token>
companyid: <company id>
Content-Type: application/json

{ "assigneeId": "<user id>" }

Response

json
{
  "status": true,
  "statusText": "Comment assigned.",
  "data": {
    "_id": "<comment id>",
    "pageId": "<page id>",
    "userId": "<user id>",
    "message": "Can we cut this section?",
    "blockId": "",
    "mentionIds": [],
    "assigneeId": "<user id>",
    "assignedBy": "<user id>",
    "assignedAt": "2026-10-01T09:30:00.000Z",
    "resolved": false,
    "reactions": [{ "emoji": "👍", "userId": "<user id>", "createdAt": "2026-10-01T09:30:00.000Z" }],
    "createdAt": "2026-10-01T09:30:00.000Z",
    "updatedAt": "2026-10-01T09:30:00.000Z"
  }
}

data is the whole stored comment; the example shows some of its fields.

Clearing the assignment answers Comment unassigned..

Errors

StatusWhen
400The comment is a reply (only a thread can be assigned), or assigneeId is not an active member who can read the page.
401No token, a token that is invalid, expired or revoked, or no valid companyid header.
403The token lacks the write scope, or its person is no longer a member of the workspace. A token limited to projects is refused here.
404The page does not exist, or the caller cannot read it. Or the comment does not exist on it.
429Too many requests from this address. Wait retryAfter seconds and send it again.

React to a page comment ​

PUT /api/v2/pages/:id/comments/:commentId/reaction · beta

Puts the caller's reaction on a comment, or takes it off if it is already there.

A reaction does not count as an edit: the comment's updatedAt stays as it was.

AuthSession or API token with the write scope
Token limited to projectsRefused
PermissionThe caller must be able to read the page

Path parameters

NameTypeDescription
ididThe page.
commentIdidThe comment.

Body

FieldTypeRequiredDescription
emojistringyesOne of 👍, ❤️, 😄, 🎉, 😮, 😢, 🚀 or 👀.

Request

http
PUT /api/v2/pages/<id>/comments/<commentId>/reaction
Authorization: Bearer <token>
companyid: <company id>
Content-Type: application/json

{ "emoji": "👍" }

Response

json
{
  "status": true,
  "statusText": "Reaction added.",
  "data": {
    "_id": "<comment id>",
    "pageId": "<page id>",
    "userId": "<user id>",
    "message": "Can we cut this section?",
    "blockId": "",
    "mentionIds": [],
    "assigneeId": "<user id>",
    "assignedBy": "<user id>",
    "assignedAt": "2026-10-01T09:30:00.000Z",
    "resolved": false,
    "reactions": [{ "emoji": "👍", "userId": "<user id>", "createdAt": "2026-10-01T09:30:00.000Z" }],
    "createdAt": "2026-10-01T09:30:00.000Z",
    "updatedAt": "2026-10-01T09:30:00.000Z"
  }
}

data is the whole stored comment; the example shows some of its fields.

Taking a reaction off answers Reaction removed..

Errors

StatusWhen
400emoji is not one of the supported reactions.
401No token, a token that is invalid, expired or revoked, or no valid companyid header.
403The token lacks the write scope, or its person is no longer a member of the workspace. A token limited to projects is refused here.
404The page does not exist, or the caller cannot read it. Or the comment does not exist on it.
429Too many requests from this address. Wait retryAfter seconds and send it again.

Released under the AGPL-3.0 licence.