Query comments

Fetch comments for any record, chat, or status update with the commentList query — scoped by category, paginated, and ordered.


Use the commentList query to read comments from any surface in Blue. There is one comment store across the product, so a single query serves all three targets: pass a category (DISCUSSION, STATUS_UPDATE, or TODO) plus the categoryId of the thing you’re reading. The result is a CommentList with the page of comments, pagination metadata, and a totalCount.

commentList is the canonical way to fetch comments. The older Chat.comments, StatusUpdate.comments, and Todo.comments fields are deprecated in favor of it — see Comments overview for the comment model and the category/categoryId targeting convention.

Request

Fetch the top-level comments on a record. category is TODO and categoryId is the record (Todo) ID.

query RecordComments {
  commentList(category: TODO, categoryId: "todo_123") {
    comments {
      id
      text
      createdAt
      user {
        id
        fullName
      }
    }
    totalCount
  }
}

The same query shape reads a chat (category: DISCUSSION, categoryId = the chat ID) or a status update (category: STATUS_UPDATE, categoryId = the status-update ID). Only category and categoryId change.

Parameters

Arguments

ArgumentTypeRequiredDescription
categoryCommentCategory!YesWhich kind of target you’re reading. Pairs with categoryId.
categoryIdString!YesThe ID of the target: a chat ID, a status-update ID, or a record (Todo) ID, per category.
firstIntNoPage size — how many comments to return. Defaults to 20 when omitted.
skipIntNoNumber of comments to skip before the page, for offset pagination. Defaults to 0.
afterStringNoCursor: return comments whose id is greater than or equal to this value. Use a comment id.
orderByChatOrderByInputNoSort order. Defaults to createdAt_ASC (oldest first).
beforeStringNoAccepted by the schema but not applied by this query. Paginate with first + skip (or after).
lastIntNoAccepted by the schema but not applied by this query. Use first for the page size.

CommentCategory

ValuecategoryId is the ID ofRead instead via
DISCUSSIONA chat threadQuery chats
STATUS_UPDATEA status updateThe status update’s ID
TODOA record (Todo)List records

ChatOrderByInput

orderBy takes a single ChatOrderByInput value (the type is shared with chatList). For comments the meaningful sorts are by timestamp:

ValueSorts comments by
createdAt_ASC / createdAt_DESCCreation time. createdAt_ASC is default.
updatedAt_ASC / updatedAt_DESCLast-edited time.
id_ASC / id_DESCComment ID.

Response

{
  "data": {
    "commentList": {
      "comments": [
        {
          "id": "clm4n8qwx000008l0g4oxdqn7",
          "text": "Kicking off the launch checklist — see the linked doc.",
          "createdAt": "2026-05-20T09:14:00.000Z",
          "user": {
            "id": "clm4n8qwx000108l0haz1f2pe",
            "fullName": "Ada Lovelace"
          }
        },
        {
          "id": "clm4n8qwx000208l0bk7c9xqz",
          "text": "Pricing copy is approved.",
          "createdAt": "2026-05-21T16:02:00.000Z",
          "user": {
            "id": "clm4n8qwx000308l0e1g5m4ab",
            "fullName": "Grace Hopper"
          }
        }
      ],
      "totalCount": 2
    }
  }
}

CommentList

FieldTypeDescription
comments[Comment!]!The top-level comments on this page, in orderBy order.
pageInfoPageInfo!Pagination metadata for the page (below).
totalCountInt!Total top-level comments on the target, across all pages.

PageInfo

FieldTypeDescription
totalItemsIntTotal matching comments, across all pages (mirrors totalCount).
totalPagesIntTotal pages at the current first.
pageIntCurrent page, derived from skip and first.
perPageIntPage size in effect (the resolved first).
hasNextPageBoolean!Whether a next page exists.
hasPreviousPageBoolean!Whether a previous page exists.
startCursorStringDeprecated. Paginate with first/skip (or after), not these cursors.
endCursorStringDeprecated. See startCursor.

Comment

The fields you’ll select most often. The Comment type exposes more — these are the common ones; the full set is documented in Comments overview.

FieldTypeDescription
idID!Unique identifier.
uidString!Short, human-facing identifier.
htmlString!Comment body as HTML.
textString!Comment body as plain text.
categoryCommentCategory!The target kind this comment belongs to.
createdAtDateTime!Creation timestamp.
updatedAtDateTime!Last-edited timestamp.
deletedAtDateTimeSet when the comment was soft-deleted; the body is blanked but the row remains.
deletedByUserWho soft-deleted the comment. Select fullName/email, not name.
userUser!The author. Select fullName/email, not name.
parentIdStringThe parent comment’s ID when this is a reply. Always null for items returned here.
parentCommentThe parent comment, when this is a reply.
replies[Comment!]!Threaded replies to this comment.
replyCountInt!Number of replies.
isReadBooleanRead state for the current user.
isSeenBooleanSeen state for the current user.
reactions[ReactionGroup!]!Emoji reactions on the comment. See Reactions.
chatChatThe parent chat, when category is DISCUSSION.
statusUpdateStatusUpdateThe parent status update, when category is STATUS_UPDATE.
todoTodoThe parent record, when category is TODO.

Full example

Read the second page of a chat’s comments (10 per page, newest first), with reply counts and reactions.

query ChatComments {
  commentList(
    category: DISCUSSION
    categoryId: "chat_123"
    first: 10
    skip: 10
    orderBy: createdAt_DESC
  ) {
    comments {
      id
      uid
      html
      text
      createdAt
      updatedAt
      replyCount
      isRead
      user {
        id
        fullName
        email
      }
      reactions {
        emoji
        count
        reactedByMe
      }
    }
    pageInfo {
      totalItems
      totalPages
      page
      perPage
      hasNextPage
      hasPreviousPage
    }
    totalCount
  }
}

Errors

This query degrades gracefully: a categoryId that doesn’t exist (or points at a target you can’t see) yields an empty comments list and a totalCount of 0, rather than an error. Errors are reserved for authentication.

CodeWhen
UNAUTHENTICATEDThe request carries no valid credentials.

Permissions

Any authenticated caller can run commentList. Visibility is then scoped to the caller:

  • A role configured with show-only-mentioned-comments sees a filtered subset — only comments the user authored or in which the user is mentioned. totalCount reflects that filtered set, not the thread’s full comment count.
  • Comments on targets the caller can’t access return nothing rather than erroring.