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

# List sessions

> Sessions in this environment. Filter by contentId / userId.



## OpenAPI

````yaml /api-reference-v2/openapi.json get /v2/projects/{projectId}/environments/{environmentId}/sessions
openapi: 3.0.0
info:
  title: Usertour API v2
  description: >-
    Project-scoped v2 API. Authenticate with a personal API token — an opaque
    `utp_...` string (NOT a JWT: do not try to decode it), created in the
    Usertour app under Settings → API, sent as `Authorization: Bearer utp_...`.
  version: '2.0'
  contact: {}
servers:
  - url: https://api.usertour.io
security: []
tags: []
paths:
  /v2/projects/{projectId}/environments/{environmentId}/sessions:
    get:
      tags:
        - Sessions
      summary: List sessions
      description: Sessions in this environment. Filter by contentId / userId.
      operationId: ApiContentSessionsController_list
      parameters:
        - name: contentId
          required: false
          in: query
          description: Filter to a single content.
          schema:
            type: string
        - name: userId
          required: false
          in: query
          description: Filter to a single end-user.
          schema:
            type: string
        - name: completed
          required: false
          in: query
          description: >-
            Filter by GENUINE completion: true = the user reached the goal (flow
            finished / every checklist task done), false = did not. This is NOT
            "ended" — a dismissed session is not completed, and a completed
            checklist may still be open.
          schema:
            enum:
              - 'true'
              - 'false'
            type: string
        - name: limit
          required: false
          in: query
          description: Max items per page (1-100, default 20).
          schema:
            minimum: 1
            maximum: 100
            default: 20
            type: integer
        - name: cursor
          required: false
          in: query
          description: >-
            Opaque page cursor — the `cursor` query value found inside a prior
            response's `next`/`previous` URL. Normally you never build this
            yourself: just GET those URLs as-is.
          schema:
            type: string
        - name: orderBy
          required: false
          in: query
          description: Order by createdAt / -createdAt.
          schema:
            anyOf:
              - type: string
                enum:
                  - createdAt
                  - '-createdAt'
              - type: array
                items:
                  type: string
                  enum:
                    - createdAt
                    - '-createdAt'
        - name: expand
          required: false
          in: query
          description: 'Inline: answers, content, company, user, version.'
          schema:
            anyOf:
              - type: string
                enum:
                  - answers
                  - content
                  - company
                  - user
                  - version
              - type: array
                items:
                  type: string
                  enum:
                    - answers
                    - content
                    - company
                    - user
                    - version
        - name: createdAfter
          required: false
          in: query
          description: >-
            Only items created at or after this time — ISO date or datetime WITH
            timezone. A date-only value starts at that day's first instant
            (UTC).
          schema:
            type: string
        - name: createdBefore
          required: false
          in: query
          description: >-
            Only items created at or before this time — ISO date or datetime
            WITH timezone. A date-only value includes the ENTIRE day (up to its
            last instant, UTC).
          schema:
            type: string
        - name: environmentId
          required: true
          in: path
          description: Environment ID
          schema:
            type: string
        - name: projectId
          required: true
          in: path
          description: Project ID
          schema:
            type: string
      responses:
        '200':
          description: List of content sessions
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListContentSessionsResponseDto'
        '400':
          description: >-
            Invalid request — E1017 validation (may carry `issues`; an invalid
            orderBy/limit is also E1017), E1015 invalid scope, E0003 invalid
            against current domain state.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponseDto'
        '401':
          description: Missing or expired API key — E1010, E1020.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponseDto'
        '403':
          description: >-
            Refused — E1000 invalid key, E1011 project not in token scope, E1012
            insufficient scope, E1029 environment not in token scope, E1032
            environment creation needs a token without env-targeted capabilities
            (its allowlist cannot cover a not-yet-existing environment).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponseDto'
        '429':
          description: >-
            Rate limit exceeded — E1013. The limit follows the project's plan
            (100/500/1000/3000 requests per minute); unknown credentials share a
            per-IP bucket. Every response also carries X-RateLimit-Limit /
            -Remaining / -Reset for pacing; a 429 adds the standard Retry-After
            header (seconds to back off).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponseDto'
      security:
        - bearer: []
