---
title: "List comments"
method: GET
path: "/api/apps/{app_id}/comments"
---

# List comments

`GET /api/apps/{app_id}/comments`

<Info>This API is in beta. Endpoints, fields, and behavior may still change, so avoid depending on it in production.</Info>

Returns the app's open comment threads with all their comments, newest first. Set `include_resolved` to `true` to include resolved threads too.

Threads are ordered by when they were created, newest first. A page holds up to `limit` threads, 500 by default. While `has_more` is `true`, request the next page with `cursor` set to `next_cursor`, and send nothing else beside it. A cursor works for 24 hours, only on this app. A thread created after you start paging shows up on a fresh first page, not in later pages.

Screenshot links in the response work for one hour. Call this again for fresh ones, or use [Create comment screenshot link](/api-reference/create-comment-screenshot-link) for a link that lasts a year.

This is limited to 600 requests per minute per app, shared by [List comments](/api-reference/list-comments) and [List mentionable users](/api-reference/list-mentionable-users). A signed-in session has its own limit, and every personal access token for the workspace shares one. Some workspaces have a different limit. Every request that counts against the limit gets `X-RateLimit-Limit`, `X-RateLimit-Remaining` and `X-RateLimit-Reset` (Unix time in seconds) headers, and a `429` also gets `Retry-After` in seconds. If the limiter itself is unavailable, requests go through without these headers.

<Note>Call this as an editor of the app, with a personal access token sent as a Bearer token or from a signed-in session. A read-only token works here. Workspace API keys aren't accepted.</Note>

<Warning>The response includes fields beyond the ones documented here. Don't rely on undocumented response fields, as they can change at any time.</Warning>

## Path parameters

- `app_id` string, required — ID of the app.

## Query parameters

- `include_resolved` boolean, nullable — Set to `true` to include resolved threads. Defaults to `false`.
- `limit` integer, nullable — Threads per page, 1 to 500. Defaults to 500.
- `cursor` string, nullable — `next_cursor` from the previous page. Send it on its own: it carries `include_resolved` and `limit`, so sending either beside it returns a `400`.

## Response `200`

One page of the app's comment threads, newest first.

