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

# Export mentions

> Export up to 50,000 mentions matching the given view and filters. Body shape matches `POST /api/v2/mentions` (v1-compatible) plus a `format` selector. Returns a downloadable file. Pass `format: "csv"` for a CSV or omit / `"json"` for a JSON file.



## OpenAPI

````yaml https://app.octolens.com/api/v2/openapi.json post /api/v2/mentions/export
openapi: 3.1.0
info:
  title: Octolens API
  version: 2.0.0
  description: >-
    The Octolens API lets you query mentions, manage keywords, and configure
    feeds programmatically. Every action available in the Octolens UI is
    available here.


    ### Authentication


    All v2 endpoints require an API key. Create one in **Settings > API** and
    pass it as `Authorization: Bearer <key>`. Keys are scoped to the
    organization they were minted in; you cannot access another org's data.


    API keys carry a scope — `read`, `write` (implies read), or `admin` (implies
    write). Each endpoint documents the scope it needs via the
    `x-required-scope` OpenAPI extension and the scope badge in the docs
    surface.


    ### Rate limiting


    The v2 API is rate-limited at **500 requests per hour per organization**,
    across all keys for that org. The limit resets at the top of each hour
    (sliding hourly window).


    Every 2xx response carries three headers so clients can pace themselves:

    * `X-RateLimit-Limit` — the hourly cap (500)

    * `X-RateLimit-Remaining` — requests left in the current window

    * `X-RateLimit-Reset` — Unix timestamp (seconds) when the window resets


    When the cap is hit, the endpoint returns **429 Rate Limited** with an
    additional `Retry-After` header (seconds until the next window). The
    response body is the standard `ErrorResponse` with `code: "RATE_LIMITED"`.


    ### Error handling


    All non-2xx responses share the same `ErrorResponse` envelope: `{ error: {
    code, message, status, details? } }`. The `code` field is a stable
    `ApiErrorCode` enum — branch on it programmatically instead of parsing
    `message`. See the `ApiErrorCode` schema for the full catalog grouped by
    category.


    `VALIDATION_ERROR` (400) responses include a `details` array with per-field
    Zod issues — inspect `details[i].path` to pinpoint which input was rejected.


    ### Building filter bodies


    Endpoints that accept `simpleFilters` / `advancedFilters` (e.g. `POST
    /api/v2/mentions`, `PATCH /api/v2/feeds/{id}`) take a structured object that
    can be tricky to hand-craft. If you just have a natural-language description
    of what you want ("negative posts about pricing on reddit in the last
    week"), call `POST /api/v2/ai/filter-wizard` with that prompt and it will
    return a ready-to-use filter object you can pass straight through.
servers:
  - url: https://app.octolens.com
    description: Production
  - url: http://localhost:3000
    description: Local development
security:
  - ApiKey: []
paths:
  /api/v2/mentions/export:
    post:
      tags:
        - Mentions
      summary: Export mentions
      description: >-
        Export up to 50,000 mentions matching the given view and filters. Body
        shape matches `POST /api/v2/mentions` (v1-compatible) plus a `format`
        selector. Returns a downloadable file. Pass `format: "csv"` for a CSV or
        omit / `"json"` for a JSON file.
      operationId: exportMentions
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ExportMentionsRequest'
      responses:
        '200':
          description: 200 response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ExportMentionsResponse'
        '400':
          description: Validation error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Missing or invalid authentication
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '403':
          description: Forbidden (insufficient plan or permissions)
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '429':
          description: Rate limit exceeded
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '500':
          description: Internal server error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
components:
  schemas:
    ExportMentionsRequest:
      description: >-
        Same filter shape as `ListMentionsRequest` plus a `format` selector.
        Exports up to 50,000 mentions per call and returns the result as a
        downloadable file.
      type: object
      properties:
        view:
          description: >-
            Feed/view ID to reuse as a base filter. If `filters` is also
            provided, the two are merged (view's saved filters + inline
            `filters` both apply).
          type: integer
          exclusiveMinimum: 0
          maximum: 9007199254740991
        filters:
          $ref: '#/components/schemas/ApiFilters'
          description: >-
            Filter object. Accepts the simple flat form (`{ source: ["twitter"],
            sentiment: ["positive"] }`) or the advanced group form with AND/OR
            operators. Use `POST /api/v2/ai/filter-wizard` to generate one from
            natural language.
        includeAll:
          description: >-
            When `true`, includes low-relevance mentions (internal
            `relevanceScore` = 2). Default `false` returns only high and medium
            relevance (scores 0 and 1).
          default: false
          type: boolean
        limit:
          description: Page size, 1-100.
          default: 20
          type: integer
          minimum: 1
          maximum: 100
        cursor:
          description: Opaque cursor from a previous response's `pagination.nextCursor`.
          type: string
        format:
          $ref: '#/components/schemas/ExportMentionsFormat'
          default: json
    ExportMentionsResponse:
      description: >-
        JSON shape returned when `format=json`. When `format=csv`, the response
        is `text/csv` with a matching `X-Total-Count` header.
      type: object
      properties:
        data:
          description: Exported mentions in the same shape as the list endpoint.
          type: array
          items:
            $ref: '#/components/schemas/Mention'
        total:
          description: Total matching mentions returned. Up to the 50,000 export cap.
          type: integer
          minimum: -9007199254740991
          maximum: 9007199254740991
      required:
        - data
        - total
      additionalProperties: false
    ErrorResponse:
      description: >-
        Standard error envelope returned for all non-2xx responses. The `code`
        field is stable — safe to branch on programmatically.
      type: object
      properties:
        error:
          type: object
          properties:
            code:
              $ref: '#/components/schemas/ApiErrorCode'
              description: >-
                Machine-readable error code. See `ApiErrorCode` for the full
                list.
              example: NOT_FOUND
            message:
              description: Human-readable error message.
              example: Resource not found
              type: string
            status:
              description: HTTP status code — always matches the response status.
              example: 404
              type: integer
              minimum: -9007199254740991
              maximum: 9007199254740991
            details:
              description: >-
                Present on `VALIDATION_ERROR` responses. Contains Zod issues
                describing each failing field (path, code, message).
              type: array
              items: {}
          required:
            - code
            - message
            - status
          additionalProperties: false
      required:
        - error
      additionalProperties: false
    ApiFilters:
      description: >-
        Mention filter object. Accepts the simple flat form (`{ source: [...]
        }`) or the advanced group form (`{ operator: "AND", groups: [...] }`).
        Matches the shape returned by `POST /api/v2/ai/filter-wizard`, so the
        wizard output plugs straight into this field.
      anyOf:
        - $ref: '#/components/schemas/SimpleApiFilters'
        - $ref: '#/components/schemas/AdvancedApiFilters'
    ExportMentionsFormat:
      description: >-
        Response format. `json` returns a downloadable JSON file (`{data,
        total}`); `csv` returns a CSV file with one row per mention across 15
        columns.
      example: csv
      type: string
      enum:
        - json
        - csv
    Mention:
      description: >-
        A single mention collected from a social platform. Canonical shape
        shared by `list_mentions` (MCP), `GET /api/v2/mentions` (REST), and the
        tRPC feed.
      type: object
      properties:
        id:
          description: >-
            Internal post id (numeric). Pass as `postId` to `PATCH
            /api/v2/mentions/{sourceId}`.
          type: integer
          minimum: -9007199254740991
          maximum: 9007199254740991
        sourceId:
          description: >-
            Stable composite key for the mention across the collection pipeline
            (e.g. `reddit_t3_1abc234`). Use this as the path parameter for
            `PATCH /api/v2/mentions/{sourceId}` and as the `sourceId` field on
            `POST /api/v2/feedback`.
          example: reddit_t3_1abc234
          type: string
        url:
          description: Canonical URL to the original post.
          example: https://reddit.com/r/example/comments/abc123/...
          type: string
        title:
          description: >-
            Post title. `null` for platforms that don't have titles (tweets,
            etc.).
          anyOf:
            - type: string
            - type: 'null'
        body:
          description: Post body / content. May be empty or `null` for posts with no text.
          anyOf:
            - type: string
            - type: 'null'
        source:
          $ref: '#/components/schemas/MentionSource'
        timestamp:
          description: >-
            When the mention was posted. Tinybird-style datetime string
            (`YYYY-MM-DD HH:mm:ss.SSS`, UTC, no `Z` suffix).
          example: '2026-05-06 13:35:37.000'
          type: string
        author:
          description: Handle/username of the mention's author. `null` if not captured.
          example: jane.doe
          anyOf:
            - type: string
            - type: 'null'
        authorName:
          description: Display name of the author, when distinct from the handle.
          anyOf:
            - type: string
            - type: 'null'
        authorAvatar:
          description: URL to the author's avatar image. `null` if not captured.
          anyOf:
            - type: string
            - type: 'null'
        authorUrl:
          description: URL to the author's profile page. `null` if not captured.
          anyOf:
            - type: string
            - type: 'null'
        authorFollowers:
          description: Author's follower count at collection time. `null` if not available.
          anyOf:
            - type: integer
              minimum: -9007199254740991
              maximum: 9007199254740991
            - type: 'null'
        relevance:
          $ref: '#/components/schemas/MentionRelevance'
          description: >-
            Relevance classification. Always one of `relevant` / `not_relevant`
            (unscored posts collapse to `not_relevant`).
          example: relevant
        relevanceComment:
          description: >-
            Free-text justification the AI produced for its relevance verdict,
            when available.
          anyOf:
            - type: string
            - type: 'null'
        sentiment:
          description: >-
            Sentiment classification. `null` until the AI has scored this
            mention.
          anyOf:
            - $ref: '#/components/schemas/MentionSentiment'
            - type: 'null'
        language:
          description: ISO 639-1 language code detected by the pipeline.
          example: en
          anyOf:
            - type: string
            - type: 'null'
        tags:
          description: AI-assigned topic tags applied to the mention.
          example:
            - competitor_mention
            - pricing
          type: array
          items:
            $ref: '#/components/schemas/MentionTag'
        keywords:
          description: Monitored keywords this mention matched, with id + display text.
          example:
            - id: 42
              keyword: social listening
          type: array
          items:
            $ref: '#/components/schemas/MentionKeyword'
        engaged:
          description: >-
            Whether a workspace member has marked this mention as engaged-with
            (replied, liked on-platform, etc.).
          type: boolean
        relevanceScore:
          description: >-
            Raw internal relevance score (0 = high, 1 = medium, 2 = low). The
            public `relevance` field is derived from this. Optional; not all
            consumers populate it.
          anyOf:
            - type: number
            - type: 'null'
        feedbackRelevant:
          description: >-
            User feedback on this mention's relevance: `1` for thumbs up, `-1`
            for thumbs down, `0` for no feedback. Optional.
          type: number
        imageUrl:
          description: URL to a preview image attached to the post, when present.
          anyOf:
            - type: string
            - type: 'null'
        keywordId:
          description: >-
            Denormalized first-matched keyword id. Convenience for callers that
            need a single keyword reference without scanning `keywords[]`.
          type: number
      required:
        - id
        - sourceId
        - url
        - title
        - body
        - source
        - timestamp
        - author
        - authorName
        - authorAvatar
        - authorUrl
        - authorFollowers
        - relevance
        - relevanceComment
        - sentiment
        - language
        - tags
        - keywords
        - engaged
      additionalProperties: false
    ApiErrorCode:
      description: >-
        Stable, machine-readable error code. Grouped as follows:


        **Auth / request shape** — `UNAUTHORIZED` (401), `FORBIDDEN` (403),
        `RATE_LIMITED` (429), `VALIDATION_ERROR` (400 — response carries a
        `details` array with Zod issues), `INTERNAL_ERROR` (500).


        **Not found (404)** — generic `NOT_FOUND` plus domain-specific variants:
        `FEED_NOT_FOUND`, `KEYWORD_NOT_FOUND`, `POST_NOT_FOUND`,
        `SUMMARY_NOT_FOUND`, `SUGGESTION_NOT_FOUND`, `COMPANY_NOT_FOUND`,
        `ORG_NOT_FOUND`, `SETTINGS_NOT_FOUND`.


        **Business-rule violations (400)** — `KEYWORD_LIMIT_EXCEEDED` (plan cap
        hit), `LAST_ADMIN` (refuses to remove the only admin), `ITEM_EXISTS`
        (duplicate), `INVALID_DOMAIN`, `INVALID_TIMEZONE`.
      type: string
      enum:
        - UNAUTHORIZED
        - FORBIDDEN
        - RATE_LIMITED
        - VALIDATION_ERROR
        - INTERNAL_ERROR
        - NOT_FOUND
        - FEED_NOT_FOUND
        - KEYWORD_NOT_FOUND
        - POST_NOT_FOUND
        - SUMMARY_NOT_FOUND
        - SUGGESTION_NOT_FOUND
        - COMPANY_NOT_FOUND
        - ORG_NOT_FOUND
        - SETTINGS_NOT_FOUND
        - KEYWORD_LIMIT_EXCEEDED
        - LAST_ADMIN
        - ITEM_EXISTS
        - INVALID_DOMAIN
        - INVALID_TIMEZONE
    SimpleApiFilters:
      description: >-
        Flat `field: values` map. Prefix a field with `!` to invert (NOT IN).
        Keys you can use: source / sentiment / keyword / language / tag /
        relevance (arrays); minXFollowers / maxXFollowers (numbers); startDate /
        endDate (ISO 8601 strings). Unknown keys are rejected with a 400.
      type: object
      properties:
        source:
          description: Filter by source platforms. Prefix with ! to exclude.
          minItems: 1
          type: array
          items:
            $ref: '#/components/schemas/Platform'
        sentiment:
          description: Filter by sentiment. Prefix with ! to exclude.
          minItems: 1
          type: array
          items:
            type: string
            enum:
              - positive
              - neutral
              - negative
        keyword:
          description: Filter by specific keyword IDs (numeric). Prefix with ! to exclude.
          minItems: 1
          type: array
          items:
            type: integer
            minimum: -9007199254740991
            maximum: 9007199254740991
        language:
          description: Filter by language codes (ISO 639-1). Prefix with ! to exclude.
          minItems: 1
          type: array
          items:
            type: string
            enum:
              - en
              - es
              - fr
              - de
              - pt
              - it
              - nl
              - ja
              - ko
              - zh
        tag:
          description: Filter by tags. Prefix with ! to exclude.
          minItems: 1
          type: array
          items:
            anyOf:
              - type: string
              - type: number
        relevance:
          description: Filter by relevance buckets. Prefix with ! to exclude.
          minItems: 1
          type: array
          items:
            anyOf:
              - type: string
              - type: number
        '!source':
          minItems: 1
          type: array
          items:
            $ref: '#/components/schemas/Platform'
        '!sentiment':
          minItems: 1
          type: array
          items:
            type: string
            enum:
              - positive
              - neutral
              - negative
        '!keyword':
          minItems: 1
          type: array
          items:
            type: integer
            minimum: -9007199254740991
            maximum: 9007199254740991
        '!language':
          minItems: 1
          type: array
          items:
            type: string
            enum:
              - en
              - es
              - fr
              - de
              - pt
              - it
              - nl
              - ja
              - ko
              - zh
        '!tag':
          minItems: 1
          type: array
          items:
            anyOf:
              - type: string
              - type: number
        '!relevance':
          minItems: 1
          type: array
          items:
            anyOf:
              - type: string
              - type: number
        minXFollowers:
          description: Minimum X/Twitter follower count for the author.
          type: integer
          minimum: 0
          maximum: 9007199254740991
        maxXFollowers:
          description: Maximum X/Twitter follower count for the author.
          type: integer
          minimum: 0
          maximum: 9007199254740991
        startDate:
          description: Only return posts from this date onwards (ISO 8601).
          type: string
        endDate:
          description: Only return posts up to this date (ISO 8601).
          type: string
      additionalProperties: false
    AdvancedApiFilters:
      description: >-
        Groups of conditions combined with AND/OR. Use this shape when a simple
        field-to-values map isn't enough (e.g. mixed OR logic across fields).
      type: object
      properties:
        operator:
          description: How groups combine at the top level.
          type: string
          enum:
            - AND
            - OR
        groups:
          minItems: 1
          type: array
          items:
            $ref: '#/components/schemas/ApiAdvancedGroup'
        minXFollowers:
          type: integer
          minimum: 0
          maximum: 9007199254740991
        maxXFollowers:
          type: integer
          minimum: 0
          maximum: 9007199254740991
        startDate:
          description: Inclusive ISO 8601 lower bound applied to all groups.
          type: string
        endDate:
          description: Inclusive ISO 8601 upper bound applied to all groups.
          type: string
      required:
        - operator
        - groups
      additionalProperties: false
    MentionSource:
      description: >-
        Platform the mention was collected from. Lowercase values like `reddit`,
        `twitter`, `linkedin`. Historical rows may be uppercase.
      example: reddit
      type: string
    MentionRelevance:
      description: >-
        AI-judged relevance classification. `relevant` = high or medium
        confidence (score 0 or 1). `not_relevant` = low confidence or not yet
        scored.
      example: relevant
      type: string
      enum:
        - relevant
        - not_relevant
    MentionSentiment:
      description: AI-judged sentiment of the mention.
      example: Neutral
      type: string
      enum:
        - Positive
        - Neutral
        - Negative
    MentionTag:
      description: >-
        AI-assigned topic tag. Applied by the relevance worker during scoring. A
        post can carry multiple tags.
      example: competitor_mention
      type: string
      enum:
        - buy_intent
        - competitor_mention
        - customer_testimonial
        - promotional_post
        - own_brand_mention
        - industry_insights
        - hiring
        - event
        - product_question
        - pricing
        - churn_intent
        - launch_announcement
        - bug_report
        - user_feedback
        - ai_generated
    MentionKeyword:
      description: Keyword the mention matched, with its display text.
      type: object
      properties:
        id:
          description: Tracked keyword id.
          type: integer
          minimum: -9007199254740991
          maximum: 9007199254740991
        keyword:
          description: Keyword text.
          type: string
        keywordTag:
          description: >-
            Keyword's classification tag (e.g. `own_brand`, `competitor`,
            `industry_term`). Internal; ignored by external consumers.
          type: string
      required:
        - id
        - keyword
      additionalProperties: false
    Platform:
      description: Platform a mention can originate from / a keyword can be monitored on.
      example: reddit
      type: string
      enum:
        - dev
        - github
        - hackernews
        - linkedin
        - producthunt
        - reddit
        - stackoverflow
        - twitter
        - youtube
        - tiktok
        - medium
        - reddit_comment
        - bluesky
        - newsletter
        - podcasts
        - news
        - firehose
    ApiAdvancedGroup:
      type: object
      properties:
        operator:
          description: How conditions inside this group combine.
          default: AND
          type: string
          enum:
            - AND
            - OR
        conditions:
          minItems: 1
          type: array
          items:
            $ref: '#/components/schemas/ApiAdvancedCondition'
      required:
        - conditions
    ApiAdvancedCondition:
      description: >-
        A single condition inside an advanced filter group. Object with exactly
        one key.
      anyOf:
        - $ref: '#/components/schemas/ApiArrayCondition'
        - $ref: '#/components/schemas/ApiNumericCondition'
        - $ref: '#/components/schemas/ApiDateCondition'
    ApiArrayCondition:
      type: object
      propertyNames:
        type: string
      additionalProperties:
        minItems: 1
        type: array
        items:
          anyOf:
            - type: string
            - type: number
    ApiNumericCondition:
      type: object
      propertyNames:
        type: string
      additionalProperties:
        type: integer
        minimum: 0
        maximum: 9007199254740991
    ApiDateCondition:
      type: object
      propertyNames:
        type: string
      additionalProperties:
        type: string
  securitySchemes:
    ApiKey:
      type: http
      scheme: bearer
      description: >-
        Clerk API key. Create one in Settings → API Keys. Pass as
        `Authorization: Bearer <key>`.

````