> ## Documentation Index
> Fetch the complete documentation index at: https://docs.base44.com/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Internal links on these pages omit the .md extension. Append .md to a docs page URL, or send an Accept: text/markdown header, to get that page as markdown.

# Create comment

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

Starts a new comment thread on the app with its first comment.

Set `page_path` to the app page the comment is about. `anchor` pins the thread to an element of the app's preview. The builder fills it in when you click an element, and `source_location` must match that element's `data-source-location` attribute in the preview for a pin to show. Leave `anchor` out to post a thread with no pin. It still shows in the builder's comments panel.

To attach a screenshot, upload the image with [Upload app file](/api-reference/upload-app-file) and `visibility` set to `private`, then pass its `file_uri` as `screenshot_file_uri`. Only private files uploaded to this app are accepted.

`mentioned_emails` records who the comment mentions. Only emails that [List mentionable users](/api-reference/list-mentionable-users) returns are kept, and the rest are dropped without an error. Mentioning someone sends them no email or notification, and responses never return the list.

Comments don't reach the builder agent on their own. It only works on a thread when someone sends the thread to the builder chat from the builder. Anyone with the app open in the builder sees the change right away.

This is limited to 120 requests per minute per app, shared by every other comments endpoint. 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. Viewers in the app's workspace, read-only tokens, and workspace API keys are refused.</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>



## OpenAPI

````yaml /developers/references/app-management/app-management-openapi.json post /api/apps/{app_id}/comments
openapi: 3.1.0
info:
  title: Base44 App Management API
  version: 1.0.0
servers:
  - url: https://app.base44.com
security:
  - PersonalAccessTokenAuth: []
paths:
  /api/apps/{app_id}/comments:
    post:
      summary: Create comment
      description: >-
        <Info>This API is in beta. Endpoints, fields, and behavior may still
        change, so avoid depending on it in production.</Info>


        Starts a new comment thread on the app with its first comment.


        Set `page_path` to the app page the comment is about. `anchor` pins the
        thread to an element of the app's preview. The builder fills it in when
        you click an element, and `source_location` must match that element's
        `data-source-location` attribute in the preview for a pin to show. Leave
        `anchor` out to post a thread with no pin. It still shows in the
        builder's comments panel.


        To attach a screenshot, upload the image with [Upload app
        file](/api-reference/upload-app-file) and `visibility` set to `private`,
        then pass its `file_uri` as `screenshot_file_uri`. Only private files
        uploaded to this app are accepted.


        `mentioned_emails` records who the comment mentions. Only emails that
        [List mentionable users](/api-reference/list-mentionable-users) returns
        are kept, and the rest are dropped without an error. Mentioning someone
        sends them no email or notification, and responses never return the
        list.


        Comments don't reach the builder agent on their own. It only works on a
        thread when someone sends the thread to the builder chat from the
        builder. Anyone with the app open in the builder sees the change right
        away.


        This is limited to 120 requests per minute per app, shared by every
        other comments endpoint. 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. Viewers in the app's
        workspace, read-only tokens, and workspace API keys are refused.</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>
      operationId: create_app_comment_api_apps__app_id__comments_post
      parameters:
        - name: app_id
          in: path
          required: true
          schema:
            type: string
            description: ID of the app.
            title: App Id
          description: ID of the app.
          example: 6820f3a4e7b91d003c45a1f2
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateAppCommentPayload'
      responses:
        '200':
          description: The new thread with its first comment.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CommentThreadItem'
        '400':
          description: '`screenshot_file_uri` isn''t a private file uploaded to this app.'
        '401':
          description: Missing or invalid credentials.
        '403':
          description: >-
            You don't have editor access to this app, you're a viewer in the
            app's workspace, the app is blocked, or your token is read-only or a
            workspace API key.
        '404':
          description: App not found.
        '409':
          description: Your workspace requires an unlocked SSO session.
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
        '429':
          description: >-
            Rate limit exceeded. Wait the number of seconds in `Retry-After`
            before retrying.
