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

# Get brand sentiment

> Returns the sentiment of AI answers towards the project's primary brand over a fixed window of completed UTC days ending yesterday: overall and for each day, across every platform. Each answer that mentions the primary brand is scored from -1 to 1 for its stance towards that brand. Sentiment uses an LLM scorer, or Jev where enabled, with LLM fallback when Jev abstains (below 0.5 confidence), fails, or is unavailable. The score is about the primary brand only, never competitors, and answers that do not mention it are not scored. Each answer counts once, including answers whose brand has since stopped being primary. There is no per-platform breakdown. Days before 20 September 2026 are withheld: they were stored by an earlier version that scored a different subject and counted failed attempts. overall leaves withheld days out, window.dataFrom is the first day it counts and overall.coverage.daysWithheld how many days it left out; a withheld trend day has every figure null. averageScore and label are null when no answer was scored, never 0. coverage says how many answers were in the window and how many were scored.



## OpenAPI

````yaml /openapi.json get /projects/{projectId}/visibility/sentiment
openapi: 3.1.0
info:
  title: DevTune API
  version: 2.0.0
  description: >-
    API for programmatic access to your AI visibility data, webhook
    subscriptions, and automation workflows. Use this API to integrate DevTune
    data into CI/CD pipelines, BI tools, AI agents, and operational systems.
servers:
  - url: https://devtune.ai/api/v2
    description: Production
security:
  - bearerAuth: []
paths:
  /projects/{projectId}/visibility/sentiment:
    get:
      summary: Get brand sentiment
      description: >-
        Returns the sentiment of AI answers towards the project's primary brand
        over a fixed window of completed UTC days ending yesterday: overall and
        for each day, across every platform. Each answer that mentions the
        primary brand is scored from -1 to 1 for its stance towards that brand.
        Sentiment uses an LLM scorer, or Jev where enabled, with LLM fallback
        when Jev abstains (below 0.5 confidence), fails, or is unavailable. The
        score is about the primary brand only, never competitors, and answers
        that do not mention it are not scored. Each answer counts once,
        including answers whose brand has since stopped being primary. There is
        no per-platform breakdown. Days before 20 September 2026 are withheld:
        they were stored by an earlier version that scored a different subject
        and counted failed attempts. overall leaves withheld days out,
        window.dataFrom is the first day it counts and
        overall.coverage.daysWithheld how many days it left out; a withheld
        trend day has every figure null. averageScore and label are null when no
        answer was scored, never 0. coverage says how many answers were in the
        window and how many were scored.
      operationId: getBrandSentiment
      parameters:
        - name: projectId
          in: path
          required: true
          schema:
            type: string
            format: uuid
        - name: windowDays
          in: query
          schema:
            type: integer
            enum:
              - 30
              - 90
            default: 30
          description: >-
            Fixed rolling window in days. Supported values are 30 and 90.
            Defaults to 30.
      responses:
        '200':
          description: Brand sentiment
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      window:
                        type: object
                        properties:
                          windowDays:
                            type: integer
                            enum:
                              - 30
                              - 90
                          dateFrom:
                            type: string
                            format: date
                          dateTo:
                            type: string
                            format: date
                          dataFrom:
                            type: string
                            format: date
                            description: >-
                              First day overall counts: the later of dateFrom
                              and 2026-09-20.
                        required:
                          - windowDays
                          - dateFrom
                          - dateTo
                          - dataFrom
                      overall:
                        allOf:
                          - $ref: '#/components/schemas/BrandSentiment'
                          - type: object
                            properties:
                              coverage:
                                type: object
                                properties:
                                  daysWithheld:
                                    type: integer
                                    minimum: 0
                                    description: >-
                                      Days in the window before 2026-09-20, left
                                      out of overall.
                                required:
                                  - daysWithheld
                      trend:
                        type: array
                        description: One row per day in the window.
                        items:
                          allOf:
                            - $ref: '#/components/schemas/BrandSentiment'
                            - type: object
                              properties:
                                date:
                                  type: string
                                  format: date
                              required:
                                - date
                    required:
                      - window
                      - overall
                      - trend
                  meta:
                    $ref: '#/components/schemas/Meta'
                required:
                  - data
                  - meta
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '403':
          $ref: '#/components/responses/ForbiddenError'
        '429':
          $ref: '#/components/responses/RateLimitExceededError'
      security:
        - bearerAuth: []
        - oauthBearer: []
components:
  schemas:
    BrandSentiment:
      type: object
      properties:
        averageScore:
          type:
            - number
            - 'null'
          minimum: -1
          maximum: 1
          description: >-
            Mean score of the scored answers, from -1 to 1. Null when no answer
            was scored or the day is withheld, never 0.
        label:
          type:
            - string
            - 'null'
          enum:
            - positive
            - neutral
            - negative
            - null
          description: >-
            averageScore with the scorer cut: above 0.3 positive, below -0.3
            negative, otherwise neutral. Null when no answer was scored.
        positive:
          type:
            - integer
            - 'null'
          minimum: 0
        neutral:
          type:
            - integer
            - 'null'
          minimum: 0
        negative:
          type:
            - integer
            - 'null'
          minimum: 0
        coverage:
          type: object
          properties:
            responses:
              type:
                - integer
                - 'null'
              minimum: 0
              description: AI answers in the window or day. Null on a withheld day.
            scoredResponses:
              type:
                - integer
                - 'null'
              minimum: 0
              description: >-
                Answers with a sentiment score: positive plus neutral plus
                negative. Null on a withheld day.
          required:
            - responses
            - scoredResponses
      required:
        - averageScore
        - label
        - positive
        - neutral
        - negative
        - coverage
    Meta:
      type: object
      properties:
        timestamp:
          type: string
          format: date-time
        projectId:
          type: string
          format: uuid
    Error:
      type: object
      properties:
        error:
          type: string
        message:
          type: string
        reason:
          type: string
          description: >-
            Why the request was refused, for an error with more than one cause,
            such as a refused content-draft start.
        details:
          type: object
          additionalProperties: true
          description: >-
            Machine-readable facts about the refusal, such as shortfall_credits
            when an Agent Picks start is refused for insufficient_credits.
        status:
          type: integer
      required:
        - error
        - message
        - status
  responses:
    UnauthorizedError:
      description: Unauthorized
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    ForbiddenError:
      description: Forbidden
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    RateLimitExceededError:
      description: Rate limit exceeded
      headers:
        X-RateLimit-Limit:
          $ref: '#/components/headers/X-RateLimit-Limit'
        X-RateLimit-Remaining:
          $ref: '#/components/headers/X-RateLimit-Remaining'
        X-RateLimit-Reset:
          $ref: '#/components/headers/X-RateLimit-Reset'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  headers:
    X-RateLimit-Limit:
      description: Maximum requests per window
      schema:
        type: integer
    X-RateLimit-Remaining:
      description: Requests remaining in current window
      schema:
        type: integer
    X-RateLimit-Reset:
      description: Unix timestamp when the window resets
      schema:
        type: integer
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: >-
        API key with dtk_live_ prefix. Obtain it from API Keys in the account
        sidebar. New keys start with all supported scopes selected for the
        chosen project, and you can narrow them to specific read/write scopes as
        needed.
    oauthBearer:
      type: http
      scheme: bearer
      description: >-
        Project-granted OAuth access token from the authorization server
        advertised at /.well-known/oauth-protected-resource/api/v2. Uses the
        same browser consent and current project permissions as MCP. Only
        operations explicitly listing oauthBearer accept these tokens.

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.