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

# List Advertiser Reviews Route

> Return public reviews for one known canonical advertiser.

Authentication is the only gate here — ``advertiser_id`` is a global
catalog id, so every authenticated caller can read every advertiser
they have a visible relationship with (Brand Library tenancy, operator
ruling 2026-08-17). That is why the response model is the identity-free
one: the owned-brand envelope must never be declared on a route without
an ownership check.



## OpenAPI

````yaml /openapi.json get /api/v1/brand-reviews/advertisers/{advertiser_id}
openapi: 3.1.0
info:
  title: AITasker
  version: 0.1.0
servers: []
security: []
paths:
  /api/v1/brand-reviews/advertisers/{advertiser_id}:
    get:
      tags:
        - Brand Reviews
        - Brand Reviews
      summary: List Advertiser Reviews Route
      description: |-
        Return public reviews for one known canonical advertiser.

        Authentication is the only gate here — ``advertiser_id`` is a global
        catalog id, so every authenticated caller can read every advertiser
        they have a visible relationship with (Brand Library tenancy, operator
        ruling 2026-08-17). That is why the response model is the identity-free
        one: the owned-brand envelope must never be declared on a route without
        an ownership check.
      operationId: >-
        list_advertiser_reviews_route_api_v1_brand_reviews_advertisers__advertiser_id__get
      parameters:
        - name: advertiser_id
          in: path
          required: true
          schema:
            type: string
            format: uuid
            title: Advertiser Id
        - name: platform
          in: query
          required: false
          schema:
            anyOf:
              - type: string
                enum:
                  - trustpilot
                  - google
              - type: 'null'
            title: Platform
        - name: limit
          in: query
          required: false
          schema:
            type: integer
            maximum: 100
            minimum: 1
            default: 50
            title: Limit
        - name: offset
          in: query
          required: false
          schema:
            type: integer
            minimum: 0
            title: Offset
            default: 0
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BrandReviewCompetitorResponse'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
      security:
        - HTTPBearer: []
