components:
  schemas:
    APIError:
      additionalProperties: false
      properties:
        error:
          $ref: "#/components/schemas/ErrorBody"
      required:
        - error
      type: object
    Ad:
      additionalProperties: false
      properties:
        advertiser:
          $ref: "#/components/schemas/AdvertiserRef"
        countries:
          description: ISO 3166-1 alpha-2
          items:
            type: string
          type:
            - array
            - "null"
        creatives:
          items:
            $ref: "#/components/schemas/Creative"
          type:
            - array
            - "null"
        derived:
          $ref: "#/components/schemas/Derived"
        eu_data:
          $ref: "#/components/schemas/EUData"
        extra:
          additionalProperties: {}
          description: Platform-specific fields
          type: object
        first_seen_by_us:
          format: date-time
          type:
            - string
            - "null"
        first_shown:
          format: date-time
          type:
            - string
            - "null"
        formats:
          items:
            type: string
          type:
            - array
            - "null"
        id:
          description: "Stable ID: <platform>:<platform_ad_id>"
          type: string
        impressions_range:
          $ref: "#/components/schemas/Range"
        last_seen_by_us:
          format: date-time
          type:
            - string
            - "null"
        last_shown:
          format: date-time
          type:
            - string
            - "null"
        library_url:
          type: string
        placements:
          items:
            type: string
          type:
            - array
            - "null"
        platform:
          enum:
            - meta
            - google
            - tiktok
            - linkedin
            - pinterest
            - x
          type: string
        platform_ad_id:
          type: string
        political:
          description: Political or issue ad. Meta only; null where the platform doesn't label it
          type:
            - boolean
            - "null"
        raw_ref:
          description: Pointer to the archived raw upstream record
          type: string
        spend_range:
          $ref: "#/components/schemas/Range"
        status:
          enum:
            - active
            - inactive
            - unknown
          type: string
      required:
        - id
        - platform
        - platform_ad_id
        - advertiser
        - status
        - first_shown
        - last_shown
        - first_seen_by_us
        - last_seen_by_us
        - formats
        - creatives
        - placements
        - countries
        - eu_data
        - spend_range
        - impressions_range
        - political
        - derived
      type: object
    AdHistory:
      additionalProperties: false
      properties:
        ad_id:
          type: string
        events:
          items:
            $ref: "#/components/schemas/EventOut"
          type:
            - array
            - "null"
        status_periods:
          items:
            $ref: "#/components/schemas/Period"
          type:
            - array
            - "null"
        versions:
          items:
            $ref: "#/components/schemas/Version"
          type:
            - array
            - "null"
      required:
        - ad_id
        - versions
        - status_periods
        - events
      type: object
    AdListOutputBody:
      additionalProperties: false
      properties:
        data:
          items:
            $ref: "#/components/schemas/Ad"
          type:
            - array
            - "null"
        meta:
          $ref: "#/components/schemas/ListMeta"
        next_cursor:
          description: Pass as cursor to get the next page; null = last page
          type:
            - string
            - "null"
      required:
        - data
        - next_cursor
        - meta
      type: object
    AdMeta:
      additionalProperties: false
      properties:
        source:
          description: live = fetched from the platform now; history = platform no longer serves it
          enum:
            - live
            - cache
            - history
          type: string
      required:
        - source
      type: object
    AdOutputBody:
      additionalProperties: false
      properties:
        data:
          $ref: "#/components/schemas/Ad"
        meta:
          $ref: "#/components/schemas/AdMeta"
      required:
        - data
        - meta
      type: object
    AddAdvertisersInputBody:
      additionalProperties: false
      properties:
        advertisers:
          items:
            type: string
          minItems: 1
          type:
            - array
            - "null"
      required:
        - advertisers
      type: object
    Advertiser:
      additionalProperties: false
      properties:
        active_ads:
          description: As reported by the platform if available, else counted by us
          format: int64
          type:
            - integer
            - "null"
        avatar_url:
          type:
            - string
            - "null"
        country:
          type:
            - string
            - "null"
        domain:
          type:
            - string
            - "null"
        extra:
          additionalProperties: {}
          type: object
        first_seen_by_us:
          format: date-time
          type:
            - string
            - "null"
        id:
          type: string
        last_seen_by_us:
          format: date-time
          type:
            - string
            - "null"
        name:
          type: string
        platform:
          type: string
        platform_advertiser_id:
          type: string
        profile_url:
          type:
            - string
            - "null"
        total_ads_known:
          description: Ads in our history
          format: int64
          type: integer
        verified:
          type:
            - boolean
            - "null"
      required:
        - id
        - platform
        - platform_advertiser_id
        - name
        - domain
        - verified
        - country
        - profile_url
        - avatar_url
        - active_ads
        - total_ads_known
        - first_seen_by_us
        - last_seen_by_us
      type: object
    AdvertiserOutputBody:
      additionalProperties: false
      properties:
        data:
          $ref: "#/components/schemas/Advertiser"
      required:
        - data
      type: object
    AdvertiserRef:
      additionalProperties: false
      properties:
        domain:
          type:
            - string
            - "null"
        id:
          description: <platform>:<platform_advertiser_id>
          type: string
        name:
          type: string
        platform_advertiser_id:
          type: string
        verified:
          type:
            - boolean
            - "null"
      required:
        - id
        - name
        - platform_advertiser_id
        - domain
        - verified
      type: object
    AdvertiserStats:
      additionalProperties: false
      properties:
        advertiser_id:
          type: string
        by_country:
          additionalProperties:
            format: int64
            type: integer
          description: Top 25 countries
          type: object
        by_format:
          additionalProperties:
            format: int64
            type: integer
          type: object
        by_language:
          additionalProperties:
            format: int64
            type: integer
          type: object
        by_status:
          additionalProperties:
            format: int64
            type: integer
          type: object
        days_running:
          $ref: "#/components/schemas/DaysRunningStats"
        first_ad_at:
          format: date-time
          type:
            - string
            - "null"
        latest_ad_at:
          format: date-time
          type:
            - string
            - "null"
        longest_running_ads:
          description: Top 5 by days_running — the advertiser's likely winners
          items:
            $ref: "#/components/schemas/Ad"
          type:
            - array
            - "null"
        new_ads_weekly:
          description: Ads first shown per ISO week, last 12 weeks
          items:
            $ref: "#/components/schemas/WeekCount"
          type:
            - array
            - "null"
        political_ads:
          description: Ads the platform labels political or issue ads (Meta only)
          format: int64
          type: integer
        total_ads:
          description: Ads in our history (incl. ads gone from the platform)
          format: int64
          type: integer
      required:
        - advertiser_id
        - total_ads
        - political_ads
        - by_status
        - by_format
        - by_country
        - by_language
        - days_running
        - new_ads_weekly
        - first_ad_at
        - latest_ad_at
        - longest_running_ads
      type: object
    BatchCreatedBody:
      additionalProperties: false
      properties:
        data:
          $ref: "#/components/schemas/BatchJob"
      required:
        - data
      type: object
    BatchInputBody:
      additionalProperties: false
      properties:
        items:
          description: "Advertiser ids (<platform>:<id>), domains, or ad ids. Up to your plan's batch size: free 5, starter 25, growth and above 100"
          items:
            type: string
          maxItems: 100
          minItems: 1
          type:
            - array
            - "null"
        options:
          $ref: "#/components/schemas/OptionsStruct"
        type:
          description: What the items are
          enum:
            - advertisers
            - domains
            - ads
          type: string
        webhook_url:
          description: POSTed (signed) when the job completes
          format: uri
          type: string
      required:
        - type
        - items
      type: object
    BatchItemOut:
      additionalProperties: false
      properties:
        ads:
          items:
            $ref: "#/components/schemas/Ad"
          type:
            - array
            - "null"
        advertisers:
          items:
            $ref: "#/components/schemas/Advertiser"
          type:
            - array
            - "null"
        error:
          type:
            - string
            - "null"
        input:
          type: string
        status:
          enum:
            - queued
            - running
            - done
            - failed
          type: string
      required:
        - input
        - status
        - error
        - ads
        - advertisers
      type: object
    BatchJob:
      additionalProperties: false
      properties:
        created_at:
          format: date-time
          type: string
        credits_billed:
          format: int64
          type: integer
        done:
          format: int64
          type: integer
        failed:
          format: int64
          type: integer
        finished_at:
          format: date-time
          type:
            - string
            - "null"
        job_id:
          type: string
        kind:
          type: string
        params: {}
        started_at:
          format: date-time
          type:
            - string
            - "null"
        status:
          enum:
            - queued
            - running
            - done
            - failed
          type: string
        total:
          format: int64
          type: integer
        webhook_url:
          type:
            - string
            - "null"
      required:
        - job_id
        - status
        - kind
        - params
        - webhook_url
        - total
        - done
        - failed
        - credits_billed
        - created_at
        - started_at
        - finished_at
      type: object
    BatchOutputBody:
      additionalProperties: false
      properties:
        data:
          $ref: "#/components/schemas/BatchJob"
        items:
          items:
            $ref: "#/components/schemas/BatchItemOut"
          type:
            - array
            - "null"
        next_cursor:
          type:
            - string
            - "null"
      required:
        - data
        - items
        - next_cursor
      type: object
    Capabilities:
      additionalProperties: false
      properties:
        EUOnly:
          type: boolean
        FilterCountry:
          type: boolean
        FilterDate:
          type: boolean
        FilterFormat:
          type: boolean
        FilterStatus:
          type: boolean
        GetAd:
          type: boolean
        Regions:
          items:
            type: string
          type:
            - array
            - "null"
        SearchAdvertiser:
          type: boolean
        SearchAdvertiserID:
          type: boolean
        SearchDomain:
          type: boolean
        SearchKeyword:
          type: boolean
        beta:
          type: boolean
      required:
        - SearchKeyword
        - SearchAdvertiser
        - SearchAdvertiserID
        - SearchDomain
        - GetAd
        - FilterCountry
        - FilterDate
        - FilterFormat
        - FilterStatus
        - Regions
        - EUOnly
      type: object
    CheckOutputBody:
      additionalProperties: false
      properties:
        data:
          $ref: "#/components/schemas/DomainCheck"
      required:
        - data
      type: object
    Company:
      additionalProperties: false
      properties:
        accounts:
          description: The company's own accounts (role brand or unknown)
          items:
            $ref: "#/components/schemas/ResolvedAdvertiser"
          type:
            - array
            - "null"
        candidates:
          description: Possible accounts below min_score; report wrong ones via POST /v1/advertisers/resolve/reports
          items:
            $ref: "#/components/schemas/ResolvedAdvertiser"
          type:
            - array
            - "null"
        domain:
          type: string
        errors:
          items:
            $ref: "#/components/schemas/PlatformFailure"
          type:
            - array
            - "null"
        family:
          $ref: "#/components/schemas/CompanyFamily"
          description: The parent company and its other brands, when known (reviewed by us); resolve a brand's domain for its accounts
        name:
          description: Name of the most confident account named like the brand (else the most confident one)
          type: string
        platforms:
          items:
            $ref: "#/components/schemas/CompanyPlatform"
          type:
            - array
            - "null"
        related:
          description: Agencies, resellers and partners running ads for the domain (role agency, reseller, partner)
          items:
            $ref: "#/components/schemas/ResolvedAdvertiser"
          type:
            - array
            - "null"
        stats:
          $ref: "#/components/schemas/AdvertiserStats"
          description: Combined history of the accounts (plus related with include_related; advertiser_id is the domain)
      required:
        - domain
        - name
        - accounts
        - related
        - candidates
        - platforms
        - stats
      type: object
    CompanyFamily:
      additionalProperties: false
      properties:
        brands:
          items:
            $ref: "#/components/schemas/FamilyBrand"
          type:
            - array
            - "null"
        parent:
          type: string
        parent_domain:
          type:
            - string
            - "null"
      required:
        - parent
        - parent_domain
        - brands
      type: object
    CompanyOutputBody:
      additionalProperties: false
      properties:
        data:
          $ref: "#/components/schemas/Company"
      required:
        - data
      type: object
    CompanyPlatform:
      additionalProperties: false
      properties:
        accounts:
          format: int64
          type: integer
        active_ads:
          format: int64
          type: integer
        platform:
          type: string
        total_ads_known:
          format: int64
          type: integer
      required:
        - platform
        - accounts
        - total_ads_known
        - active_ads
      type: object
    Creative:
      additionalProperties: false
      properties:
        cta:
          type:
            - string
            - "null"
        headline:
          type:
            - string
            - "null"
        landing_url:
          type:
            - string
            - "null"
        media:
          items:
            $ref: "#/components/schemas/Media"
          type:
            - array
            - "null"
        text:
          type:
            - string
            - "null"
        type:
          type: string
      required:
        - type
        - text
        - headline
        - cta
        - landing_url
        - media
      type: object
    DataStruct:
      additionalProperties: false
      properties:
        secret:
          examples:
            - whsec_3f0c…
          type: string
        version:
          format: int64
          type: integer
      required:
        - secret
        - version
      type: object
    DaysRunningStats:
      additionalProperties: false
      properties:
        known:
          description: Ads with a known start date
          format: int64
          type: integer
        long_running:
          description: Ads running longer than the long-running threshold
          format: int64
          type: integer
        max:
          format: int64
          type:
            - integer
            - "null"
        median:
          format: double
          type:
            - number
            - "null"
        p90:
          format: double
          type:
            - number
            - "null"
      required:
        - median
        - p90
        - max
        - long_running
        - known
      type: object
    DeliveriesOutputBody:
      additionalProperties: false
      properties:
        data:
          items:
            $ref: "#/components/schemas/DeliveryInfo"
          type:
            - array
            - "null"
        next_cursor:
          type:
            - string
            - "null"
      required:
        - data
        - next_cursor
      type: object
    DeliveryInfo:
      additionalProperties: false
      properties:
        attempts:
          format: int64
          type: integer
        created_at:
          format: date-time
          type: string
        delivered_at:
          format: date-time
          type:
            - string
            - "null"
        event:
          type: string
        id:
          format: int64
          type: integer
        last_error:
          type:
            - string
            - "null"
        next_attempt:
          format: date-time
          type: string
        payload: {}
        response_status:
          format: int64
          type:
            - integer
            - "null"
        status:
          enum:
            - pending
            - delivered
            - failed
          type: string
        url:
          type: string
      required:
        - id
        - url
        - event
        - status
        - attempts
        - response_status
        - last_error
        - created_at
        - delivered_at
      type: object
    DeliveryOutputBody:
      additionalProperties: false
      properties:
        data:
          $ref: "#/components/schemas/DeliveryInfo"
      required:
        - data
      type: object
    Derived:
      additionalProperties: false
      properties:
        days_running:
          format: int64
          type:
            - integer
            - "null"
        is_long_running:
          description: days_running > 30
          type:
            - boolean
            - "null"
        language:
          description: ISO 639-1 of the primary ad text
          type:
            - string
            - "null"
        variant_count:
          description: Ads sharing this ad's primary text for the same advertiser
          format: int64
          type:
            - integer
            - "null"
      required:
        - days_running
        - is_long_running
        - language
        - variant_count
      type: object
    DomainCheck:
      additionalProperties: false
      properties:
        advertising:
          description: true if at least one platform shows a current ad; null if no platform could be checked
          type:
            - boolean
            - "null"
        checked_at:
          format: date-time
          type: string
        domain:
          type: string
        platforms:
          items:
            $ref: "#/components/schemas/PlatformCheck"
          type:
            - array
            - "null"
      required:
        - domain
        - advertising
        - platforms
        - checked_at
      type: object
    DomainSuggestion:
      additionalProperties: false
      properties:
        ads_known:
          format: int64
          type: integer
        advertisers:
          format: int64
          type: integer
        domain:
          type: string
        name:
          description: Most common advertiser name for the domain
          type: string
        platforms:
          items:
            type: string
          type:
            - array
            - "null"
      required:
        - domain
        - name
        - platforms
        - advertisers
        - ads_known
      type: object
    EUData:
      additionalProperties: false
      properties:
        beneficiary:
          type:
            - string
            - "null"
        payer:
          type:
            - string
            - "null"
        reach_by_country:
          additionalProperties:
            format: int64
            type: integer
          type: object
        reach_by_country_range:
          additionalProperties:
            $ref: "#/components/schemas/Range"
          type: object
        reach_range:
          $ref: "#/components/schemas/Range"
        reach_total:
          format: int64
          type:
            - integer
            - "null"
        targeting:
          $ref: "#/components/schemas/Targeting"
      required:
        - reach_total
        - reach_by_country
        - targeting
        - payer
        - beneficiary
      type: object
    ErrorBody:
      additionalProperties: false
      properties:
        billed:
          description: Errors are never billed
          type: boolean
        code:
          description: Machine-readable code
          examples:
            - not_found
          type: string
        details:
          items:
            type: string
          type:
            - array
            - "null"
        extra:
          additionalProperties: {}
          type: object
        message:
          type: string
        platform:
          type: string
        request_id:
          type: string
      required:
        - code
        - message
        - billed
      type: object
    EventListOutputBody:
      additionalProperties: false
      properties:
        data:
          items:
            $ref: "#/components/schemas/EventOut"
          type:
            - array
            - "null"
        meta:
          $ref: "#/components/schemas/MetaStruct"
        next_cursor:
          type:
            - string
            - "null"
      required:
        - data
        - next_cursor
        - meta
      type: object
    EventOut:
      additionalProperties: false
      properties:
        ad:
          $ref: "#/components/schemas/Ad"
        ad_id:
          type: string
        at:
          format: date-time
          type: string
        type:
          enum:
            - started
            - stopped
            - changed
            - discovered
          type: string
      required:
        - type
        - at
      type: object
    FamilyBrand:
      additionalProperties: false
      properties:
        domain:
          type: string
        name:
          type: string
      required:
        - name
        - domain
      type: object
    HistoryOutputBody:
      additionalProperties: false
      properties:
        data:
          $ref: "#/components/schemas/AdHistory"
      required:
        - data
      type: object
    ListMeta:
      additionalProperties: false
      properties:
        cached:
          type: boolean
        count:
          format: int64
          type: integer
        errors:
          description: Platforms that failed (not billed)
          items:
            $ref: "#/components/schemas/PlatformFailure"
          type:
            - array
            - "null"
        platforms:
          items:
            type: string
          type:
            - array
            - "null"
        source:
          enum:
            - live
            - history
          type: string
      required:
        - count
        - cached
        - source
      type: object
    Media:
      additionalProperties: false
      properties:
        duration:
          format: double
          type:
            - number
            - "null"
        height:
          format: int64
          type:
            - integer
            - "null"
        kind:
          enum:
            - image
            - video
          type: string
        original_url:
          type: string
        preview_url:
          type: string
        sha256:
          type:
            - string
            - "null"
        url:
          type: string
        width:
          format: int64
          type:
            - integer
            - "null"
      required:
        - kind
        - url
        - sha256
        - width
        - height
        - duration
      type: object
    MetaStruct:
      additionalProperties: false
      properties:
        count:
          format: int64
          type: integer
        summary:
          additionalProperties:
            format: int64
            type: integer
          type: object
      required:
        - count
        - summary
      type: object
    OptionsStruct:
      additionalProperties: false
      properties:
        country:
          type: string
        include_ads:
          description: "domains: also fetch the first page of ads of each matched advertiser"
          type: boolean
        max_pages:
          description: "advertisers: pages per advertiser (default 3)"
          format: int64
          maximum: 20
          minimum: 0
          type: integer
        min_score:
          description: "domains: keep only advertisers with at least this resolve score"
          format: double
          maximum: 1
          minimum: 0
          type: number
        platforms:
          description: "domains: restrict resolution"
          items:
            type: string
          type:
            - array
            - "null"
        status:
          enum:
            - active
            - inactive
            - ""
          type: string
      type: object
    Period:
      additionalProperties: false
      properties:
        active_from:
          format: date-time
          type: string
        active_to:
          format: date-time
          type:
            - string
            - "null"
      required:
        - active_from
        - active_to
      type: object
    Plan:
      additionalProperties: false
      properties:
        history_access:
          type: boolean
        history_days:
          format: int64
          type: integer
        max_batch_items:
          format: int64
          type: integer
        max_watchlist_advertisers:
          format: int64
          type: integer
        min_interval_hours:
          format: int64
          type: integer
        monthly_credits:
          format: int64
          type: integer
        name:
          type: string
        requests_per_minute:
          format: int64
          type: integer
      required:
        - name
        - requests_per_minute
        - monthly_credits
        - max_batch_items
        - max_watchlist_advertisers
        - history_access
        - history_days
        - min_interval_hours
      type: object
    PlatformCheck:
      additionalProperties: false
      properties:
        active_ads:
          description: Platform-reported count when available, else counted in the sample
          format: int64
          type:
            - integer
            - "null"
        advertiser:
          type: string
        advertiser_id:
          type: string
        advertising:
          type:
            - boolean
            - "null"
        error:
          type: string
        latest_ad_at:
          format: date-time
          type:
            - string
            - "null"
        platform:
          type: string
        sample_ad_ids:
          items:
            type: string
          type:
            - array
            - "null"
        score:
          format: double
          type: number
      required:
        - platform
        - advertising
        - active_ads
        - latest_ad_at
        - sample_ad_ids
      type: object
    PlatformFailure:
      additionalProperties: false
      properties:
        code:
          type: string
        message:
          type: string
        platform:
          type: string
      required:
        - platform
        - code
        - message
      type: object
    PlatformInfo:
      additionalProperties: false
      properties:
        capabilities:
          $ref: "#/components/schemas/Capabilities"
        enabled:
          type: boolean
        platform:
          type: string
      required:
        - platform
        - enabled
        - capabilities
      type: object
    PlatformStatus:
      additionalProperties: false
      properties:
        circuit_breaker:
          type: string
        enabled:
          type: boolean
        last_24h:
          $ref: "#/components/schemas/Window"
        last_hour:
          $ref: "#/components/schemas/Window"
        last_smoke_test:
          $ref: "#/components/schemas/SmokeResult"
        platform:
          type: string
        proxy_tier:
          type: string
        state:
          enum:
            - operational
            - degraded
            - down
            - disabled
          type: string
      required:
        - platform
        - enabled
        - state
        - circuit_breaker
        - last_hour
        - last_24h
        - last_smoke_test
      type: object
    PlatformsOutputBody:
      additionalProperties: false
      properties:
        data:
          items:
            $ref: "#/components/schemas/PlatformInfo"
          type:
            - array
            - "null"
      required:
        - data
      type: object
    QueuedOutputBody:
      additionalProperties: false
      properties:
        delivery_id:
          format: int64
          type: integer
        status:
          type: string
      required:
        - delivery_id
        - status
      type: object
    Range:
      additionalProperties: false
      properties:
        currency:
          type: string
        lower:
          format: int64
          type:
            - integer
            - "null"
        upper:
          format: int64
          type:
            - integer
            - "null"
      required:
        - lower
        - upper
      type: object
    ReportInputBody:
      additionalProperties: false
      properties:
        advertiser_id:
          description: <platform>:<id>. Required for wrong_match
          examples:
            - google:AR01700036858500612097
          maxLength: 200
          type: string
        domain:
          examples:
            - audi.de
          maxLength: 253
          minLength: 3
          type: string
        kind:
          enum:
            - wrong_match
            - missing_match
            - wrong_role
          type: string
        note:
          description: What is wrong, e.g. "agency account, not the brand"
          maxLength: 1000
          type: string
        role:
          description: "wrong_role (required) and missing_match: the role the account should have"
          enum:
            - brand
            - agency
            - reseller
            - partner
            - ""
          type: string
      required:
        - domain
        - kind
      type: object
    ReportOutputBody:
      additionalProperties: false
      properties:
        data:
          $ref: "#/components/schemas/ResolveReport"
      required:
        - data
      type: object
    ReportsOutputBody:
      additionalProperties: false
      properties:
        data:
          items:
            $ref: "#/components/schemas/ResolveReport"
          type:
            - array
            - "null"
      required:
        - data
      type: object
    ResolveOutputBody:
      additionalProperties: false
      properties:
        data:
          $ref: "#/components/schemas/ResolveResponse"
      required:
        - data
      type: object
    ResolveReport:
      additionalProperties: false
      properties:
        advertiser_id:
          type:
            - string
            - "null"
        created_at:
          format: date-time
          type: string
        domain:
          type: string
        id:
          format: int64
          type: integer
        kind:
          enum:
            - wrong_match
            - missing_match
            - wrong_role
          type: string
        note:
          type:
            - string
            - "null"
        resolution:
          description: Our answer when the report was reviewed
          type:
            - string
            - "null"
        resolved_at:
          format: date-time
          type:
            - string
            - "null"
        role:
          description: "wrong_role / missing_match: the role the account should have"
          enum:
            - brand
            - agency
            - reseller
            - partner
          type:
            - string
            - "null"
        status:
          enum:
            - open
            - accepted
            - rejected
          type: string
      required:
        - id
        - domain
        - advertiser_id
        - kind
        - role
        - note
        - status
        - resolution
        - created_at
        - resolved_at
      type: object
    ResolveResponse:
      additionalProperties: false
      properties:
        advertisers:
          items:
            $ref: "#/components/schemas/ResolvedAdvertiser"
          type:
            - array
            - "null"
        domain:
          type: string
        errors:
          items:
            $ref: "#/components/schemas/PlatformFailure"
          type:
            - array
            - "null"
      required:
        - domain
        - advertisers
      type: object
    ResolvedAdvertiser:
      additionalProperties: false
      properties:
        active_ads:
          description: As reported by the platform if available, else counted by us
          format: int64
          type:
            - integer
            - "null"
        avatar_url:
          type:
            - string
            - "null"
        country:
          type:
            - string
            - "null"
        domain:
          type:
            - string
            - "null"
        extra:
          additionalProperties: {}
          type: object
        first_seen_by_us:
          format: date-time
          type:
            - string
            - "null"
        id:
          type: string
        last_seen_by_us:
          format: date-time
          type:
            - string
            - "null"
        match_reason:
          description: manual = confirmed by us (or from a customer report we accepted)
          enum:
            - domain
            - name
            - history
            - manual
          type: string
        name:
          type: string
        platform:
          type: string
        platform_advertiser_id:
          type: string
        profile_url:
          type:
            - string
            - "null"
        role:
          description: "The account's relation to the domain: the brand itself, or an agency, reseller (dealer, importer) or partner running ads for it"
          enum:
            - brand
            - agency
            - reseller
            - partner
            - unknown
          type: string
        role_source:
          description: manual = set by us; inferred = from the account name
          enum:
            - manual
            - inferred
          type: string
        score:
          description: 0..1 confidence that this advertiser belongs to the domain
          format: double
          type: number
        total_ads_known:
          description: Ads in our history
          format: int64
          type: integer
        verified:
          type:
            - boolean
            - "null"
      required:
        - score
        - match_reason
        - role
        - role_source
        - id
        - platform
        - platform_advertiser_id
        - name
        - domain
        - verified
        - country
        - profile_url
        - avatar_url
        - active_ads
        - total_ads_known
        - first_seen_by_us
        - last_seen_by_us
      type: object
    SmokeCheck:
      additionalProperties: false
      properties:
        error:
          type: string
        latency_ms:
          format: int64
          type: integer
        name:
          type: string
        ok:
          type: boolean
        results:
          format: int64
          type: integer
      required:
        - name
        - ok
        - latency_ms
        - results
      type: object
    SmokeResult:
      additionalProperties: false
      properties:
        at:
          format: date-time
          type: string
        checks:
          items:
            $ref: "#/components/schemas/SmokeCheck"
          type:
            - array
            - "null"
        ok:
          type: boolean
        platform:
          type: string
      required:
        - platform
        - at
        - ok
        - checks
      type: object
    StatsOutputBody:
      additionalProperties: false
      properties:
        data:
          $ref: "#/components/schemas/AdvertiserStats"
      required:
        - data
      type: object
    StatusOutputBody:
      additionalProperties: false
      properties:
        platforms:
          items:
            $ref: "#/components/schemas/PlatformStatus"
          type:
            - array
            - "null"
        status:
          enum:
            - operational
            - degraded
            - down
          type: string
        version:
          type: string
      required:
        - status
        - platforms
        - version
      type: object
    SuggestOutputBody:
      additionalProperties: false
      properties:
        data:
          items:
            $ref: "#/components/schemas/DomainSuggestion"
          type:
            - array
            - "null"
      required:
        - data
      type: object
    Targeting:
      additionalProperties: false
      properties:
        ages:
          items:
            type: string
          type:
            - array
            - "null"
        genders:
          items:
            type: string
          type:
            - array
            - "null"
        locations:
          items:
            type: string
          type:
            - array
            - "null"
        other:
          additionalProperties:
            items:
              type: string
            type:
              - array
              - "null"
          type: object
      required:
        - ages
        - genders
        - locations
      type: object
    TestWebhookInputBody:
      additionalProperties: false
      properties:
        url:
          description: Your endpoint (https recommended)
          format: uri
          type: string
      required:
        - url
      type: object
    UsageMonth:
      additionalProperties: false
      properties:
        endpoint:
          type: string
        month:
          type: string
        requests:
          format: int64
          type: integer
        units:
          format: int64
          type: integer
      required:
        - month
        - endpoint
        - requests
        - units
      type: object
    UsageOutputBody:
      additionalProperties: false
      properties:
        credits_this_month:
          format: int64
          type: integer
        data:
          description: Daily rows (kept 90 days)
          items:
            $ref: "#/components/schemas/UsageRow"
          type:
            - array
            - "null"
        monthly:
          description: Older usage folded into monthly totals
          items:
            $ref: "#/components/schemas/UsageMonth"
          type:
            - array
            - "null"
        owner:
          type: string
        plan:
          $ref: "#/components/schemas/Plan"
      required:
        - owner
        - plan
        - credits_this_month
        - data
        - monthly
      type: object
    UsageRow:
      additionalProperties: false
      properties:
        day:
          type: string
        endpoint:
          type: string
        requests:
          format: int64
          type: integer
        units:
          format: int64
          type: integer
      required:
        - day
        - endpoint
        - requests
        - units
      type: object
    Version:
      additionalProperties: false
      properties:
        creatives:
          items:
            $ref: "#/components/schemas/Creative"
          type:
            - array
            - "null"
        valid_from:
          format: date-time
          type: string
        valid_to:
          format: date-time
          type:
            - string
            - "null"
      required:
        - valid_from
        - valid_to
        - creatives
      type: object
    Watchlist:
      additionalProperties: false
      properties:
        advertiser_count:
          format: int64
          type: integer
        advertisers:
          description: Empty in the list endpoint; GET /v1/watchlists/{id} has the entries
          items:
            $ref: "#/components/schemas/WatchlistEntry"
          type:
            - array
            - "null"
        archive_videos:
          type: boolean
        created_at:
          format: date-time
          type: string
        id:
          type: string
        interval_hours:
          description: Crawl interval, as set with interval_hours on create
          format: int64
          type: integer
        name:
          type: string
        webhook_url:
          type:
            - string
            - "null"
      required:
        - id
        - name
        - webhook_url
        - interval_hours
        - archive_videos
        - created_at
        - advertiser_count
        - advertisers
      type: object
    WatchlistEntry:
      additionalProperties: false
      properties:
        active_ads_known:
          format: int64
          type: integer
        advertiser_id:
          type: string
        last_crawl_at:
          format: date-time
          type:
            - string
            - "null"
        last_error:
          type:
            - string
            - "null"
        name:
          type: string
        next_crawl_at:
          format: date-time
          type: string
      required:
        - advertiser_id
        - name
        - last_crawl_at
        - next_crawl_at
        - last_error
        - active_ads_known
      type: object
    WatchlistInputBody:
      additionalProperties: false
      properties:
        advertisers:
          description: Advertiser ids <platform>:<id> (find them via /v1/advertisers/resolve)
          items:
            type: string
          minItems: 1
          type:
            - array
            - "null"
        archive_videos:
          description: Keep full video files for these advertisers (default true)
          type: boolean
        interval_hours:
          description: "Crawl interval in hours (default 24). Shortest per plan: Free and Starter 24, Growth 12, Pro 6, Business 1"
          format: int64
          maximum: 168
          minimum: 1
          type: integer
        name:
          maxLength: 200
          type: string
        webhook_url:
          description: Receives advertiser.changes events (new/stopped/changed ads)
          format: uri
          type: string
      required:
        - advertisers
      type: object
    WatchlistOutputBody:
      additionalProperties: false
      properties:
        data:
          $ref: "#/components/schemas/Watchlist"
      required:
        - data
      type: object
    WatchlistsOutputBody:
      additionalProperties: false
      properties:
        data:
          items:
            $ref: "#/components/schemas/Watchlist"
          type:
            - array
            - "null"
      required:
        - data
      type: object
    WebhookSecretOutputBody:
      additionalProperties: false
      properties:
        data:
          $ref: "#/components/schemas/DataStruct"
      required:
        - data
      type: object
    WeekCount:
      additionalProperties: false
      properties:
        count:
          format: int64
          type: integer
        week:
          type: string
      required:
        - week
        - count
      type: object
    Window:
      additionalProperties: false
      properties:
        avg_latency_ms:
          format: int64
          type:
            - integer
            - "null"
        blocked:
          format: int64
          type: integer
        bytes_per_result:
          description: "Upstream bytes per delivered ad (decompressed size: upper bound of proxy traffic)"
          format: int64
          type:
            - integer
            - "null"
        errors:
          format: int64
          type: integer
        ok:
          format: int64
          type: integer
        proxy_bytes:
          format: int64
          type: integer
        proxy_cost_per_1k_results_usd:
          format: double
          type:
            - number
            - "null"
        proxy_cost_usd:
          format: double
          type:
            - number
            - "null"
        requests:
          format: int64
          type: integer
        results:
          description: Ads delivered by upstream calls
          format: int64
          type: integer
        success_rate:
          format: double
          type:
            - number
            - "null"
      required:
        - requests
        - ok
        - errors
        - blocked
        - success_rate
        - avg_latency_ms
        - proxy_bytes
        - proxy_cost_usd
        - results
        - bytes_per_result
        - proxy_cost_per_1k_results_usd
      type: object
  securitySchemes:
    apiKey:
      in: header
      name: X-API-Key
      type: apiKey
    rapidApi:
      description: When called through RapidAPI
      in: header
      name: X-RapidAPI-Key
      type: apiKey
