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

# Preview the sources a topic extraction would hit

> Runs the exact same source selection as the extraction trigger — the top sources (by citation count) matching the standard analytics filters — but enqueues nothing. Returns the selected sources grouped by domain so the frontend can let the user assess the scope before triggering.



## OpenAPI

````yaml https://api.mentionlab.io/api/docs-json post /api/v1/source-topics/preview
openapi: 3.0.0
info:
  title: MentionLab Public API v0.3.4-rc
  description: ''
  version: 0.3.4-rc
  contact: {}
servers:
  - url: https://api.mentionlab.io
security: []
tags: []
paths:
  /api/v1/source-topics/preview:
    post:
      tags:
        - Source Topics
      summary: Preview the sources a topic extraction would hit
      description: >-
        Runs the exact same source selection as the extraction trigger — the top
        sources (by citation count) matching the standard analytics filters —
        but enqueues nothing. Returns the selected sources grouped by domain so
        the frontend can let the user assess the scope before triggering.
      operationId: SourceTopicsV1Controller_previewTopics_v1
      parameters:
        - name: x-project-id
          in: header
          description: Project ID to specify the project context
          required: true
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SourceTopicsExtractDto'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SourceTopicsPreviewResponse'
        '400':
          description: >-
            The request failed validation — the body, query or path parameters
            are malformed or out of range.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiErrorResponse'
        '401':
          description: The request is missing valid authentication credentials.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiErrorResponse'
        '403':
          description: >-
            The authenticated principal lacks the required permission, or access
            to the requested organisation/project.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ApiErrorResponse'