- CommentThreadList — One page of an app's comment threads.
  - `items` CommentThreadItem[], required — Threads on this page, newest first.
    - `thread` CommentThread, required — A comment thread's state.
      - `id` string, required — ID of the thread.
      - `page_path` string, required — Path of the app page the thread is on.
      - `anchor` CommentAnchor, required — Where a comment thread is pinned in the app's preview. When the builder's AI edits the anchored file, Base44 moves an open thread's `source_location` to the element's new line.
        - `source_location` string, nullable — Position of the element's tag in the app's code, as `file:line:column`, exactly as the element's `data-source-location` attribute in the preview. The pin shows only on an element with this value. `null` for a thread with no pin.
        - `element_tag` string, nullable — HTML tag of the element, such as `button`.
        - `instance_index` integer, nullable — Which of the elements sharing `source_location` the pin is on, counting from `0` in page order, for an element repeated in a list. `null` means the first.
        - `point` CommentAnchorPoint — Fractions of the anchored element's rect, not of the document.
          - `x` number, required — Horizontal position, as a fraction of the element's width.
          - `y` number, required — Vertical position, as a fraction of the element's height.
        - `crop` CommentAnchorCrop — The screenshot's area in page pixels: the visible area plus the page's scroll when it was taken.
          - `x` number, required — Left edge, in page pixels.
          - `y` number, required — Top edge, in page pixels, scroll included.
          - `width` number, required — Width, in pixels.
          - `height` number, required — Height, in pixels.
        - `region` CommentAnchorRegion — The screenshot's area as fractions of the visible preview when it was taken, so it depends on the scroll.
          - `x` number, required — Left edge, as a fraction of the preview's width.
          - `y` number, required — Top edge, as a fraction of the preview's height.
          - `width` number, required — Width, as a fraction of the preview's width.
          - `height` number, required — Height, as a fraction of the preview's height.
        - `viewport_size` CommentAnchorViewportSize — Size of the preview when the screenshot was taken.
          - `width` integer, required — Width of the preview, in pixels.
          - `height` integer, required — Height of the preview, in pixels.
      - `screenshot_url` string, nullable, required — Signed link to the screenshot attached to the thread, valid for one hour. `null` when the thread has no screenshot or it can't be read.
      - `resolved_at` string, date-time, nullable, required — When the thread was resolved, in UTC, or `null` while it's open.
      - `message_count` integer, required — Number of replies, not counting the first comment.
      - `last_activity_at` string, date-time, nullable, required — When the thread was created or last replied to, in UTC.
      - `created_date` string, date-time, required — When the thread was created, in UTC.
      - `agent_working_since` string, date-time, nullable, required — When the builder agent started working on the thread, in UTC, or `null` when it isn't working on it. A value older than an hour is left over from a turn that stopped.
      - `unread` boolean, required — Whether the thread has a comment from someone else posted after you last read it. Always `false` in the responses of Create comment and Update comment anchor.
    - `comment` CommentMessage, required — One comment: the first comment of a thread or a reply.
      - `id` string, required — ID of the comment.
      - `content` string, required — Text of the comment.
      - `sender_id` string, required — ID of the Base44 user who wrote it, or `base44` for a reply from the builder agent.
      - `sender_name` string, required — Name of the author when they wrote it, or their email when they had no name. `Base44` for the builder agent.
      - `sender_avatar_url` string, nullable, required — URL of the author's profile image, or `null` when they have none.
      - `created_date` string, date-time, required — When the comment was posted, in UTC.
      - `edited_at` string, date-time, nullable, required — When the comment was last edited, in UTC, or `null` when it never was.
      - `reactions` object, required — Each emoji reacted with, mapped to the IDs of the users who reacted with it.
    - `replies` CommentMessage[], required — Replies, oldest first.
      - `id` string, required — ID of the comment.
      - `content` string, required — Text of the comment.
      - `sender_id` string, required — ID of the Base44 user who wrote it, or `base44` for a reply from the builder agent.
      - `sender_name` string, required — Name of the author when they wrote it, or their email when they had no name. `Base44` for the builder agent.
      - `sender_avatar_url` string, nullable, required — URL of the author's profile image, or `null` when they have none.
      - `created_date` string, date-time, required — When the comment was posted, in UTC.
      - `edited_at` string, date-time, nullable, required — When the comment was last edited, in UTC, or `null` when it never was.
      - `reactions` object, required — Each emoji reacted with, mapped to the IDs of the users who reacted with it.
    - `reactor_names` object, required — User ID mapped to name, for the people who reacted anywhere in the thread.
  - `has_more` boolean, required — Whether more threads follow this page.
  - `next_cursor` string, nullable, required — Pass as `cursor` to get the next page. `null` on the last page.

## Other responses

- `400` — `cursor` is invalid, expired, or from another app, or `include_resolved` or `limit` was sent beside it.
- `401` — Missing or invalid credentials.
- `403` — You don't have editor access to this app, the app is blocked, or you used a workspace API key.
- `404` — App not found.
- `409` — Your workspace requires an unlocked SSO session.
- `422` — Validation Error
- `429` — Rate limit exceeded. Wait the number of seconds in `Retry-After` before retrying.

## Changes

> 28 revisions in range; 1 not diffed.

- **2026-10-06** `dddf17e0f9f0` — 1 info
  - endpoint added

[Change history](https://skmtc.dev/adexad/apis/base44-app-management-api/changes/api/apps/:app_id/comments/get.md)

---

[API](https://skmtc.dev/adexad/apis/base44-app-management-api.md) · [All operations](https://skmtc.dev/adexad/apis/base44-app-management-api/llms.txt) · [OpenAPI document](https://skmtc.dev/adexad/apis/base44-app-management-api/revisions/99df85f579f9?raw)