info:
  description: |-
    One API for the public ad libraries of **Meta (Facebook/Instagram), Google, TikTok, LinkedIn, Pinterest and X** —
    with our own **ad history**: ads that disappear from a platform's library when they stop are still here, with their run time.

    * **Unified schema** — every platform maps into one `Ad` object; fields a platform does not provide are `null`, never estimated. Platform-specific fields live in `extra`.
    * **One query, six platforms** — `/v1/advertisers/resolve?domain=nike.com` finds a brand's advertiser ids everywhere.
    * **History & change detection** — versions, status periods, timelines, `/changes?since=`, watchlists with webhooks.
    * **Permanent creatives** — images are archived (WebP) under stable URLs; platform media URLs expire, ours don't.
    * **Fair billing** — you pay credits per delivered result (`X-Billing-Credits` header): 1 per ad on Meta, TikTok, Pinterest and X, 2 on Google, 3 on LinkedIn, double for archived ads last shown over a year ago. A live search page costs at most 5 credits per platform (10 on Google, 15 on LinkedIn), however many ads it returns. Empty results, cached results and upstream errors are free.

    Limits: every response carries `X-RateLimit-Limit`, `X-RateLimit-Remaining` and `X-RateLimit-Reset`. Over the per-minute limit the API answers 429 `rate_limited` with `Retry-After`; when the plan's monthly credits are used up, 429 `quota_exceeded` (do not retry; upgrade or wait for the next month).

    Pagination is cursor-based everywhere: pass `next_cursor` back as `cursor`. Every response carries `X-Request-Id`.
  title: Unified Ad Library API
  version: 1.0.0