components:
  schemas:
    SourceTopicsExtractDto:
      type: object
      properties:
        startDate:
          type: string
          description: Start date (inclusive)
          example: '2025-01-01'
        endDate:
          type: string
          description: End date (exclusive)
          example: '2025-02-01'
        countries:
          description: Filter by country codes
          example:
            - BE
            - FR
          type: array
          items:
            type: string
        languages:
          description: Filter by language codes
          example:
            - en
            - fr
          type: array
          items:
            type: string
        models:
          description: Filter by AI models
          example:
            - gpt-4o
            - claude-3-5-sonnet
          type: array
          items:
            type: string
        queryIds:
          description: Filter by query IDs
          example:
            - 3fa85f64-5717-4562-b3fc-2c963f66afa6
          type: array
          items:
            type: string
        hasSources:
          type: string
          description: >-
            Filter by source presence: "sources" (only with sources),
            "no_sources" (only without), "all" (no filter). Legacy true/false
            values are still accepted.
          enum:
            - all
            - sources
            - no_sources
        hasShopping:
          type: string
          description: >-
            Filter by shopping presence: "shopping" (only with shopping),
            "no_shopping" (only without), "all" (no filter). Legacy true/false
            values are still accepted.
          enum:
            - all
            - shopping
            - no_shopping
        queryTagIds:
          description: Filter by query tag IDs (numeric — bigint column)
          example:
            - '42'
          type: array
          items:
            type: string
        execTagIds:
          description: Filter by execution tag IDs
          example:
            - 3fa85f64-5717-4562-b3fc-2c963f66afa6
          type: array
          items:
            type: string
        queryTagGroupIds:
          description: >-
            Filter by query tag group IDs — matches rows carrying any tag filed
            under a selected group. Combines with queryTagIds per queryTagMode.
          example:
            - 3fa85f64-5717-4562-b3fc-2c963f66afa6
          type: array
          items:
            type: string
        execTagGroupIds:
          description: >-
            Filter by execution tag group IDs — matches rows carrying any tag
            filed under a selected group. Combines with execTagIds per
            execTagMode.
          example:
            - 3fa85f64-5717-4562-b3fc-2c963f66afa6
          type: array
          items:
            type: string
        queryTypes:
          type: array
          description: >-
            Filter by query type. Include "untyped" to also match queries
            without a type. Results from since-deleted queries are excluded when
            this filter is set.
          items:
            type: string
            enum:
              - comparative
              - informative
              - perception
              - untyped
        queryTagMode:
          type: string
          description: >-
            Query tag matching mode: "or" matches ANY tag (default), "and"
            matches ALL tags.
          enum:
            - and
            - or
          default: or
        execTagMode:
          type: string
          description: >-
            Execution tag matching mode: "or" matches ANY tag (default), "and"
            matches ALL tags.
          enum:
            - and
            - or
          default: or
        timezone:
          type: string
          description: >-
            IANA timezone for date bucketing and filtering (e.g.
            "Europe/Brussels"). Defaults to UTC.
          example: Europe/Brussels
          default: UTC
        groupBy:
          type: string
          description: >-
            Row grouping level for entity results. "none" = one row per entity,
            "division" = one row per division (entities not in a division get
            their own row), "group" = one row per top-level group (divisions
            roll up into their group). Defaults to "none".
          enum:
            - none
            - division
            - group
        groupByEntityGroup:
          type: boolean
          description: >-
            Deprecated — use groupBy instead. true is equivalent to
            groupBy="group".
          deprecated: true
          example: false
        showAllEntities:
          type: boolean
          description: >-
            Include entities that have only ever been seen in a single AI
            response. These are mostly one-off extraction noise and are hidden
            by default.
          example: false
    SourceTopicsPreviewResponse:
      type: object
      properties:
        totalSources:
          type: number
          description: >-
            Number of source snapshots (distinct url + month) selected — the
            exact set the extraction endpoint would enqueue. Capped at `limit`.
          example: 100
        limit:
          type: number
          description: Maximum number of sources selected (top-N by citation count).
          example: 100
        coverage:
          description: >-
            Estimated analysis coverage of the selected snapshots: withMeta is
            guaranteed in the topic map, preMeta will be skipped, uncertain is
            resolved at run time. Buckets sum to totalSources.
          allOf:
            - $ref: '#/components/schemas/SourceTopicsPreviewCoverage'
        domains:
          description: >-
            Selected sources grouped by domain, ordered by sourceCount
            descending (then citationCount). Lets the user assess what the
            extraction will hit.
          type: array
          items:
            $ref: '#/components/schemas/SourceTopicsPreviewDomain'
        categorization:
          description: >-
            Source-categorisation coverage of the selected domains — check
            before extracting whether the sources have been categorised.
          allOf:
            - $ref: '#/components/schemas/SourceTopicsPreviewCategorization'
        relationships:
          description: >-
            Project-level relationship-overlay readiness. Content-gap presence
            (owned/competitor) is only meaningful once these are mapped.
          allOf:
            - $ref: '#/components/schemas/SourceTopicsPreviewRelationships'
      required:
        - totalSources
        - limit
        - coverage
        - domains
        - categorization
        - relationships
    ApiErrorResponse:
      type: object
      properties:
        statusCode:
          type: number
          description: HTTP status code of the error.
          example: 400
        message:
          type: string
          description: >-
            Human-readable description of the error. Validation failures return
            an array of per-field validation errors instead of a single string.
          example: Validation failed
        error:
          type: string
          description: Short name of the HTTP error.
          example: Bad Request
      required:
        - statusCode
    SourceTopicsPreviewCoverage:
      type: object
      properties:
        withMeta:
          type: number
          description: Snapshots with stored page metadata — guaranteed to be analysed.
          example: 51
        preMeta:
          type: number
          description: Snapshots older than metadata collection — these will be skipped.
          example: 9
        uncertain:
          type: number
          description: >-
            Snapshots whose metadata availability is only known at run time —
            they may be analysed or skipped.
          example: 6
      required:
        - withMeta
        - preMeta
        - uncertain
    SourceTopicsPreviewDomain:
      type: object
      properties:
        sourceDomainId:
          type: string
          description: Source domain UUID.
          example: d1f8c3a2-9b4e-4c7a-8f21-6e0a5b2c9d10
        domain:
          type: string
          description: Root domain name.
          example: reddit.com
        sourceCount:
          type: number
          description: >-
            Number of selected source snapshots (distinct url + month) on this
            domain that the extraction would process.
          example: 12
        citationCount:
          type: number
          description: >-
            Total citation count (distinct AI responses) across this domain’s
            selected sources — the metric the top-N ranking is based on.
          example: 248
        categorizationStatus:
          description: >-
            Source-categorisation lifecycle state of this domain: `done` =
            categorised, `pending`/`failed` = still in the categorisation
            pipeline, null = never queued. Use to spot sources missing a
            category before extracting.
          nullable: true
          example: done
          allOf:
            - $ref: '#/components/schemas/SourceDomainCategorizationStatus'
        isCategorized:
          type: boolean
          description: Convenience flag — true when categorizationStatus is `done`.
          example: true
      required:
        - sourceDomainId
        - domain
        - sourceCount
        - citationCount
        - categorizationStatus
        - isCategorized
    SourceTopicsPreviewCategorization:
      type: object
      properties:
        totalDomains:
          type: number
          description: Distinct source domains in the selected set.
          example: 18
        categorized:
          type: number
          description: Selected domains that are fully categorised (status `done`).
          example: 15
        uncategorized:
          type: number
          description: >-
            Selected domains not yet categorised (status is null, `pending` or
            `failed`).
          example: 3
        pending:
          type: boolean
          description: >-
            True when any selected domain is still mid-flight in the
            categorisation pipeline (status `pending` or `failed`) —
            categorisation may still complete on its own.
          example: true
        allCategorized:
          type: boolean
          description: >-
            True when every selected domain is categorised (uncategorized === 0)
            — safe to run the topic analysis with full category coverage.
          example: false
      required:
        - totalDomains
        - categorized
        - uncategorized
        - pending
        - allCategorized
    SourceTopicsPreviewRelationships:
      type: object
      properties:
        ownedDomains:
          type: number
          description: >-
            Number of source domains mapped as `owned` for this project
            (relationship overlay). Zero means content-gap cannot mark any topic
            as covered — every topic would read as a gap until the brand’s
            domains are mapped.
          example: 3
        competitorDomains:
          type: number
          description: >-
            Number of source domains mapped as `competitor` for this project.
            Zero means competitor presence can never be detected.
          example: 5
      required:
        - ownedDomains
        - competitorDomains
    SourceDomainCategorizationStatus:
      type: string
      enum:
        - pending
        - done
        - failed
      description: >-
        Source-categorisation lifecycle state of this domain: `done` =
        categorised, `pending`/`failed` = still in the categorisation pipeline,
        null = never queued. Use to spot sources missing a category before
        extracting.

````