> ## 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 segments



## OpenAPI

````yaml /api-reference-v2/openapi.json get /v2/projects/{projectId}/segments
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}/segments:
    get:
      tags:
        - Segments
      summary: List segments
      operationId: ApiSegmentsController_list
      parameters:
        - name: projectId
          required: true
          in: path
          description: Project ID
          schema:
            type: string
        - name: bizType
          required: false
          in: query
          description: Filter to user or company segments.
          schema:
            type: string
            enum:
              - user
              - company
        - 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: name
          required: false
          in: query
          description: Filter by name (case-insensitive substring match).
          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'
      responses:
        '200':
          description: List of segments
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ListSegmentsResponseDto'
        '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:
    ListSegmentsResponseDto:
      type: object
      properties:
        results:
          type: array
          items:
            type: object
            properties:
              id:
                type: string
              object:
                type: string
                enum:
                  - segment
              name:
                type: string
              bizType:
                type: string
                enum:
                  - user
                  - company
              kind:
                type: string
                enum:
                  - all
                  - condition
                  - manual
                description: >-
                  `all` = the built-in everyone segment (one per bizType;
                  immutable, cannot be deleted); `condition` = membership
                  computed from `conditions`; `manual` = explicit member list.
              conditions:
                description: >-
                  Present on condition segments (decompiled to stable attribute
                  codes). Top-level siblings are ANDed; an OR lives inside a
                  match:"any" group — same rules as writes.
                type: array
                items:
                  $ref: '#/components/schemas/ListSegmentsResponseDto__schema0'
              createdAt:
                type: string
                format: date-time
              updatedAt:
                type: string
                format: date-time
            required:
              - id
              - object
              - name
              - bizType
              - kind
              - createdAt
              - updatedAt
        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
    ListSegmentsResponseDto__schema0:
      oneOf:
        - type: object
          properties:
            type:
              type: string
              enum:
                - group
            match:
              type: string
              enum:
                - all
                - any
            conditions:
              minItems: 1
              type: array
              items:
                $ref: '#/components/schemas/ListSegmentsResponseDto__schema0'
              description: >-
                The grouped conditions — at least one. An EMPTY group is not "no
                filter": it never matches, so next to an AND it makes the whole
                rule unmatchable, and writing one is rejected. A version saved
                with an empty group in the BUILDER still reads back with it
                (validate warns); writing that list back is refused until the
                group is filled or dropped.
          required:
            - type
            - match
            - conditions
        - type: object
          properties:
            type:
              type: string
              enum:
                - attribute
            scope:
              type: string
              enum:
                - user
                - company
                - companyMembership
              description: >-
                Which entity owns the attribute — `user` (the end user),
                `company`, or `companyMembership`. Same value as the attribute
                definition's `scope` (see the attribute definitions list);
                required to disambiguate a codeName that exists in more than one
                scope.
            attribute:
              type: string
            op:
              type: string
              enum:
                - is
                - not
                - contains
                - not_contains
                - starts_with
                - ends_with
                - any
                - empty
                - lt
                - lte
                - gt
                - gte
                - between
                - 'true'
                - 'false'
                - includes_any
                - includes_all
                - not_includes_any
                - not_includes_all
                - less_than
                - exactly
                - more_than
                - before
                - 'on'
                - after
              description: >-
                Operator — the allowed set depends on the attribute dataType.
                String: is | not | contains | not_contains | starts_with |
                ends_with | any | empty. Number: is | not | lt | lte | gt | gte
                | between | any | empty. Boolean: true | false | any | empty.
                List: includes_any | includes_all | not_includes_any |
                not_includes_all | any | empty. DateTime: less_than | exactly |
                more_than (relative — `value` is a number of days) | before | on
                | after (`value` is an absolute date) | any | empty. The
                relative ops are ONE-SIDED bounds around (now − N days):
                `less_than N` = the date is AFTER now−N — so it also matches
                every FUTURE date, and on a future-dated attribute (a trial end,
                a renewal date) it is NOT "within the last N days"; `more_than
                N` = the date is BEFORE now−N. **"Signed up in the last N days"
                therefore needs BOTH bounds** — `less_than N` AND `more_than 0`
                in one `all` group; `less_than N` alone silently includes anyone
                whose date is in the future (a mis-mapped trial-end column, a
                clock/timezone slip), and those are exactly the users a new-user
                audience must not contain (observed in testing). Negative N
                shifts the bound into the future: the rolling "within the NEXT 7
                days" window is `less_than` value "0" AND `more_than` value "-7"
                (two conditions, both required). The relative ops are
                DAY-granularity only — no unit field; for hour/minute windows
                use an `event` condition with a `within` (which has a `unit`).
            value:
              description: >-
                The comparison value (string / number-as-string / date). Omit
                for any/empty/true/false.
              type: string
            value2:
              description: >-
                Upper bound for the `between` operator (`value` is the lower
                bound).
              type: string
            values:
              description: Values for the List operators (includes_any / includes_all / …).
              type: array
              items:
                type: string
          required:
            - type
            - scope
            - attribute
            - op
        - type: object
          properties:
            type:
              type: string
              enum:
                - unsupported
            note:
              type: string
          required:
            - type
  securitySchemes:
    bearer:
      scheme: bearer
      bearerFormat: utp_... personal API token (opaque)
      type: http

````