components:
  schemas:
    ListContentSessionsResponseDto:
      type: object
      properties:
        results:
          type: array
          items:
            type: object
            properties:
              id:
                type: string
              object:
                type: string
                enum:
                  - contentSession
              answers:
                type: array
                items:
                  type: object
                  properties:
                    id:
                      type: string
                    object:
                      type: string
                      enum:
                        - contentSessionAnswer
                    answerType:
                      type: string
                      enum:
                        - nps
                        - star-rating
                        - scale
                        - single-line-text
                        - multi-line-text
                        - multiple-choice
                      description: >-
                        Kind of question answered — the same vocabulary as
                        question `type` on the version.
                    answerValue:
                      anyOf:
                        - type: number
                        - type: string
                        - type: array
                          items:
                            type: string
                      description: >-
                        The answer's value in its real type, keyed off
                        answerType: nps / star-rating / scale → a number;
                        single-line-text / multi-line-text → a string;
                        multiple-choice → an array of the chosen option strings.
                        null only when the stored value is missing.
                      nullable: true
                    createdAt:
                      type: string
                      format: date-time
                    questionCvid:
                      type: string
                    questionName:
                      type: string
                  required:
                    - id
                    - object
                    - answerType
                    - answerValue
                    - createdAt
                    - questionCvid
                    - questionName
                description: >-
                  null = not expanded (pass expand: ["answers"]). Expanded: []
                  means the session has no question answers; entries appear as
                  the user answers.
                nullable: true
              completed:
                type: boolean
                description: >-
                  Whether the user GENUINELY reached the goal — a flow ran to
                  its end (or an explicit completion step) / every checklist
                  task was checked. Independent of whether the session is still
                  open: a completed checklist can still be showing, and a flow
                  can complete at a mid-flow completion step and keep running.
                  Only flows and checklists can be completed; banners /
                  launchers / resource centers are seen-then-dismissed and are
                  always false.
              completedAt:
                type: string
                description: When the goal was reached (null if never completed).
                nullable: true
              endedAt:
                type: string
                description: >-
                  When the session closed (null while it is still open/active).
                  A session can be completed but not yet ended (still open), or
                  ended without being completed (dismissed).
                nullable: true
              endReason:
                type: string
                description: >-
                  Why the session ended (null while open). Vocabulary — user
                  actions: `close_button_dismiss` (the X), `backdrop_dismiss`,
                  `dismiss_button`, `user_closed`; authored behavior:
                  `action_dismiss` (a dismiss action ran), `trigger_dismiss`,
                  `auto_dismissed`, `end_from_program`; displacement:
                  `replaced`, `user_started_other_content`,
                  `program_started_other_content`; health/diagnostic:
                  **`tooltip_target_missing`** (the tooltip anchor was never
                  found — the per-session selector-health signal),
                  `step_not_found`, `content_not_found`, `store_not_found`,
                  `unpublished_content`, `session_timeout`, `system_closed`,
                  `url_start_closed`, `launcher_deactivated`; admin:
                  `admin_ended`. Old sessions may carry legacy spellings (e.g.
                  bare `action`) — treat unknown values as "ended, reason
                  unclassified".
                nullable: true
              contentId:
                type: string
              content:
                type: object
                properties:
                  id:
                    type: string
                  object:
                    type: string
                    enum:
                      - content
                  name:
                    type: string
                  type:
                    type: string
                    enum:
                      - checklist
                      - flow
                      - launcher
                      - banner
                      - tracker
                      - resource-center
                      - announcement
                  editedVersionId:
                    type: string
                  updatedAt:
                    type: string
                    format: date-time
                  createdAt:
                    type: string
                    format: date-time
                required:
                  - id
                  - object
                  - name
                  - type
                  - editedVersionId
                  - updatedAt
                  - createdAt
                description: >-
                  null until expanded with expand: ["content"] (the content
                  always exists).
                nullable: true
              createdAt:
                type: string
                format: date-time
              companyId:
                type: string
                description: >-
                  null when the session has no company context (user not in a
                  company).
                nullable: true
              company:
                type: object
                properties:
                  id:
                    type: string
                  object:
                    type: string
                    enum:
                      - company
                  attributes:
                    type: object
                    additionalProperties: {}
                  createdAt:
                    type: string
                    format: date-time
                required:
                  - id
                  - object
                  - attributes
                  - createdAt
                description: >-
                  null = not expanded (pass expand: ["company"]) OR, after
                  expanding, the session genuinely has no company — check
                  `companyId` to tell the two apart.
                nullable: true
              lastActivityAt:
                type: string
                format: date-time
              progress:
                type: number
                description: >-
                  Flow progress percentage, 0-100 (integer). 100 does not imply
                  completed — see `completed`.
              userId:
                type: string
                nullable: true
              user:
                type: object
                properties:
                  id:
                    type: string
                  object:
                    type: string
                    enum:
                      - user
                  attributes:
                    type: object
                    additionalProperties: {}
                  createdAt:
                    type: string
                    format: date-time
                required:
                  - id
                  - object
                  - attributes
                  - createdAt
                description: >-
                  null = not expanded (pass expand: ["user"]) OR the user was
                  deleted — check `userId`.
                nullable: true
              versionId:
                type: string
              version:
                type: object
                properties:
                  id:
                    type: string
                  object:
                    type: string
                    enum:
                      - contentVersion
                  number:
                    type: number
                  updatedAt:
                    type: string
                    format: date-time
                  createdAt:
                    type: string
                    format: date-time
                required:
                  - id
                  - object
                  - number
                  - updatedAt
                  - createdAt
                description: 'null until expanded with expand: ["version"].'
                nullable: true
            required:
              - id
              - object
              - answers
              - completed
              - completedAt
              - endedAt
              - endReason
              - contentId
              - content
              - createdAt
              - companyId
              - company
              - lastActivityAt
              - progress
              - userId
              - user
              - versionId
              - version
        next:
          type: string
          description: >-
            Full URL of the next page — request it as-is (it already carries
            `cursor=` and your query parameters). null = no further pages.
          nullable: true
        previous:
          type: string
          description: >-
            Full URL of the previous page — request it as-is. null = already at
            the first page.
          nullable: true
      required:
        - results
        - next
        - previous
    ErrorResponseDto:
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              type: string
              description: >-
                Stable machine-readable code (e.g. E1017). Match on this, never
                on `message`.
            message:
              type: string
              description: Human-readable summary. Wording may change between releases.
            issues:
              description: >-
                Validation errors (E1017) may carry one entry per problem so
                every field can be fixed in a single round-trip. Absent on other
                errors.
              type: array
              items:
                type: object
                properties:
                  rule:
                    type: string
                    description: >-
                      Which validation layer rejected it: schema |
                      reactive_condition | action_not_allowed | step_shape |
                      reference_target | auto_start | media_url. New values may
                      be added; treat an unknown value as a generic validation
                      failure.
                  message:
                    type: string
                  path:
                    description: >-
                      Path into the request body (e.g.
                      `steps[0].triggers[0].when[1]`).
                    type: string
                required:
                  - rule
                  - message
            doc_url:
              type: string
              description: Base URL of the API documentation.
      required:
        - error
  securitySchemes:
    bearer:
      scheme: bearer
      bearerFormat: utp_... personal API token (opaque)
      type: http

````