Huddlekit Comments API

Read, create and change the status of comments.

Operations 3

GET /comments List comments on a project, web app or document #
POST /comments Create a comment #
PATCH /comments/{id} Change a comment's status #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/huddlekit-comments-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

huddlekit-comments-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Huddlekit Comments API
  version: 1.0.0
  summary: Read and create feedback comments, change their status and subscribe to comment webhooks.
  description: The Huddlekit REST API reads a workspace's projects, web apps, documents and comments, creates comments, changes a comment's status and manages webhook subscriptions.
  termsOfService: https://huddlekit.com/terms
  contact:
    name: Huddlekit
    email: hello@huddlekit.com
    url: https://huddlekit.com
servers:
- url: https://app.huddlekit.com/api/v1
  description: Production
security:
- apiKey: []
tags:
- name: Comments
  description: Read, create and change the status of comments.
paths:
  /comments:
    get:
      operationId: listComments
      tags:
      - Comments
      summary: List comments on a project, web app or document
      description: Returns the newest comments on one parent (a project, web app or document), newest first, up to `limit`. The fields returned depend on `surface`. Requires the `read` scope.
      parameters:
      - name: parent_id
        in: query
        required: true
        description: Id of the project, web app or document (from `listProjects`). Must belong to the key's workspace.
        schema:
          type: string
          format: uuid
      - name: project_id
        in: query
        required: false
        deprecated: true
        description: Deprecated alias of `parent_id`, used only when `parent_id` is absent.
        schema:
          type: string
          format: uuid
      - $ref: '#/components/parameters/Surface'
      - name: limit
        in: query
        required: false
        description: Maximum number of comments to return, 1 to 200. Defaults to 50. Out-of-range values are clamped.
        schema:
          type: integer
          minimum: 1
          maximum: 200
          default: 50
      responses:
        '200':
          description: Comments on the parent.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListCommentsResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
    post:
      operationId: createComment
      tags:
      - Comments
      summary: Create a comment
      description: Adds a comment to a project, web app or document in the key's workspace. The comment is attributed to a guest author named `API`, is not private, and gets the next comment number. It triggers a `comment.created` event with `source` set to `connector:`; webhook subscriptions created with the same key do not receive it. Requires the `write` scope.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CreateCommentRequest'
      responses:
        '201':
          description: The comment was created.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CreateCommentResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
  /comments/{id}:
    patch:
      operationId: updateCommentStatus
      tags:
      - Comments
      summary: Change a comment's status
      description: 'Sets the status of one comment. Status is the only field the API can change: comment text cannot be edited (sending `text` returns 400) and comments cannot be deleted. Setting `resolved` marks the comment resolved; any other status marks it unresolved. A real change triggers a `comment.status_changed` event with `source` set to `connector:`. Requires the `write` scope.'
      parameters:
      - name: id
        in: path
        required: true
        description: Id of the comment to update (a UUID).
        schema:
          type: string
          format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/UpdateCommentStatusRequest'
      responses:
        '200':
          description: The status was updated.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UpdateCommentStatusResponse'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
