Comments API
Threaded review comments on merge requests and blocks.
Comment methods let reviewers open threads on a merge request or a block, reply, mention users, and resolve or reopen the discussion. They live at cms.api.<collection>.<method> and mirror on the client at client.<collection>.<method> with identical types. Examples below use pages as the sample collection.
These endpoints operate on comment threads and messages, not on content commits, so no method returns a commit envelope.
Open a Comment Thread
Open a new review thread with an initial message, so reviewers can flag something on a merge request or a block. targetType picks the anchor: 'mergeRequest' requires mergeRequestId, 'block' requires blockId. Anyone you list in mentions gets a notification.
comment:create/{collection}/createCommentThreadconst data = await cms.api.pages.createCommentThread({
body: {
targetType: 'mergeRequest', // required
mergeRequestId: 'mr_8fd21c', // required when targetType is 'mergeRequest'
body: 'Can we tighten the hero copy before merging?', // required
mentions: ['user_editor'],
},
});const { data, error } = await client.pages.createCommentThread({
body: {
targetType: 'mergeRequest', // required
mergeRequestId: 'mr_8fd21c', // required when targetType is 'mergeRequest'
body: 'Can we tighten the hero copy before merging?', // required
mentions: ['user_editor'],
},
});targetType'mergeRequest' | 'block'requiredWhat the thread is attached to.
bodystringrequiredInitial message text (non-empty).
mergeRequestIdstringMerge request to attach to. Required when targetType is 'mergeRequest'; also infers rootId.
blockIdstringBlock to attach to. Required when targetType is 'block'.
commitIdstringOptional commit to pin the thread to a specific snapshot.
rootIdstringOptional root ID. Inferred from the merge request when omitted.
mentionsstring[]User IDs to mention in the initial message.
threadCommentThreadThe new thread: `{ id, status, targetType, rootId, mergeRequestId, blockId, commitId, createdBy, createdAt, ... }`.
messageCommentMessageThe initial message, with its resolved `mentions` (the author is stripped out).
Reply to a Thread
Reply to an existing thread, optionally nested under a parent message. The thread's creator and every mentioned user get notified.
comment:create/{collection}/createCommentMessageconst data = await cms.api.pages.createCommentMessage({
body: {
threadId: 'thr_1a2b3c', // required
body: 'Updated, ready for another look.', // required
},
});const { data, error } = await client.pages.createCommentMessage({
body: {
threadId: 'thr_1a2b3c', // required
body: 'Updated, ready for another look.', // required
},
});threadIdstringrequiredThread to reply in.
bodystringrequiredMessage text (non-empty).
parentMessageIdstringParent message for a nested reply.
mentionsstring[]User IDs to mention in this message.
messageCommentMessageThe new reply, with its resolved `mentions` and `parentMessageId` when nested.
List Comment Threads
Page through comment threads, filtered by what they're attached to (merge request, block, commit, root), by status, or by who was mentioned. Each thread comes back with its message count and first/latest message, so you can render a list without a second round-trip. Every query field is optional.
comment:read/{collection}/listCommentThreadsconst data = await cms.api.pages.listCommentThreads({
query: {
status: 'open',
limit: 50,
},
});const { data, error } = await client.pages.listCommentThreads({
query: {
status: 'open',
limit: 50,
},
});mergeRequestIdstringFilter by merge request.
blockIdstringFilter by block.
commitIdstringFilter by commit.
rootIdstringFilter by root.
status'open' | 'resolved'Filter by thread status.
mentionedUserIdstringOnly threads mentioning this user.
limitnumber= 20Page size, 1 to 100.
offsetnumber= 0Rows to skip.
threadsCommentThreadSummary[]The threads on this page, newest first. Each carries `messageCount`, `firstMessage`, `latestMessage`, and enriched `createdByUser` / `resolvedByUser`.
totalnumberTotal threads matching the filters, ignoring limit/offset.
hasMorebooleanWhether more threads exist after this page.
Get a Thread with Its Messages
Load a single thread together with all of its messages in chronological order, so you can render the full discussion. Deleted messages still come back, but with their body masked to null.
comment:read/{collection}/getCommentThreadconst data = await cms.api.pages.getCommentThread({
query: { threadId: 'thr_1a2b3c' }, // required
});const { data, error } = await client.pages.getCommentThread({
query: { threadId: 'thr_1a2b3c' }, // required
});threadIdstringrequiredThread to fetch.
threadCommentThreadThe thread, with enriched `createdByUser` / `resolvedByUser`.
messagesCommentMessage[]Every message in the thread, oldest first. Deleted messages come back with `body: null`; author profiles attach as `authorUser` when user enrichment is on.
Edit a Message
Edit the text of a message you wrote, and optionally replace its mentions. Only the original author may edit, and system messages cannot be edited.
comment:update/{collection}/updateCommentMessageconst data = await cms.api.pages.updateCommentMessage({
body: {
messageId: 'msg_9f8e7d', // required
body: 'Revised: tightened the hero copy.', // required
},
});const { data, error } = await client.pages.updateCommentMessage({
body: {
messageId: 'msg_9f8e7d', // required
body: 'Revised: tightened the hero copy.', // required
},
});messageIdstringrequiredMessage to edit.
bodystringrequiredNew message text (non-empty).
mentionsstring[]When provided, replaces the message's mentions.
messageCommentMessageThe edited message, with `editedAt` set and its current `mentions`.
Resolve a Thread
Mark a thread as resolved once its discussion is settled. A system message is appended recording who resolved it, and you get both the updated thread and that message back.
comment:update/{collection}/resolveCommentThreadconst data = await cms.api.pages.resolveCommentThread({
body: { threadId: 'thr_1a2b3c' }, // required
});const { data, error } = await client.pages.resolveCommentThread({
body: { threadId: 'thr_1a2b3c' }, // required
});threadIdstringrequiredThread to resolve.
threadCommentThreadThe thread, now resolved: `status: 'resolved'` with `resolvedBy` and `resolvedAt` set.
messageCommentMessageThe appended system message recording the resolution (`messageType: 'system'`, `systemType: 'threadResolved'`).
Reopen a Thread
Reopen a resolved thread when the discussion isn't finished after all. A system message is appended recording the reopening, and you get both the updated thread and that message back.
comment:update/{collection}/reopenCommentThreadconst data = await cms.api.pages.reopenCommentThread({
body: { threadId: 'thr_1a2b3c' }, // required
});const { data, error } = await client.pages.reopenCommentThread({
body: { threadId: 'thr_1a2b3c' }, // required
});threadIdstringrequiredThread to reopen.
threadCommentThreadThe thread, reopened: `status: 'open'` with `resolvedBy` / `resolvedAt` cleared.
messageCommentMessageThe appended system message recording the reopening (`systemType: 'threadReopened'`).
Delete a Thread
Soft-delete a thread so it drops out of list and get. Its messages and mentions stay in the database and are removed only when the owning root is pruned.
comment:delete/{collection}/deleteCommentThreadconst data = await cms.api.pages.deleteCommentThread({
body: { threadId: 'thr_1a2b3c' }, // required
});const { data, error } = await client.pages.deleteCommentThread({
body: { threadId: 'thr_1a2b3c' }, // required
});threadIdstringrequiredThread to soft-delete.
threadIdstringThe id of the soft-deleted thread.
Delete a Message
Soft-delete a single message so its body is masked on retrieval. Only the original author may delete, and system messages cannot be deleted.
comment:delete/{collection}/deleteCommentMessageconst data = await cms.api.pages.deleteCommentMessage({
body: { messageId: 'msg_9f8e7d' }, // required
});const { data, error } = await client.pages.deleteCommentMessage({
body: { messageId: 'msg_9f8e7d' }, // required
});messageIdstringrequiredMessage to soft-delete.
messageCommentMessageThe soft-deleted message, returned with `body: null` and `deletedAt` set.
List a User's Mentions
Page through the mentions a user has received, each with the message and thread it came from, so you can build a mentions inbox. Filter to a single thread with threadId.
comment:read/{collection}/listMentionsconst data = await cms.api.pages.listMentions({
query: {
mentionedUserId: 'usr_1', // required
limit: 50,
},
});const { data, error } = await client.pages.listMentions({
query: {
mentionedUserId: 'usr_1', // required
limit: 50,
},
});mentionedUserIdstringrequiredUser whose mentions to list.
threadIdstringRestrict to mentions in one thread.
limitnumber= 20Page size, 1 to 100.
offsetnumber= 0Rows to skip.
mentionsMention[]The mentions on this page, newest first. Each has `id`, `mentionedUserId`, `mentionedBy`, `createdAt`, plus the full `message` and `thread` it belongs to.
totalnumberTotal mentions matching the filters, ignoring limit/offset.
hasMorebooleanWhether more mentions exist after this page.