openapi: 3.1.0
paths:
  /v1/ads/{id}:
    get:
      description: Fetches the ad live from its platform (which also updates our history). If the platform no longer has it, the archived version is returned (`meta.source = history`).
      operationId: get-ad
      parameters:
        - description: Our ad id <platform>:<platform_ad_id>
          in: path
          name: id
          required: true
          schema:
            description: Our ad id <platform>:<platform_ad_id>
            examples:
              - meta:1234567890
            type: string
        - description: Serve from our archive if we saw the ad within this many seconds (0 = always live)
          explode: false
          in: query
          name: max_age
          schema:
            default: 3600
            description: Serve from our archive if we saw the ad within this many seconds (0 = always live)
            format: int64
            minimum: 0
            type: integer
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AdOutputBody"
          description: OK
        default:
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/APIError"
          description: Error
      summary: Get one ad
      tags:
        - Ads
  /v1/ads/{id}/history:
    get:
      operationId: get-ad-history
      parameters:
        - in: path
          name: id
          required: true
          schema:
            examples:
              - meta:1234567890
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/HistoryOutputBody"
          description: OK
        default:
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/APIError"
          description: Error
      summary: All observed versions and status changes of an ad
      tags:
        - History
  /v1/advertisers/resolve:
    get:
      description: Domain in, advertiser ids on Meta, Google, TikTok, LinkedIn, Pinterest and X out — each with a confidence `score` and `match_reason`.
      operationId: resolve-advertisers
      parameters:
        - explode: false
          in: query
          name: domain
          required: true
          schema:
            examples:
              - nike.com
            type: string
        - description: Comma-separated platforms; omit for all
          explode: false
          in: query
          name: platform
          schema:
            description: Comma-separated platforms; omit for all
            type: string
        - explode: false
          in: query
          name: max_per_platform
          schema:
            default: 3
            format: int64
            maximum: 10
            minimum: 1
            type: integer
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ResolveOutputBody"
          description: OK
        default:
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/APIError"
          description: Error
      summary: Find a brand's advertiser ids on all platforms from its domain
      tags:
        - Advertisers
  /v1/advertisers/resolve/reports:
    get:
      operationId: list-resolve-reports
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ReportsOutputBody"
          description: OK
        default:
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/APIError"
          description: Error
      summary: Your reports and how we resolved them (free)
      tags:
        - Advertisers
    post:
      description: "wrong_match: an advertiser in the resolve result does not belong to the domain (advertiser_id required). missing_match: the domain's account is missing (advertiser_id optional, if you know it; role optional). wrong_role: the account belongs to the domain but has the wrong role, e.g. an agency shown as the brand (advertiser_id and role required). We review reports; accepted ones change the resolve for everyone. Up to 50 reports per day."
      operationId: report-resolve
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ReportInputBody"
        required: true
      responses:
        "201":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ReportOutputBody"
          description: Created
        default:
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/APIError"
          description: Error
      summary: Report a wrong or missing resolve match (free)
      tags:
        - Advertisers
  /v1/advertisers/{id}:
    get:
      operationId: get-advertiser
      parameters:
        - in: path
          name: id
          required: true
          schema:
            examples:
              - meta:15087023444
            type: string
        - description: Crawl the first page of the advertiser's ads live before answering
          explode: false
          in: query
          name: refresh
          schema:
            description: Crawl the first page of the advertiser's ads live before answering
            type: boolean
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AdvertiserOutputBody"
          description: OK
        default:
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/APIError"
          description: Error
      summary: Get an advertiser incl. ad counts
      tags:
        - Advertisers
  /v1/advertisers/{id}/ads:
    get:
      operationId: list-advertiser-ads
      parameters:
        - in: path
          name: id
          required: true
          schema:
            examples:
              - meta:15087023444
            type: string
        - explode: false
          in: query
          name: status
          schema:
            default: all
            enum:
              - active
              - inactive
              - all
            type: string
        - description: history includes ads that vanished from the platform
          explode: false
          in: query
          name: source
          schema:
            default: live
            description: history includes ads that vanished from the platform
            enum:
              - live
              - history
            type: string
        - description: "source=history only: longest-running first"
          explode: false
          in: query
          name: sort
          schema:
            default: newest
            description: "source=history only: longest-running first"
            enum:
              - newest
              - days_running
            type: string
        - explode: false
          in: query
          name: cursor
          schema:
            type: string
        - explode: false
          in: query
          name: limit
          schema:
            default: 25
            format: int64
            maximum: 100
            minimum: 1
            type: integer
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AdListOutputBody"
          description: OK
        default:
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/APIError"
          description: Error
      summary: All ads of an advertiser (live or from history)
      tags:
        - Advertisers
  /v1/advertisers/{id}/changes:
    get:
      operationId: advertiser-changes
      parameters:
        - in: path
          name: id
          required: true
          schema:
            examples:
              - meta:15087023444
            type: string
        - description: YYYY-MM-DD or RFC3339
          explode: false
          in: query
          name: since
          required: true
          schema:
            description: YYYY-MM-DD or RFC3339
            examples:
              - "2026-10-01"
            type: string
        - description: "Comma-separated: started, stopped, changed, discovered"
          explode: false
          in: query
          name: types
          schema:
            default: started,stopped,changed
            description: "Comma-separated: started, stopped, changed, discovered"
            type: string
        - explode: false
          in: query
          name: cursor
          schema:
            type: string
        - explode: false
          in: query
          name: limit
          schema:
            default: 50
            format: int64
            maximum: 200
            minimum: 1
            type: integer
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/EventListOutputBody"
          description: OK
        default:
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/APIError"
          description: Error
      summary: New, stopped and changed ads since a point in time
      tags:
        - History
  /v1/advertisers/{id}/stats:
    get:
      description: Ads by status, format, country and language; run-time distribution; new ads per week; and the 5 longest-running ads (likely winners).
      operationId: advertiser-stats
      parameters:
        - in: path
          name: id
          required: true
          schema:
            examples:
              - meta:1234567890
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/StatsOutputBody"
          description: OK
        default:
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/APIError"
          description: Error
      summary: Advertiser analytics from our history
      tags:
        - Advertisers
  /v1/advertisers/{id}/timeline:
    get:
      operationId: advertiser-timeline
      parameters:
        - in: path
          name: id
          required: true
          schema:
            examples:
              - meta:15087023444
            type: string
        - description: Events at or after (YYYY-MM-DD or RFC3339)
          explode: false
          in: query
          name: from
          schema:
            description: Events at or after (YYYY-MM-DD or RFC3339)
            type: string
        - explode: false
          in: query
          name: to
          schema:
            type: string
        - explode: false
          in: query
          name: cursor
          schema:
            type: string
        - explode: false
          in: query
          name: limit
          schema:
            default: 50
            format: int64
            maximum: 200
            minimum: 1
            type: integer
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/EventListOutputBody"
          description: OK
        default:
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/APIError"
          description: Error
      summary: When which ads started and stopped
      tags:
        - History
  /v1/batch:
    post:
      description: Up to N (plan-dependent, max 100) advertisers, domains or ad ids. Billing is per delivered result in credits (same prices as the synchronous endpoints), not per job.
      operationId: create-batch
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/BatchInputBody"
        required: true
      responses:
        "202":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/BatchCreatedBody"
          description: Accepted
        default:
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/APIError"
          description: Error
      summary: Start an asynchronous batch job
      tags:
        - Batch
  /v1/batch/{job_id}:
    get:
      description: Finished jobs and their results are kept for 30 days.
      operationId: get-batch
      parameters:
        - in: path
          name: job_id
          required: true
          schema:
            format: uuid
            type: string
        - explode: false
          in: query
          name: cursor
          schema:
            type: string
        - description: Items per page
          explode: false
          in: query
          name: limit
          schema:
            default: 20
            description: Items per page
            format: int64
            maximum: 100
            minimum: 1
            type: integer
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/BatchOutputBody"
          description: OK
        default:
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/APIError"
          description: Error
      summary: Batch job status and results (paginated)
      tags:
        - Batch
  /v1/companies/{domain}:
    get:
      description: "Resolves the domain (like /v1/advertisers/resolve, including our manual corrections), keeps accounts with score >= min_score and aggregates their history: totals, platforms, countries, formats, weekly launches and the longest-running ads. Accounts of agencies, resellers and partners that run ads for the domain are listed separately under related (role per account) and left out of the totals unless include_related=true. Accounts below the threshold are listed as candidates. Costs one resolve plus one stats call."
      operationId: get-company
      parameters:
        - in: path
          name: domain
          required: true
          schema:
            examples:
              - audi.de
            type: string
        - description: Comma-separated platforms; omit for all
          explode: false
          in: query
          name: platform
          schema:
            description: Comma-separated platforms; omit for all
            type: string
        - description: Accounts below this resolve score are candidates, not part of the totals
          explode: false
          in: query
          name: min_score
          schema:
            default: 0.75
            description: Accounts below this resolve score are candidates, not part of the totals
            format: double
            maximum: 1
            minimum: 0
            type: number
        - description: Brands often run several accounts per platform (countries, product lines)
          explode: false
          in: query
          name: max_per_platform
          schema:
            default: 5
            description: Brands often run several accounts per platform (countries, product lines)
            format: int64
            maximum: 10
            minimum: 1
            type: integer
        - description: Count agency, reseller and partner accounts in platforms and stats too
          explode: false
          in: query
          name: include_related
          schema:
            description: Count agency, reseller and partner accounts in platforms and stats too
            type: boolean
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CompanyOutputBody"
          description: OK
        default:
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/APIError"
          description: Error
      summary: "Company profile: all ad accounts of a domain across platforms, with combined stats"
      tags:
        - Advertisers
  /v1/domains/suggest:
    get:
      description: Prefix match on domains and advertiser names we already know, most archived ads first. For autocomplete; it never asks the platforms.
      operationId: suggest-domains
      parameters:
        - explode: false
          in: query
          name: q
          required: true
          schema:
            examples:
              - nik
            maxLength: 100
            minLength: 2
            type: string
        - explode: false
          in: query
          name: limit
          schema:
            default: 8
            format: int64
            maximum: 20
            minimum: 1
            type: integer
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/SuggestOutputBody"
          description: OK
        default:
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/APIError"
          description: Error
      summary: Domain suggestions from our index while typing (free)
      tags:
        - Advertisers
  /v1/domains/{domain}/check:
    get:
      description: "Resolves the domain on all platforms and checks for current ads. Built for lead enrichment (Clay, n8n, CRMs): one flat price per check, free if nothing could be checked."
      operationId: check-domain
      parameters:
        - in: path
          name: domain
          required: true
          schema:
            examples:
              - nike.com
            type: string
        - description: Comma-separated platforms; omit for all
          explode: false
          in: query
          name: platform
          schema:
            description: Comma-separated platforms; omit for all
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/CheckOutputBody"
          description: OK
        default:
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/APIError"
          description: Error
      summary: Is this company advertising right now, and where?
      tags:
        - Advertisers
  /v1/platforms:
    get:
      operationId: platforms
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PlatformsOutputBody"
          description: OK
        default:
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/APIError"
          description: Error
      security: []
      summary: Supported search modes and filters per platform
      tags:
        - Meta
  /v1/search:
    get:
      description: "Exactly one search mode is required: `q` (keyword), `advertiser` (name, or our advertiser id `<platform>:<id>`), or `domain`. Without `platform`, all platforms supporting the mode are queried in parallel; platforms that fail are listed in `meta.errors` (and not billed). `source=history` searches our own archive instead, including ads that are gone from the platforms."
      operationId: search
      parameters:
        - description: Comma-separated platforms; omit for all that support the query
          explode: false
          in: query
          name: platform
          schema:
            description: Comma-separated platforms; omit for all that support the query
            examples:
              - meta,google
            type: string
        - description: Keyword in the ad text
          explode: false
          in: query
          name: q
          schema:
            description: Keyword in the ad text
            examples:
              - running shoes
            type: string
        - description: Advertiser name, or our advertiser id <platform>:<id>
          explode: false
          in: query
          name: advertiser
          schema:
            description: Advertiser name, or our advertiser id <platform>:<id>
            examples:
              - Nike
            type: string
        - description: Landing page / advertiser domain
          explode: false
          in: query
          name: domain
          schema:
            description: Landing page / advertiser domain
            examples:
              - nike.com
            type: string
        - description: ISO 3166-1 alpha-2
          explode: false
          in: query
          name: country
          schema:
            description: ISO 3166-1 alpha-2
            examples:
              - US
            type: string
        - explode: false
          in: query
          name: status
          schema:
            default: all
            enum:
              - active
              - inactive
              - all
            type: string
        - description: Shown on or after (YYYY-MM-DD)
          explode: false
          in: query
          name: from
          schema:
            description: Shown on or after (YYYY-MM-DD)
            type: string
        - description: Shown before (YYYY-MM-DD)
          explode: false
          in: query
          name: to
          schema:
            description: Shown before (YYYY-MM-DD)
            type: string
        - explode: false
          in: query
          name: format
          schema:
            enum:
              - image
              - video
              - carousel
              - text
              - ""
            type: string
        - description: true = only political/issue ads, false = none. Only Meta labels them, so true limits results to Meta
          explode: false
          in: query
          name: political
          schema:
            description: true = only political/issue ads, false = none. Only Meta labels them, so true limits results to Meta
            enum:
              - "true"
              - "false"
              - ""
            type: string
        - explode: false
          in: query
          name: source
          schema:
            default: live
            enum:
              - live
              - history
            type: string
        - description: "source=history only: days_running = longest-running ads first (likely winners)"
          explode: false
          in: query
          name: sort
          schema:
            default: newest
            description: "source=history only: days_running = longest-running ads first (likely winners)"
            enum:
              - newest
              - days_running
            type: string
        - explode: false
          in: query
          name: cursor
          schema:
            type: string
        - description: Page size hint (platforms have native page sizes; history honours it exactly)
          explode: false
          in: query
          name: limit
          schema:
            default: 25
            description: Page size hint (platforms have native page sizes; history honours it exactly)
            format: int64
            maximum: 100
            minimum: 1
            type: integer
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AdListOutputBody"
          description: OK
        default:
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/APIError"
          description: Error
      summary: Search ads (cross-platform when `platform` is omitted)
      tags:
        - Search
  /v1/status:
    get:
      operationId: status
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/StatusOutputBody"
          description: OK
        default:
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/APIError"
          description: Error
      security: []
      summary: Health per platform (success rate, latency, last smoke test)
      tags:
        - Meta
  /v1/usage:
    get:
      operationId: usage
      parameters:
        - explode: false
          in: query
          name: days
          schema:
            default: 30
            format: int64
            maximum: 92
            minimum: 1
            type: integer
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/UsageOutputBody"
          description: OK
        default:
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/APIError"
          description: Error
      summary: Your billed units per day and endpoint
      tags:
        - Meta
  /v1/watchlists:
    get:
      operationId: list-watchlists
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WatchlistsOutputBody"
          description: OK
        default:
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/APIError"
          description: Error
      summary: List your watchlists
      tags:
        - Monitoring
    post:
      operationId: create-watchlist
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/WatchlistInputBody"
        required: true
      responses:
        "201":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WatchlistOutputBody"
          description: Created
        default:
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/APIError"
          description: Error
      summary: Watch advertisers; we crawl them regularly and call your webhook on changes
      tags:
        - Monitoring
  /v1/watchlists/{id}:
    delete:
      operationId: delete-watchlist
      parameters:
        - in: path
          name: id
          required: true
          schema:
            format: uuid
            type: string
      responses:
        "204":
          description: No Content
        default:
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/APIError"
          description: Error
      summary: Delete a watchlist
      tags:
        - Monitoring
    get:
      operationId: get-watchlist
      parameters:
        - in: path
          name: id
          required: true
          schema:
            format: uuid
            type: string
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WatchlistOutputBody"
          description: OK
        default:
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/APIError"
          description: Error
      summary: Get a watchlist with crawl status per advertiser
      tags:
        - Monitoring
  /v1/watchlists/{id}/advertisers:
    post:
      operationId: add-watchlist-advertisers
      parameters:
        - in: path
          name: id
          required: true
          schema:
            format: uuid
            type: string
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AddAdvertisersInputBody"
        required: true
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WatchlistOutputBody"
          description: OK
        default:
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/APIError"
          description: Error
      summary: Add advertisers to a watchlist
      tags:
        - Monitoring
  /v1/watchlists/{id}/advertisers/{advertiser_id}:
    delete:
      operationId: remove-watchlist-advertiser
      parameters:
        - in: path
          name: id
          required: true
          schema:
            format: uuid
            type: string
        - in: path
          name: advertiser_id
          required: true
          schema:
            type: string
      responses:
        "204":
          description: No Content
        default:
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/APIError"
          description: Error
      summary: Remove an advertiser from a watchlist
      tags:
        - Monitoring
  /v1/webhooks/deliveries:
    get:
      description: Status, attempts and the receiver's HTTP status per delivery. Kept 30 days.
      operationId: list-webhook-deliveries
      parameters:
        - description: Filter by status
          explode: false
          in: query
          name: status
          schema:
            description: Filter by status
            enum:
              - pending
              - delivered
              - failed
              - ""
            type: string
        - explode: false
          in: query
          name: cursor
          schema:
            type: string
        - explode: false
          in: query
          name: limit
          schema:
            default: 25
            format: int64
            maximum: 100
            minimum: 1
            type: integer
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DeliveriesOutputBody"
          description: OK
        default:
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/APIError"
          description: Error
      summary: Your webhook deliveries (newest first)
      tags:
        - Monitoring
  /v1/webhooks/deliveries/{id}:
    get:
      operationId: get-webhook-delivery
      parameters:
        - in: path
          name: id
          required: true
          schema:
            format: int64
            type: integer
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/DeliveryOutputBody"
          description: OK
        default:
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/APIError"
          description: Error
      summary: One delivery incl. its payload
      tags:
        - Monitoring
  /v1/webhooks/deliveries/{id}/redeliver:
    post:
      operationId: redeliver-webhook
      parameters:
        - in: path
          name: id
          required: true
          schema:
            format: int64
            type: integer
      responses:
        "202":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/QueuedOutputBody"
          description: Accepted
        default:
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/APIError"
          description: Error
      summary: Queue a delivery again
      tags:
        - Monitoring
  /v1/webhooks/secret:
    get:
      description: "Verify X-AdLib-Signature with this secret: HMAC-SHA256 over \"<t>.<raw body>\", hex, compared to v1. Reject timestamps older than 5 minutes."
      operationId: get-webhook-secret
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WebhookSecretOutputBody"
          description: OK
        default:
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/APIError"
          description: Error
      summary: Your webhook signing secret
      tags:
        - Monitoring
  /v1/webhooks/secret/rotate:
    post:
      description: Deliveries from now on are signed with the new secret; the old one stops working immediately.
      operationId: rotate-webhook-secret
      responses:
        "200":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/WebhookSecretOutputBody"
          description: OK
        default:
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/APIError"
          description: Error
      summary: Rotate your webhook signing secret
      tags:
        - Monitoring
  /v1/webhooks/test:
    post:
      description: "Use it to verify your endpoint and signature check (X-AdLib-Signature: t=<unix>,v1=<hex HMAC-SHA256 of \"<t>.<body>\"> with your webhook secret). Slack and Discord webhook URLs get a readable message instead, unsigned."
      operationId: test-webhook
      requestBody:
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/TestWebhookInputBody"
        required: true
      responses:
        "202":
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/QueuedOutputBody"
          description: Accepted
        default:
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/APIError"
          description: Error
      summary: Send a signed test event (webhook.ping) to a URL
      tags:
        - Monitoring
security:
  - apiKey: []
  - rapidApi: []
servers:
  - url: https://api.adlibapi.com