components:
  schemas:
    PlanRequiredError:
      type: object
      description: Returned with 403 when the key's workspace is not on a plan that includes API access.
      required:
      - error
      - requiredPlans
      properties:
        error:
          type: string
          description: Human-readable message naming the required plan.
        requiredPlans:
          type: array
          description: Plan ids that include API access.
          items:
            type: string
      example:
        error: This feature requires the Team plan.
        requiredPlans:
        - team
    CreateCommentRequest:
      type: object
      description: 'A new comment. Which location fields are allowed depends on `surface`: `path` for website; `url`, `page_title` and `path` for webapp; `page_number` and `video_timestamp` for document. Sending a location field that belongs to another surface is a 400 (except `path` on a document, which is ignored). A null or empty-string location field counts as not sent.'
      required:
      - parent_id
      - text
      properties:
        parent_id:
          type: string
          format: uuid
          description: Id of the project, web app or document to comment on (from `GET /projects`). Must belong to the key's workspace.
        project_id:
          type: string
          format: uuid
          deprecated: true
          description: Deprecated alias of `parent_id`, used only when `parent_id` is absent.
        surface:
          $ref: '#/components/schemas/Surface'
          default: website
          description: What `parent_id` refers to. Defaults to `website`.
        text:
          type: string
          minLength: 1
          maxLength: 10000
          description: Comment text. Must not be blank. At most 10,000 characters.
        status:
          $ref: '#/components/schemas/CommentStatus'
          default: open
          description: Initial status. Defaults to `open`.
        path:
          type: string
          maxLength: 2048
          description: Website and webapp only. Page path the comment is about, such as `/pricing`. Sanitized before it is stored. Defaults to `/` for a website, and to the path of `url` (or `/`) for a web app. Ignored for documents.
        url:
          type: string
          format: uri
          maxLength: 2048
          description: Webapp only. Full http:// or https:// URL of the page on your site that the comment is about.
        page_title:
          type: string
          maxLength: 500
          description: Webapp only. Title of the page. Trimmed; at most 500 characters.
        page_number:
          type: integer
          minimum: 1
          description: Document only. Page number, 1 or more. Defaults to 1.
        video_timestamp:
          type: number
          minimum: 0
          description: Document only, and only when the document is a video. Position in seconds, 0 or more.
      example:
        parent_id: 0d3c7a52-9e61-4f0b-8a2d-5b7e1c4f9a36
        surface: website
        text: Hero headline wraps badly at 1024px.
        path: /
    CommentStatus:
      type: string
      enum:
      - open
      - in-review
      - in-progress
      - resolved
      description: Workflow status of a comment. Setting `resolved` also marks the comment resolved; any other value marks it unresolved.
    CreateCommentResponse:
      type: object
      required:
      - comment
      - surface
      properties:
        comment:
          $ref: '#/components/schemas/CreatedComment'
        surface:
          $ref: '#/components/schemas/Surface'
      example:
        comment:
          id: 6b1f9c2e-4d7a-4c1b-9e3f-2a8d5c7b1e04
          comment_number: 43
          text: Hero headline wraps badly at 1024px.
          status: open
          created_at: '2026-09-27T08:00:00.000Z'
        surface: website
    WebsiteComment:
      type: object
      description: 'A comment on a website project (`surface: website`).'
      additionalProperties: false
      required:
      - id
      - comment_number
      - text
      - status
      - priority
      - resolved
      - is_private
      - path
      - screenshot
      - created_at
      - updated_at
      properties:
        id:
          type: string
          format: uuid
          description: Comment id.
        comment_number:
          type:
          - integer
          - 'null'
          description: 'Sequential number of the comment within its parent (shown as #42 in Huddlekit).'
        text:
          type: string
          description: The comment text as written.
        status:
          type:
          - string
          - 'null'
          enum:
          - open
          - in-review
          - in-progress
          - resolved
          - null
          description: 'Workflow status: `open`, `in-review`, `in-progress` or `resolved`.'
        priority:
          type:
          - string
          - 'null'
          enum:
          - Low
          - Medium
          - Critical
          - null
          description: Priority set in Huddlekit, or null when none is set.
        resolved:
          type:
          - boolean
          - 'null'
          description: Whether the comment is resolved.
        is_private:
          type: boolean
          description: Whether the comment is hidden from guests.
        path:
          type:
          - string
          - 'null'
          description: Page path on the website, relative to the project's URL.
        screenshot:
          type:
          - string
          - 'null'
          description: Screenshot of the page, or null if none has been captured.
        created_at:
          type:
          - string
          - 'null'
          format: date-time
          description: When the comment was created.
        updated_at:
          type:
          - string
          - 'null'
          format: date-time
          description: When the comment was last updated.
    Error:
      type: object
      description: Error body returned by every failed call.
      required:
      - error
      properties:
        error:
          type: string
          description: Short, human-readable error message.
        detail:
          type: string
          description: Extra explanation, when there is one.
      example:
        error: Unauthorized
        detail: Invalid or revoked API key
    UpdateCommentStatusRequest:
      type: object
      description: The new status. `status` is the only writable field; sending `text` is refused with a 400. Other fields are ignored.
      required:
      - status
      properties:
        status:
          $ref: '#/components/schemas/CommentStatus'
          description: New status for the comment.
        surface:
          $ref: '#/components/schemas/Surface'
          default: website
          description: Surface the comment belongs to. Defaults to `website`. A comment id looked up on the wrong surface returns 404.
      example:
        status: resolved
        surface: website
    UpdatedComment:
      type: object
      description: The comment after the update.
      required:
      - id
      - comment_number
      - text
      - status
      - updated_at
      properties:
        id:
          type: string
          format: uuid
          description: Comment id.
        comment_number:
          type:
          - integer
          - 'null'
          description: Sequential number of the comment within its parent.
        text:
          type: string
          description: The comment text (unchanged).
        status:
          type:
          - string
          - 'null'
          enum:
          - open
          - in-review
          - in-progress
          - resolved
          - null
          description: 'Workflow status: `open`, `in-review`, `in-progress` or `resolved`.'
        updated_at:
          type:
          - string
          - 'null'
          format: date-time
          description: When the comment was last updated.
    CreatedComment:
      type: object
      description: The comment that was created.
      required:
      - id
      - comment_number
      - text
      - status
      - created_at
      properties:
        id:
          type: string
          format: uuid
          description: Id of the new comment.
        comment_number:
          type:
          - integer
          - 'null'
          description: Sequential number of the comment within its parent.
        text:
          type: string
          description: The comment text.
        status:
          type:
          - string
          - 'null'
          enum:
          - open
          - in-review
          - in-progress
          - resolved
          - null
          description: 'Workflow status: `open`, `in-review`, `in-progress` or `resolved`.'
        created_at:
          type:
          - string
          - 'null'
          format: date-time
          description: When the comment was created.
    WebappComment:
      type: object
      description: 'A comment on a web app (`surface: webapp`).'
      additionalProperties: false
      required:
      - id
      - comment_number
      - text
      - status
      - priority
      - resolved
      - is_private
      - url
      - path
      - page_title
      - screenshot
      - created_at
      - updated_at
      properties:
        id:
          type: string
          format: uuid
          description: Comment id.
        comment_number:
          type:
          - integer
          - 'null'
          description: 'Sequential number of the comment within its parent (shown as #42 in Huddlekit).'
        text:
          type: string
          description: The comment text as written.
        status:
          type:
          - string
          - 'null'
          enum:
          - open
          - in-review
          - in-progress
          - resolved
          - null
          description: 'Workflow status: `open`, `in-review`, `in-progress` or `resolved`.'
        priority:
          type:
          - string
          - 'null'
          enum:
          - Low
          - Medium
          - Critical
          - null
          description: Priority set in Huddlekit, or null when none is set.
        resolved:
          type:
          - boolean
          - 'null'
          description: Whether the comment is resolved.
        is_private:
          type: boolean
          description: Whether the comment is hidden from guests.
        url:
          type:
          - string
          - 'null'
          description: Full URL of the page the comment is on.
        path:
          type: string
          description: Page path.
        page_title:
          type:
          - string
          - 'null'
          description: Title of the page the comment is on.
        screenshot:
          type:
          - string
          - 'null'
          description: Screenshot of the page, or null if none has been captured.
        created_at:
          type:
          - string
          - 'null'
          format: date-time
          description: When the comment was created.
        updated_at:
          type:
          - string
          - 'null'
          format: date-time
          description: When the comment was last updated.
    ListCommentsResponse:
      type: object
      required:
      - comments
      - surface
      properties:
        comments:
          type: array
          description: Comments on the parent, newest first. The shape of each item depends on `surface`.
          items:
            oneOf:
            - $ref: '#/components/schemas/WebsiteComment'
            - $ref: '#/components/schemas/WebappComment'
            - $ref: '#/components/schemas/DocumentComment'
        surface:
          $ref: '#/components/schemas/Surface'
      example:
        comments:
        - id: 6b1f9c2e-4d7a-4c1b-9e3f-2a8d5c7b1e04
          comment_number: 42
          text: The signup button overlaps the footer on mobile.
          status: open
          priority: Medium
          resolved: false
          is_private: false
          path: /pricing
          screenshot: null
          created_at: '2026-09-20T10:15:00.000Z'
          updated_at: '2026-09-20T10:15:00.000Z'
        surface: website
    Surface:
      type: string
      enum:
      - website
      - webapp
      - document
      description: 'What a comment is attached to. `website`: a website project (the parent is a project). `webapp`: a web app that runs the Huddlekit SDK widget (the parent is a web app). `document`: an uploaded PDF, image or video (the parent is a document).'
    DocumentComment:
      type: object
      description: 'A comment on a document (`surface: document`). Document comments have no path, URL or screenshot.'
      additionalProperties: false
      required:
      - id
      - comment_number
      - text
      - status
      - priority
      - resolved
      - is_private
      - page_number
      - video_timestamp
      - created_at
      - updated_at
      properties:
        id:
          type: string
          format: uuid
          description: Comment id.
        comment_number:
          type:
          - integer
          - 'null'
          description: 'Sequential number of the comment within its parent (shown as #42 in Huddlekit).'
        text:
          type: string
          description: The comment text as written.
        status:
          type:
          - string
          - 'null'
          enum:
          - open
          - in-review
          - in-progress
          - resolved
          - null
          description: 'Workflow status: `open`, `in-review`, `in-progress` or `resolved`.'
        priority:
          type:
          - string
          - 'null'
          enum:
          - Low
          - Medium
          - Critical
          - null
          description: Priority set in Huddlekit, or null when none is set.
        resolved:
          type:
          - boolean
          - 'null'
          description: Whether the comment is resolved.
        is_private:
          type: boolean
          description: Whether the comment is hidden from guests.
        page_number:
          type:
          - integer
          - 'null'
          description: Page of the document the comment is on (1-based).
        video_timestamp:
          type:
          - number
          - 'null'
          description: Position in seconds, for comments on a video; otherwise null.
        created_at:
          type:
          - string
          - 'null'
          format: date-time
          description: When the comment was created.
        updated_at:
          type:
          - string
          - 'null'
          format: date-time
          description: When the comment was last updated.
    UpdateCommentStatusResponse:
      type: object
      required:
      - comment
      - surface
      properties:
        comment:
          $ref: '#/components/schemas/UpdatedComment'
        surface:
          $ref: '#/components/schemas/Surface'
      example:
        comment:
          id: 6b1f9c2e-4d7a-4c1b-9e3f-2a8d5c7b1e04
          comment_number: 42
          text: The signup button overlaps the footer on mobile.
          status: resolved
          updated_at: '2026-09-27T08:05:00.000Z'
        surface: website
  responses:
    Forbidden:
      description: The key lacks the scope this call needs (`{"error":"Forbidden","detail":"This key lacks the \"read\" scope"}`), or the workspace has no active Team subscription (body includes `requiredPlans`).
      content:
        application/json:
          schema:
            anyOf:
            - $ref: '#/components/schemas/PlanRequiredError'
            - $ref: '#/components/schemas/Error'
          example:
            error: This feature requires the Team plan.
            requiredPlans:
            - team
    BadRequest:
      description: The request was invalid. `error` says which field and why.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: parent_id is required
    NotFound:
      description: Not found, or it belongs to another workspace (the two cases are indistinguishable on purpose). An id that isn't a valid UUID also answers 404.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: Not found
    TooManyRequests:
      description: 'Rate limit exceeded. Limits: 200 reads and 30 writes per minute per API key, counted per endpoint group (`/me`, `/projects`, `/comments`, `/comments/{id}`, `/hooks`, `/events/recent`) and separately for reads and writes; `DELETE /hooks/{id}` counts toward the `/hooks` writes. Refused calls count too. Wait the number of seconds in `Retry-After`, then retry.'
      headers:
        Retry-After:
          description: Whole seconds until the limit resets (at least 1).
          schema:
            type: integer
            minimum: 1
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: Too many requests
    InternalError:
      description: The request could not be completed.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Unauthorized:
      description: No API key, a malformed `Authorization` header, or an invalid, revoked or expired key.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: Unauthorized
            detail: 'Send your key as: Authorization: Bearer hk_live_…'
    ServiceUnavailable:
      description: A temporary failure, such as the API key, the workspace plan or the parent record could not be checked. Safe to retry.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: Could not verify the workspace plan
  parameters:
    Surface:
      name: surface
      in: query
      required: false
      description: What `parent_id` refers to. Defaults to `website`.
      schema:
        $ref: '#/components/schemas/Surface'
        default: website
  securitySchemes:
    apiKey:
      type: http
      scheme: bearer
      bearerFormat: hk_live_ + 64 hex characters
      description: 'Workspace API key, created in the Huddlekit app and shown once. Send it as `Authorization: Bearer hk_live_<64 lowercase hex characters>`. The key identifies the workspace; there is no user session. GET calls need the `read` scope; POST, PATCH and DELETE calls need `write`.'
externalDocs:
  description: REST API guide
  url: https://huddlekit.com/support/using-the-rest-api