components:
  schemas:
    BrandReviewCompetitorResponse:
      properties:
        generated_at:
          type: string
          format: date-time
          title: Generated At
        subject:
          $ref: '#/components/schemas/BrandReviewSubject'
        platforms:
          items:
            $ref: '#/components/schemas/BrandReviewPlatformSummary'
          type: array
          title: Platforms
        total:
          type: integer
          minimum: 0
          title: Total
          default: 0
        limit:
          type: integer
          minimum: 1
          title: Limit
        offset:
          type: integer
          minimum: 0
          title: Offset
        has_more:
          type: boolean
          title: Has More
          default: false
        reviews:
          items:
            $ref: '#/components/schemas/BrandReviewCompetitorItem'
          type: array
          title: Reviews
      type: object
      required:
        - generated_at
        - subject
        - limit
        - offset
      title: BrandReviewCompetitorResponse
      description: The competitor review page — same envelope, identity-free rows.
    HTTPValidationError:
      properties:
        detail:
          items:
            $ref: '#/components/schemas/ValidationError'
          type: array
          title: Detail
      type: object
      title: HTTPValidationError
    BrandReviewSubject:
      properties:
        advertiser_id:
          anyOf:
            - type: string
              format: uuid
            - type: 'null'
          title: Advertiser Id
        brand_id:
          anyOf:
            - type: string
              format: uuid
            - type: 'null'
          title: Brand Id
        name:
          type: string
          title: Name
        domain:
          anyOf:
            - type: string
            - type: 'null'
          title: Domain
      type: object
      required:
        - name
      title: BrandReviewSubject
    BrandReviewPlatformSummary:
      properties:
        platform:
          type: string
          enum:
            - trustpilot
            - google
          title: Platform
        label:
          type: string
          title: Label
        review_count:
          type: integer
          minimum: 0
          title: Review Count
          default: 0
        average_rating:
          anyOf:
            - type: number
              maximum: 5
              minimum: 0
            - type: 'null'
          title: Average Rating
        profile_url:
          anyOf:
            - type: string
            - type: 'null'
          title: Profile Url
        last_collected_at:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: Last Collected At
        available:
          type: boolean
          title: Available
          default: false
      type: object
      required:
        - platform
        - label
      title: BrandReviewPlatformSummary
    BrandReviewCompetitorItem:
      properties:
        id:
          type: string
          format: uuid
          title: Id
        platform:
          type: string
          enum:
            - trustpilot
            - google
          title: Platform
        rating:
          type: number
          maximum: 5
          minimum: 1
          title: Rating
        title:
          anyOf:
            - type: string
            - type: 'null'
          title: Title
        body:
          anyOf:
            - type: string
            - type: 'null'
          title: Body
        reviewed_at:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: Reviewed At
        verified:
          anyOf:
            - type: boolean
            - type: 'null'
          title: Verified
        business_response:
          anyOf:
            - type: string
            - type: 'null'
          title: Business Response
        business_responded_at:
          anyOf:
            - type: string
              format: date-time
            - type: 'null'
          title: Business Responded At
        source_url:
          anyOf:
            - type: string
            - type: 'null'
          title: Source Url
        aspects:
          items:
            $ref: '#/components/schemas/BrandReviewAspectScore'
          type: array
          title: Aspects
      type: object
      required:
        - id
        - platform
        - rating
      title: BrandReviewCompetitorItem
      description: |-
        One review of an advertiser the requesting user does NOT own.

        Declares no fields of its own — being identity-free *is* the type. The
        2026-08-09 operator ruling took reviewer identity off every cross-brand
        wire; the on-platform-visibility argument that exempts the owned-brand
        list ("the business already sees these reviewers on its own profile")
        stops at the brand boundary and does not reach a competitor's customers.
    ValidationError:
      properties:
        loc:
          items:
            anyOf:
              - type: string
              - type: integer
          type: array
          title: Location
        msg:
          type: string
          title: Message
        type:
          type: string
          title: Error Type
        input:
          title: Input
        ctx:
          type: object
          title: Context
      type: object
      required:
        - loc
        - msg
        - type
      title: ValidationError
    BrandReviewAspectScore:
      properties:
        aspect:
          type: string
          maxLength: 100
          minLength: 1
          title: Aspect
        aspect_label:
          type: string
          maxLength: 100
          minLength: 1
          title: Aspect Label
        sentiment:
          type: string
          enum:
            - positive
            - negative
            - mixed
            - neutral
          title: Sentiment
      type: object
      required:
        - aspect
        - aspect_label
        - sentiment
      title: BrandReviewAspectScore
      description: >-
        One classifier-assigned aspect on a single review.


        The vocabulary slug, its display label (recovered from the ONE taxonomy

        map — never a second vocabulary), and the per-aspect sentiment verdict.

        That is the whole of it, and the omissions are the point:


        * **No ``evidence`` span.** ``brand_reviews.review_classification_json``
          stores a verbatim fragment of ``brand_reviews.body`` beside every
          aspect. This model hangs off :class:`BrandReviewCore`, which
          COMPETITOR-owned rows inherit, and competitor verbatim text does not
          reach that wire today. The licensed excerpt surface stays
          ``ReviewAspectEvidence`` (the group-insights evidence drawer), which
          bounds the span, requires a source URL and is separately gated.
        * **No ``sub_theme``.** Free-form model output rather than vocabulary,
        so
          the same reasoning applies — and it is a diagnosis layer no detail panel
          reads.
        * **No star score.** ``sentiment`` is what was MEASURED; stars are a
          rendering of it. Mapping here would put a presentation choice on the
          wire and make a second, divergent scale possible next to the one
          ``ReviewDetailPanel`` already applies to evidence rows.
  securitySchemes:
    HTTPBearer:
      type: http
      scheme: bearer

````