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

# Topics available as a conversations filter, optionally scoped to a set of sources.

> One rule covers both cases: a topic is listed when it has at least one LeadTopic row in
scope. That deliberately carries no Status predicate. Only Active slugs ever enter the
classifier enum (TopicClassificationPrompt) and the collector refuses to write a fact row
for a non-Active topic, so Proposed topics provably have zero rows and fall out on their
own — while Merged and Archived topics stay filterable for as long as their history does.
Filtering on Status instead would offer topics that always return zero conversations.
            
Unpaginated by design: the taxonomy is capped at 30 Active topics per agency, so this is
a ListPersonas-shaped endpoint, not a GetSources-shaped one.



## OpenAPI

````yaml https://megastream25-api.closebot.com/swagger/v1/swagger.json post /analytics/topics/options
openapi: 3.0.4
info:
  title: CloseBot API
  version: v1
servers:
  - url: https://api.closebot.com
    description: CloseBot API Endpoint
security:
  - Key: []
tags:
  - name: Account
  - name: AccountNotification
  - name: Agency
  - name: Analytics
  - name: Billing
  - name: Bot
  - name: BotMetric
  - name: BotSourceVariable
  - name: BotTemplate
  - name: BotTesting
  - name: Dashboard
  - name: Hierarchy
  - name: Lead
  - name: Leaderboard
  - name: Library
  - name: LiveDemo
  - name: Notification
  - name: Persona
  - name: Report
  - name: SmartFAQ
  - name: Source
  - name: SourceChannel
  - name: Webhook
paths:
  /analytics/topics/options:
    post:
      tags:
        - Analytics
      summary: >-
        Topics available as a conversations filter, optionally scoped to a set
        of sources.
      description: >-
        One rule covers both cases: a topic is listed when it has at least one
        LeadTopic row in

        scope. That deliberately carries no Status predicate. Only Active slugs
        ever enter the

        classifier enum (TopicClassificationPrompt) and the collector refuses to
        write a fact row

        for a non-Active topic, so Proposed topics provably have zero rows and
        fall out on their

        own — while Merged and Archived topics stay filterable for as long as
        their history does.

        Filtering on Status instead would offer topics that always return zero
        conversations.
                    
        Unpaginated by design: the taxonomy is capped at 30 Active topics per
        agency, so this is

        a ListPersonas-shaped endpoint, not a GetSources-shaped one.
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TopicOptionsRequest'
          text/json:
            schema:
              $ref: '#/components/schemas/TopicOptionsRequest'
          application/*+json:
            schema:
              $ref: '#/components/schemas/TopicOptionsRequest'
      responses:
        '200':
          description: OK
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/TopicOptionsResponse'
            application/json:
              schema:
                $ref: '#/components/schemas/TopicOptionsResponse'
            text/json:
              schema:
                $ref: '#/components/schemas/TopicOptionsResponse'
        '403':
          description: Forbidden
          content:
            text/plain:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            application/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
            text/json:
              schema:
                $ref: '#/components/schemas/ProblemDetails'
components:
  schemas:
    TopicOptionsRequest:
      type: object
      properties:
        filters:
          $ref: '#/components/schemas/AnalyticsQueryFilters'
      additionalProperties: false
    TopicOptionsResponse:
      required:
        - topics
      type: object
      properties:
        topics:
          type: array
          items:
            $ref: '#/components/schemas/TopicOptionsTopic'
          nullable: true
      additionalProperties: false
    ProblemDetails:
      type: object
      properties:
        type:
          type: string
          nullable: true
        title:
          type: string
          nullable: true
        status:
          type: integer
          format: int32
          nullable: true
        detail:
          type: string
          nullable: true
        instance:
          type: string
          nullable: true
      additionalProperties: {}
    AnalyticsQueryFilters:
      type: object
      properties:
        sourceIds:
          type: array
          items:
            type: string
          description: Optional AgencySource IDs to include.
          nullable: true
        dimensions:
          type: array
          items:
            $ref: '#/components/schemas/DimensionFilter'
          description: >-
            Optional narrowing by the metric's declared dimensions. Each entry
            ANDs with the rest.

            A dimension the metric does not declare is a 400 rather than a
            silent no-op — a chart

            must never quietly show unfiltered totals under a filter the user
            set.
          nullable: true
      additionalProperties: false
    TopicOptionsTopic:
      required:
        - conversationCount
        - name
        - slug
        - topicId
      type: object
      properties:
        topicId:
          type: string
          nullable: true
        name:
          type: string
          nullable: true
        slug:
          type: string
          nullable: true
        conversationCount:
          type: integer
          description: >-
            Distinct conversations carrying this topic within the requested
            scope. Defines the

            ordering the caller relies on — a dropdown has no other ranking, and
            the topic

            someone wants is almost always the biggest one.
          format: int32
      additionalProperties: false
    DimensionFilter:
      required:
        - dimension
        - operator
      type: object
      properties:
        dimension:
          type: string
          description: >-
            One of
            Closebot.Api.Controllers.AnalyticsController.MetricDimensions. Must
            be declared by the metric.
          nullable: true
        operator:
          type: string
          description: >-
            One of
            Closebot.Api.Controllers.AnalyticsController.DimensionOperators.
          nullable: true
        values:
          type: array
          items:
            type: string
          description: Required for `is` and `isNot`; ignored otherwise.
          nullable: true
      additionalProperties: false
      description: One filter on one dimension.
  securitySchemes:
    Key:
      type: apiKey
      description: CloseBot API Key Authorization
      name: X-CB-KEY
      in: header

````