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

# List project survey response

> Returns a page of responses, oldest first, with an opaque keyset cursor. The cursor is keyset (timestamp, response_id) rather than an offset, so a client polling forward through history never skips a response or sees one twice as new rows arrive. No per-response score is returned: a score is a property of a population, not of one answer. Requires the feedback-survey:read permission.



## OpenAPI

````yaml agent-platform/api-specs/public-feedback-survey.yaml get /api/public/feedback/projects/{projectId}
openapi: 3.1.0
info:
  title: Public Feedback Survey API
  version: 1.0.0
  description: >-
    Partner-facing survey capture and retrieval. A partner collects ratings in
    their own channels, submits them here against a survey referenced by name,
    then polls the survey's responses back with stable keyset pagination.

    Authentication is by platform API key only (x-api-key: abl_*, or
    Authorization: Bearer abl_*). The key is the registered origin: its clientId
    is resolved server-side and stamped on every submitted response, so a body
    can never set origin, capture method, the survey template id, or a score —
    those fields are refused rather than ignored. A user session (JWT) has no
    clientId and is refused on both endpoints.

    Retrieval returns the survey's COMPLETE responses — runtime-captured and
    every integration's — to any credential holding the read scope; the audience
    is the project's own team, not mutually-distrusting partners. Each row
    carries response_source so a caller can still separate capture paths.
servers:
  - url: /
security: []
paths:
  /api/public/feedback/projects/{projectId}:
    get:
      summary: List the project's survey responses
      description: >-
        Returns a page of responses, oldest first, with an opaque keyset cursor.
        The cursor is keyset (timestamp, response_id) rather than an offset, so
        a client polling forward through history never skips a response or sees
        one twice as new rows arrive. No per-response score is returned: a score
        is a property of a population, not of one answer. Requires the
        feedback-survey:read permission.
      operationId: listSurveyResponses
      parameters:
        - $ref: '#/components/parameters/ProjectId'
        - $ref: '#/components/parameters/ApiKey'
        - $ref: '#/components/parameters/Limit'
        - $ref: '#/components/parameters/Cursor'
        - $ref: '#/components/parameters/SurveyFilter'
        - $ref: '#/components/parameters/From'
        - $ref: '#/components/parameters/To'
      responses:
        '200':
          $ref: '#/components/responses/ResponsePage'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/SurveyNotFound'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/ServerError'
components:
  parameters:
    ProjectId:
      name: projectId
      in: path
      required: true
      schema:
        type: string
    ApiKey:
      name: x-api-key
      in: header
      required: true
      schema:
        type: string
        pattern: ^abl_
    Limit:
      name: limit
      in: query
      required: false
      description: >-
        Responses per page. Values above the maximum are capped rather than
        rejected; a missing or non-positive value falls back to the default.
      schema:
        type: integer
        minimum: 1
        maximum: 200
        default: 50
    Cursor:
      name: cursor
      in: query
      required: false
      description: >-
        Opaque keyset cursor from a prior page's nextCursor. A cursor this
        endpoint did not issue is rejected with 400 INVALID_CURSOR rather than
        silently restarting the feed.
      schema:
        type: string
        maxLength: 512
    SurveyFilter:
      name: survey
      in: query
      required: false
      description: >-
        Restrict the page to one survey, by its name. A name that resolves to no
        survey is a 404, not an empty page.
      schema:
        type: string
    From:
      name: from
      in: query
      required: false
      description: Inclusive lower bound on submitted_at.
      schema:
        type: string
        format: date-time
    To:
      name: to
      in: query
      required: false
      description: Inclusive upper bound on submitted_at.
      schema:
        type: string
        format: date-time
  responses:
    ResponsePage:
      description: A page of responses.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ResponsePage'
    BadRequest:
      description: >-
        The request shape was invalid. Codes: INVALID_BODY, SURVEY_REQUIRED,
        RATING_REQUIRED, INVALID_COMMENT, COMMENT_TOO_LONG, FIELD_NOT_ACCEPTED,
        UNKNOWN_FIELD (submit); INVALID_CURSOR (list).
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Unauthorized:
      description: Authentication is required. Code AUTHENTICATION_REQUIRED.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Forbidden:
      description: >-
        The credential is not permitted. ORIGIN_UNRESOLVED when the credential
        has no registered origin (for example a user session rather than an API
        key); otherwise a missing feedback-survey:write / feedback-survey:read
        permission.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    SurveyNotFound:
      description: The named survey does not exist in this project. Code SURVEY_NOT_FOUND.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    RateLimited:
      description: The credential's rate allowance is exhausted.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    ServerError:
      description: >-
        The request could not be completed. SUBMIT_FAILED on submit,
        RETRIEVAL_FAILED on list.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  schemas:
    ResponsePage:
      type: object
      required:
        - success
        - data
      properties:
        success:
          type: boolean
          const: true
        data:
          type: object
          required:
            - responses
            - nextCursor
          properties:
            responses:
              type: array
              items:
                $ref: '#/components/schemas/PublicSurveyResponse'
            nextCursor:
              type:
                - string
                - 'null'
              description: Cursor for the next page, or null when this is the last page.
    Error:
      type: object
      required:
        - success
        - error
      properties:
        success:
          type: boolean
          const: false
        error:
          type: object
          required:
            - code
            - message
          properties:
            code:
              type: string
              description: A stable
              machine-readable error code.: null
            message:
              type: string
              description: A human-readable explanation.
    PublicSurveyResponse:
      type: object
      required:
        - response_id
        - survey
        - survey_id
        - rating
        - rating_type
        - submitted_at
        - session_id
        - channel
        - response_source
        - has_comment
        - comment_length
      properties:
        response_id:
          type: string
          description: The response's stable id.
        survey:
          type: string
          description: >-
            The survey's CURRENT name, for display only. Empty when the survey
            was since deleted, or when the response answered no survey. Never
            correlate on this; use survey_id.
        survey_id:
          type: string
          description: >-
            The survey's stable identity. This is what the response is
            attributed to and what survives a rename.
        rating:
          type: number
          description: The value given
          on the control's own scale.: null
        rating_type:
          $ref: '#/components/schemas/RatingType'
        submitted_at:
          type: string
          format: date-time
        session_id:
          type: string
        channel:
          type: string
        response_source:
          type: string
          description: >-
            How the response was captured: runtime for in-product capture, or
            the submitter's own label (default external) for API submissions.
        comment:
          type: string
          description: >-
            The comment, when one was given. Absent when the response carried
            none.
        has_comment:
          type: boolean
        comment_length:
          type: integer
          minimum: 0
          description: >-
            Length of the comment, or 0 when none. Lets a caller size a comment
            before displaying it.
    RatingType:
      type: string
      description: >-
        The survey's rating control. Each implies the range its rating is
        checked against: thumbs 0-1 (0 dislike, 1 like), star 1-5, scale 0-10.
        text collects no rating.
      enum:
        - thumbs
        - star
        - scale
        - text

````