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.
| Auth | Session or API token with the read scope |
| Token limited to projects | Refused |
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
projectId | id | The pages of that project. | |
taskId | id | The pages linked to that task. It wins over projectId. | |
scope | string | all lists every page the caller can see. trash lists the deleted ones. |
Request
GET /api/v2/pages?projectId=<project id>
Authorization: Bearer <token>
companyid: <company id>Response
{
"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
| Status | When |
|---|---|
| 400 | projectId or taskId is not an id. |
| 401 | No token, a token that is invalid, expired or revoked, or no valid companyid header. |
| 403 | The token lacks the read scope, or its person is no longer a member of the workspace. A token limited to projects is refused here. |
| 429 | Too 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.
| Auth | Session or API token with the write scope |
| Token limited to projects | Refused |
| Permission | With a projectId, the caller must be able to edit that project |
Body
| Field | Type | Required | Description |
|---|---|---|---|
title | string | yes | Up to 200 characters. |
projectId | id | The project the page belongs to. | |
parentPageId | id | The page this one sits under. | |
contentBlocks | array | The 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. | |
visibility | string | project (the default) or private. | |
linkedTasks | id[] | Tasks the page is attached to. Each must be a task the caller can open. | |
isWiki | boolean | Marks the page as a wiki page, which has an owner and a review date. | |
ownerId | id | The wiki page's owner. The caller when left out. | |
reviewDate | date | When the wiki page is next due for review. Three months from now when left out. | |
createdByAgent | boolean | Marks 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
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
{
"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
| Status | When |
|---|---|
| 400 | No 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. |
| 401 | No token, a token that is invalid, expired or revoked, or no valid companyid header. |
| 403 | The token lacks the write scope, or its person is no longer a member of the workspace. A token limited to projects is refused here. |
| 404 | The project or the parent page does not exist, or the caller may not use it. |
| 429 | Too 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.
| Auth | Session or API token with the read scope |
| Token limited to projects | Refused |
Path parameters
| Name | Type | Description |
|---|---|---|
id | id | The page. |
Request
GET /api/v2/pages/<id>
Authorization: Bearer <token>
companyid: <company id>Response
{
"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
| Status | When |
|---|---|
| 400 | The id is not an id. |
| 401 | No token, a token that is invalid, expired or revoked, or no valid companyid header. |
| 403 | The token lacks the read scope, or its person is no longer a member of the workspace. A token limited to projects is refused here. |
| 404 | The page does not exist, or the caller cannot see it. |
| 429 | Too 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.
| Auth | Session or API token with the write scope |
| Token limited to projects | Refused |
| Permission | The caller must be able to edit the page |
Path parameters
| Name | Type | Description |
|---|---|---|
id | id | The page. |
Body
| Field | Type | Required | Description |
|---|---|---|---|
title | string | Up to 200 characters. | |
contentBlocks | array | The new body, as a list of blocks. | |
contentHtml | string | The new body, as HTML. Send one of the two. | |
visibility | string | project or private. Only the author can make a page private. | |
linkedTasks | id[] | Replaces the tasks the page is attached to. A task added here must be one the caller can open. | |
isWiki | boolean | Marks or unmarks the page as a wiki page. | |
ownerId | id | The wiki page's owner. | |
reviewDate | date | When the wiki page is next due for review. |
Request
PUT /api/v2/pages/<id>
Authorization: Bearer <token>
companyid: <company id>
Content-Type: application/json
{ "title": "Release checklist (2026)" }Response
{
"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
| Status | When |
|---|---|
| 400 | 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. |
| 401 | No token, a token that is invalid, expired or revoked, or no valid companyid header. |
| 403 | The 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. |
| 404 | The page does not exist, or the caller may not change it. |
| 429 | Too 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.
| Auth | Session or API token with the write scope |
| Token limited to projects | Refused |
| Permission | A private page goes only by its author, an owner or an admin. Any other page needs edit rights on its project |
Path parameters
| Name | Type | Description |
|---|---|---|
id | id | The page. |
Request
DELETE /api/v2/pages/<id>
Authorization: Bearer <token>
companyid: <company id>Response
{ "status": true, "statusText": "Page deleted.", "data": { "deleted": 3 } }deleted counts the page and the pages under it that went with it.
Errors
| Status | When |
|---|---|
| 400 | The id is not an id. |
| 401 | No token, a token that is invalid, expired or revoked, or no valid companyid header. |
| 403 | The 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. |
| 404 | The page does not exist, or the caller cannot see it. |
| 429 | Too 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.
| Auth | Session or API token with the write scope |
| Token limited to projects | Refused |
| Permission | The caller must be able to edit the page |
Path parameters
| Name | Type | Description |
|---|---|---|
id | id | The page. |
Request
PUT /api/v2/pages/<id>/restore
Authorization: Bearer <token>
companyid: <company id>Response
{
"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
| Status | When |
|---|---|
| 400 | The id is not an id. |
| 401 | No token, a token that is invalid, expired or revoked, or no valid companyid header. |
| 403 | The token lacks the write scope, or its person is no longer a member of the workspace. A token limited to projects is refused here. |
| 404 | The page is not in the trash, or the caller may not change it. |
| 429 | Too 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.
| Auth | Session or API token with the read scope |
| Token limited to projects | Refused |
Path parameters
| Name | Type | Description |
|---|---|---|
id | id | The page. |
Request
GET /api/v2/pages/<id>/versions
Authorization: Bearer <token>
companyid: <company id>Response
{
"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
| Status | When |
|---|---|
| 401 | No token, a token that is invalid, expired or revoked, or no valid companyid header. |
| 403 | The token lacks the read scope, or its person is no longer a member of the workspace. A token limited to projects is refused here. |
| 404 | The page does not exist, or the caller cannot see it. |
| 429 | Too 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.
| Auth | Session or API token with the write scope |
| Token limited to projects | Refused |
| Permission | The caller must be able to edit the page |
Path parameters
| Name | Type | Description |
|---|---|---|
id | id | The page. |
Body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | A name for the version, up to 80 characters. |
Request
POST /api/v2/pages/<id>/versions
Authorization: Bearer <token>
companyid: <company id>
Content-Type: application/json
{ "name": "Before the rewrite" }Response
{
"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
| Status | When |
|---|---|
| 400 | The 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. |
| 401 | No token, a token that is invalid, expired or revoked, or no valid companyid header. |
| 403 | The 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. |
| 404 | The page does not exist, or the caller cannot see it. |
| 429 | Too 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.
| Auth | Session or API token with the read scope |
| Token limited to projects | Refused |
Path parameters
| Name | Type | Description |
|---|---|---|
id | id | The page. |
versionId | id | The version. |
Request
GET /api/v2/pages/<id>/versions/<versionId>
Authorization: Bearer <token>
companyid: <company id>Response
{
"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
| Status | When |
|---|---|
| 401 | No token, a token that is invalid, expired or revoked, or no valid companyid header. |
| 403 | The token lacks the read scope, or its person is no longer a member of the workspace. A token limited to projects is refused here. |
| 404 | The page or the version does not exist, or the caller cannot see it. |
| 429 | Too 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.
| Auth | Session or API token with the write scope |
| Token limited to projects | Refused |
| Permission | The caller must be able to edit the page |
Path parameters
| Name | Type | Description |
|---|---|---|
id | id | The page. |
versionId | id | The version. |
Body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | The name, up to 80 characters. An empty name clears it. |
Request
PUT /api/v2/pages/<id>/versions/<versionId>
Authorization: Bearer <token>
companyid: <company id>
Content-Type: application/json
{ "name": "Signed off" }Response
{
"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
| Status | When |
|---|---|
| 400 | The name is not text or is over 80 characters, or the page already has 30 named versions. |
| 401 | No token, a token that is invalid, expired or revoked, or no valid companyid header. |
| 403 | The 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. |
| 404 | The page or the version does not exist, or the caller cannot see it. |
| 429 | Too 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.
| Auth | Session or API token with the write scope |
| Token limited to projects | Refused |
| Permission | The caller must be able to edit the page |
Path parameters
| Name | Type | Description |
|---|---|---|
id | id | The page. |
versionId | id | The version. |
Request
POST /api/v2/pages/<id>/versions/<versionId>/restore
Authorization: Bearer <token>
companyid: <company id>Response
{
"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
| Status | When |
|---|---|
| 401 | No token, a token that is invalid, expired or revoked, or no valid companyid header. |
| 403 | The 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. |
| 404 | The page or the version does not exist, or the caller cannot see it. |
| 429 | Too 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.
| Auth | Session or API token with the read scope |
| Token limited to projects | Refused |
| Permission | The caller must be able to read the page |
Path parameters
| Name | Type | Description |
|---|---|---|
id | id | The page. |
Request
GET /api/v2/pages/<id>/comments/people
Authorization: Bearer <token>
companyid: <company id>Response
{ "status": true, "statusText": "People fetched.", "data": ["<user id>"] }Paging
None.
Errors
| Status | When |
|---|---|
| 401 | No token, a token that is invalid, expired or revoked, or no valid companyid header. |
| 403 | The token lacks the read scope, or its person is no longer a member of the workspace. A token limited to projects is refused here. |
| 404 | The page does not exist, or the caller cannot read it. |
| 429 | Too 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.
| Auth | Session or API token with the write scope |
| Token limited to projects | Refused |
| Permission | The 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
| Name | Type | Description |
|---|---|---|
id | id | The page. |
commentId | id | The comment. |
Body
| Field | Type | Required | Description |
|---|---|---|---|
assigneeId | id | An active member who can read the page. Empty, or left out, clears the assignment. |
Request
PUT /api/v2/pages/<id>/comments/<commentId>/assign
Authorization: Bearer <token>
companyid: <company id>
Content-Type: application/json
{ "assigneeId": "<user id>" }Response
{
"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
| Status | When |
|---|---|
| 400 | The comment is a reply (only a thread can be assigned), or assigneeId is not an active member who can read the page. |
| 401 | No token, a token that is invalid, expired or revoked, or no valid companyid header. |
| 403 | The token lacks the write scope, or its person is no longer a member of the workspace. A token limited to projects is refused here. |
| 404 | The page does not exist, or the caller cannot read it. Or the comment does not exist on it. |
| 429 | Too 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.
| Auth | Session or API token with the write scope |
| Token limited to projects | Refused |
| Permission | The caller must be able to read the page |
Path parameters
| Name | Type | Description |
|---|---|---|
id | id | The page. |
commentId | id | The comment. |
Body
| Field | Type | Required | Description |
|---|---|---|---|
emoji | string | yes | One of 👍, ❤️, 😄, 🎉, 😮, 😢, 🚀 or 👀. |
Request
PUT /api/v2/pages/<id>/comments/<commentId>/reaction
Authorization: Bearer <token>
companyid: <company id>
Content-Type: application/json
{ "emoji": "👍" }Response
{
"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
| Status | When |
|---|---|
| 400 | emoji is not one of the supported reactions. |
| 401 | No token, a token that is invalid, expired or revoked, or no valid companyid header. |
| 403 | The token lacks the write scope, or its person is no longer a member of the workspace. A token limited to projects is refused here. |
| 404 | The page does not exist, or the caller cannot read it. Or the comment does not exist on it. |
| 429 | Too many requests from this address. Wait retryAfter seconds and send it again. |
