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

# Get a brand's ad creatives

> Return creatives for a brand. `mode: "structured"` derives filters
from `userRequest`; `mode: "smart"` also runs a semantic search.

Limited to 120 requests per minute for this endpoint.
Costs 1,000 microdollars ($0.0010) per creative returned, charged against your plan's monthly credits. The count field is what you were charged for.
Both modes run a language model, so the call bills a minimum of one
row even when nothing matches. In that case `count` is 0 but you
are charged for one row.



## OpenAPI

````yaml https://app.spyglass.so/api/v1/openapi.json post /brands/{id}/media
openapi: 3.1.0
info:
  title: Spyglass API
  version: 1.0.0
  description: |-
    Query Spyglass ad intelligence over HTTP.

    ## Authentication
    Send your key as a bearer token: `Authorization: Bearer sg_live_...`.
    Create and revoke keys in Settings → API. A key is scoped to the
    team it was created for, and stops working if you leave that team.

    ## Billing
    Calls draw on the same monthly credits as the rest of Spyglass. Most
    endpoints charge per row returned. Bound what a call costs with
    `limit` on /brands/{id}/media, /insights and /landing-pages, and with
    `count` on /brands/search. POST /brands/index and GET
    /brands/{id}/index-status are free and are not blocked when the team
    is out of credits. Requests that fail
    validation, auth, or the credit check are never charged.

    Calls that run a language model — /brands/{id}/media in either mode,
    and /brands/search with `mode: "smart"` — are charged a minimum of one
    row even when nothing matches, because the model ran either way.

    ## Rate limits
    Three limits apply: 60 requests per minute per IP address, 120 per
    minute per API key, and a per-endpoint limit listed on each operation.
    Whichever is lowest applies. Exceeding any of them returns 429 with a
    Retry-After header.
servers:
  - url: https://app.spyglass.so/api/v1
security:
  - bearerAuth: []
tags:
  - name: Lookup
    description: Find a brand you already know about.
  - name: Indexing
    description: Add a brand we do not have yet, then poll until ready.
  - name: Ads
    description: Creatives, insights, and landing pages for a brand.
paths:
  /brands/{id}/media:
    post:
      tags:
        - Ads
      summary: Get a brand's ad creatives
      description: >-
        Return creatives for a brand. `mode: "structured"` derives filters

        from `userRequest`; `mode: "smart"` also runs a semantic search.


        Limited to 120 requests per minute for this endpoint.

        Costs 1,000 microdollars ($0.0010) per creative returned, charged
        against your plan's monthly credits. The count field is what you were
        charged for.

        Both modes run a language model, so the call bills a minimum of one

        row even when nothing matches. In that case `count` is 0 but you

        are charged for one row.
      operationId: getBrandMedia
      parameters:
        - name: id
          in: path
          required: true
          description: Brand id returned by POST /brands/search.
          schema:
            type: string
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                mode:
                  type: string
                  enum:
                    - structured
                    - smart
                userRequest:
                  type: string
                  minLength: 1
                  maxLength: 2000
                limit:
                  default: 100
                  type: integer
                  minimum: 1
                  maximum: 2000
              required:
                - mode
                - userRequest
            example:
              mode: smart
              userRequest: video ads about comfort
              limit: 20
      responses:
        '200':
          description: Matching creatives.
          content:
            application/json:
              schema:
                type: object
                properties:
                  count:
                    type: integer
                  media:
                    type: array
                    items:
                      type: object
                      properties:
                        id:
                          type: string
                        title:
                          anyOf:
                            - type: string
                            - type: 'null'
                        type:
                          anyOf:
                            - type: string
                              enum:
                                - DPA
                                - VIDEO
                                - CAROUSEL
                                - IMAGE
                                - DCO
                            - type: 'null'
                        mediaType:
                          anyOf:
                            - type: string
                              enum:
                                - VIDEO
                                - IMAGE
                            - type: 'null'
                        mediaUrl:
                          anyOf:
                            - type: string
                            - type: 'null'
                        thumbnailUrl:
                          anyOf:
                            - type: string
                            - type: 'null'
                        platforms:
                          type: array
                          items:
                            type: string
                        hook:
                          anyOf:
                            - type: string
                            - type: 'null'
                        startAt:
                          anyOf:
                            - type: string
                            - type: 'null'
                        endAt:
                          anyOf:
                            - type: string
                            - type: 'null'
                        daysRun:
                          anyOf:
                            - type: number
                            - type: 'null'
                        categories:
                          type: array
                          items:
                            type: string
                        carouselCount:
                          anyOf:
                            - type: number
                            - type: 'null'
                        viewCount:
                          anyOf:
                            - type: number
                            - type: 'null'
                        likeCount:
                          anyOf:
                            - type: number
                            - type: 'null'
                        commentCount:
                          anyOf:
                            - type: number
                            - type: 'null'
                        impressionPercentile:
                          anyOf:
                            - type: number
                            - type: 'null'
                        impressionsText:
                          anyOf:
                            - type: string
                            - type: 'null'
                      required:
                        - id
                        - title
                        - type
                        - mediaType
                        - mediaUrl
                        - thumbnailUrl
                        - platforms
                        - hook
                        - startAt
                        - endAt
                        - daysRun
                        - categories
                        - carouselCount
                        - viewCount
                        - likeCount
                        - commentCount
                        - impressionPercentile
                        - impressionsText
                required:
                  - count
                  - media
        '400':
          $ref: '#/components/responses/InvalidRequest'
        '401':
          $ref: '#/components/responses/InvalidApiKey'
        '402':
          $ref: '#/components/responses/OutOfCredits'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/BrandNotFound'
        '405':
          $ref: '#/components/responses/MethodNotAllowed'
        '413':
          $ref: '#/components/responses/PayloadTooLarge'
        '429':
          $ref: '#/components/responses/RateLimited'
        '500':
          $ref: '#/components/responses/InternalError'
components:
  responses:
    InvalidRequest:
      description: >-
        The request body or query string failed validation. `details` lists the
        offending fields.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    InvalidApiKey:
      description: The API key is missing, malformed, unknown, or revoked.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    OutOfCredits:
      description: The team's monthly credits are exhausted.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    Forbidden:
      description: The team's subscription is inactive, or your membership of it has ended.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    BrandNotFound:
      description: No brand matches that id.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    MethodNotAllowed:
      description: >-
        The HTTP method is not supported on this path. The Allow header lists
        what is. HEAD is refused on metered GET endpoints because it would be
        billed without returning data.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    PayloadTooLarge:
      description: The request body exceeds the 100 KB limit.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    RateLimited:
      description: >-
        Too many requests. Carries a Retry-After header. Limits are 60/minute
        per IP, 120/minute per key, plus the per-endpoint limit stated on the
        operation.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
    InternalError:
      description: Something went wrong on our side.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
  schemas:
    Error:
      type: object
      required:
        - error
      properties:
        error:
          type: object
          required:
            - code
            - message
          properties:
            code:
              type: string
              enum:
                - invalid_request
                - invalid_api_key
                - payload_too_large
                - out_of_credits
                - membership_ended
                - subscription_inactive
                - brand_not_found
                - not_found
                - method_not_allowed
                - rate_limited
                - internal_error
            message:
              type: string
            details:
              type: array
              items:
                type: object
                required:
                  - path
                  - message
                properties:
                  path:
                    type: string
                  message:
                    type: string
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: An API key from Settings → API, prefixed sg_live_.

````

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