components:
  schemas:
    CreateAppCommentPayload:
      properties:
        content:
          type: string
          maxLength: 5000
          minLength: 1
          title: Content
          description: Text of the comment, 1 to 5000 characters.
          example: Make this button match the header color.
        page_path:
          type: string
          maxLength: 512
          title: Page Path
          description: Path of the app page the comment is about. Defaults to `/`.
          default: /
          example: /pricing
        anchor:
          $ref: '#/components/schemas/CommentAnchor'
          description: >-
            Where to pin the thread in the app's preview. Leave it out for a
            thread with no pin.
        screenshot_file_uri:
          anyOf:
            - type: string
              maxLength: 2000
            - type: 'null'
          title: Screenshot File Uri
          description: >-
            `file_uri` of a screenshot uploaded to this app with [Upload app
            file](/api-reference/upload-app-file) and `visibility` set to
            `private`. Starts with `mp/private/` followed by the app's ID.
          example: mp/private/6820f3a4e7b91d003c45a1f2/4b1e9c2a7_shot.png
        mentioned_emails:
          items:
            type: string
          type: array
          maxItems: 50
          title: Mentioned Emails
          description: >-
            Emails of up to 50 people the comment mentions. Mentions send no
            notification.
          example:
            - dana@acme.com
      type: object
      required:
        - content
      title: CreateAppCommentPayload
      description: A new comment thread.
    CommentThreadItem:
      properties:
        thread:
          $ref: '#/components/schemas/CommentThread'
          description: The thread's state.
        comment:
          $ref: '#/components/schemas/CommentMessage'
          description: The first comment, which started the thread.
        replies:
          items:
            $ref: '#/components/schemas/CommentMessage'
          type: array
          title: Replies
          description: Replies, oldest first.
          example:
            - content: Done, it now uses the header blue.
              created_date: '2026-10-05T09:14:22.512000Z'
              id: 68e2b80fd4f0a9001c3e5a21
              reactions: {}
              sender_id: base44
              sender_name: Base44
        reactor_names:
          additionalProperties:
            type: string
          type: object
          title: Reactor Names
          description: >-
            User ID mapped to name, for the people who reacted anywhere in the
            thread.
          example:
            6820f41be7b91d003c45a20a: Dana Levi
      type: object
      required:
        - thread
        - comment
        - replies
        - reactor_names
      title: CommentThreadItem
      description: A comment thread with all its comments.
    HTTPValidationError:
      properties:
        detail:
          items:
            $ref: '#/components/schemas/ValidationError'
          type: array
          title: Detail
      type: object
      title: HTTPValidationError
    CommentAnchor:
      properties:
        source_location:
          anyOf:
            - type: string
              maxLength: 512
            - type: 'null'
          title: Source Location
          description: >-
            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.
          example: pages/Pricing.jsx:42:8
        element_tag:
          anyOf:
            - type: string
              maxLength: 64
            - type: 'null'
          title: Element Tag
          description: HTML tag of the element, such as `button`.
          example: button
        instance_index:
          anyOf:
            - type: integer
              minimum: 0
            - type: 'null'
          title: Instance Index
          description: >-
            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.
          example: 0
        point:
          anyOf:
            - $ref: '#/components/schemas/CommentAnchorPoint'
            - type: 'null'
          description: >-
            Where on the element the pin sits. `null` puts it at the middle of
            the top edge.
        crop:
          anyOf:
            - $ref: '#/components/schemas/CommentAnchorCrop'
            - type: 'null'
          description: >-
            Area of the page the screenshot shows, used to redraw the crop box
            in the builder.
        region:
          anyOf:
            - $ref: '#/components/schemas/CommentAnchorRegion'
            - type: 'null'
          description: Area of the visible preview the screenshot shows when it was taken.
        viewport_size:
          anyOf:
            - $ref: '#/components/schemas/CommentAnchorViewportSize'
            - type: 'null'
          description: Size of the preview when the screenshot was taken.
      type: object
      title: CommentAnchor
      description: >-
        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.
    CommentThread:
      properties:
        id:
          type: string
          title: Id
          description: ID of the thread.
          example: 68e2b7c1d4f0a9001c3e5a17
        page_path:
          type: string
          title: Page Path
          description: Path of the app page the thread is on.
          example: /pricing
        anchor:
          $ref: '#/components/schemas/CommentAnchor'
          description: Where the thread is pinned in the app's preview.
        screenshot_url:
          anyOf:
            - type: string
            - type: 'null'
          title: Screenshot Url
          description: >-
            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.
          example: >-
            https://static.base44.com/images/private/6820f3a4e7b91d003c45a1f2/4b1e9c2a7_shot.png?token=eyJhbGciOi
        resolved_at:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: Resolved At
          description: When the thread was resolved, in UTC, or `null` while it's open.
          example: '2026-10-05T09:14:22.512000Z'
        message_count:
          type: integer
          title: Message Count
          description: Number of replies, not counting the first comment.
          example: 2
        last_activity_at:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: Last Activity At
          description: When the thread was created or last replied to, in UTC.
          example: '2026-10-05T09:14:22.512000Z'
        created_date:
          type: string
          format: date-time
          title: Created Date
          description: When the thread was created, in UTC.
          example: '2026-10-05T09:14:22.512000Z'
        agent_working_since:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: Agent Working Since
          description: >-
            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.
          example: '2026-10-05T09:14:22.512000Z'
        unread:
          type: boolean
          title: Unread
          description: >-
            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.
          example: true
      type: object
      required:
        - id
        - page_path
        - anchor
        - screenshot_url
        - resolved_at
        - message_count
        - last_activity_at
        - created_date
        - agent_working_since
        - unread
      title: CommentThread
      description: A comment thread's state.
    CommentMessage:
      properties:
        id:
          type: string
          title: Id
          description: ID of the comment.
          example: 68e2b7c4d4f0a9001c3e5a1c
        content:
          type: string
          title: Content
          description: Text of the comment.
          example: Make this button match the header color.
        sender_id:
          type: string
          title: Sender Id
          description: >-
            ID of the Base44 user who wrote it, or `base44` for a reply from the
            builder agent.
          example: 6820f41be7b91d003c45a20a
        sender_name:
          type: string
          title: Sender Name
          description: >-
            Name of the author when they wrote it, or their email when they had
            no name. `Base44` for the builder agent.
          example: Dana Levi
        sender_avatar_url:
          anyOf:
            - type: string
            - type: 'null'
          title: Sender Avatar Url
          description: URL of the author's profile image, or `null` when they have none.
          example: https://lh3.googleusercontent.com/a/ACg8ocJ2
        created_date:
          type: string
          format: date-time
          title: Created Date
          description: When the comment was posted, in UTC.
          example: '2026-10-05T09:14:22.512000Z'
        edited_at:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: Edited At
          description: >-
            When the comment was last edited, in UTC, or `null` when it never
            was.
          example: '2026-10-05T09:14:22.512000Z'
        reactions:
          additionalProperties:
            items:
              type: string
            type: array
          type: object
          title: Reactions
          description: >-
            Each emoji reacted with, mapped to the IDs of the users who reacted
            with it.
          example:
            👍:
              - 6820f41be7b91d003c45a20a
      type: object
      required:
        - id
        - content
        - sender_id
        - sender_name
        - sender_avatar_url
        - created_date
        - edited_at
        - reactions
      title: CommentMessage
      description: 'One comment: the first comment of a thread or a reply.'
    ValidationError:
      properties:
        loc:
          items:
            anyOf:
              - type: string
              - type: integer
          type: array
          title: Location
        msg:
          type: string
          title: Message
        type:
          type: string
          title: Error Type
      type: object
      required:
        - loc
        - msg
        - type
      title: ValidationError
    CommentAnchorPoint:
      properties:
        x:
          type: number
          maximum: 1
          minimum: 0
          title: X
          description: Horizontal position, as a fraction of the element's width.
          example: 0.5
        'y':
          type: number
          maximum: 1
          minimum: 0
          title: 'Y'
          description: Vertical position, as a fraction of the element's height.
          example: 0.5
      type: object
      required:
        - x
        - 'y'
      title: CommentAnchorPoint
      description: Fractions of the anchored element's rect, not of the document.
    CommentAnchorCrop:
      properties:
        x:
          type: number
          title: X
          description: Left edge, in page pixels.
          example: 512
        'y':
          type: number
          title: 'Y'
          description: Top edge, in page pixels, scroll included.
          example: 1340
        width:
          type: number
          exclusiveMinimum: 0
          title: Width
          description: Width, in pixels.
          example: 240
        height:
          type: number
          exclusiveMinimum: 0
          title: Height
          description: Height, in pixels.
          example: 96
      type: object
      required:
        - x
        - 'y'
        - width
        - height
      title: CommentAnchorCrop
      description: >-
        The screenshot's area in page pixels: the visible area plus the page's
        scroll when it was taken.
    CommentAnchorRegion:
      properties:
        x:
          type: number
          maximum: 1
          minimum: 0
          title: X
          description: Left edge, as a fraction of the preview's width.
          example: 0.42
        'y':
          type: number
          maximum: 1
          minimum: 0
          title: 'Y'
          description: Top edge, as a fraction of the preview's height.
          example: 0.18
        width:
          type: number
          maximum: 1
          minimum: 0
          title: Width
          description: Width, as a fraction of the preview's width.
          example: 0.2
        height:
          type: number
          maximum: 1
          minimum: 0
          title: Height
          description: Height, as a fraction of the preview's height.
          example: 0.08
      type: object
      required:
        - x
        - 'y'
        - width
        - height
      title: CommentAnchorRegion
      description: >-
        The screenshot's area as fractions of the visible preview when it was
        taken, so it depends on the scroll.
    CommentAnchorViewportSize:
      properties:
        width:
          type: integer
          minimum: 1
          title: Width
          description: Width of the preview, in pixels.
          example: 1280
        height:
          type: integer
          minimum: 1
          title: Height
          description: Height of the preview, in pixels.
          example: 800
      type: object
      required:
        - width
        - height
      title: CommentAnchorViewportSize
      description: Size of the preview when the screenshot was taken.
  securitySchemes:
    PersonalAccessTokenAuth:
      type: http
      scheme: bearer
      description: 'Personal access token, sent as `Authorization: Bearer <token>`.'

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.