---
title: "Advertisers or distinct ads seen for one keyword"
method: GET
path: "/projects/{project_id}/keywords/{keyword_id}/ads"
tags: ["Keywords"]
---

# Advertisers or distinct ads seen for one keyword

`GET /projects/{project_id}/keywords/{keyword_id}/ads`

## Request

- Base URL: `https://adslighthouse.com/api/v1`
- URL: `https://adslighthouse.com/api/v1/projects/{project_id}/keywords/{keyword_id}/ads`
- Auth: HTTP bearer

Lists what one keyword's saved checks found in the window and filters, 10 per page, grouped like the keyword page. view=advertisers (default): one row per advertiser domain. view=ads: one row per distinct ad (same domain, copy, display URL and full destination URL), with the ad copy, where it was seen first and last, and its automated policy review when there is one. ads_observed counts occurrences; checks_with_ads counts saved checks where the row appeared; best_position is the highest paid slot reached (1 is first). These are observations of search results, not competitor spend or proof of a policy violation. Sorts: most-observed (default), newest, oldest, name (advertisers only), top-position or lowest-position (ads only). advertiser narrows view=ads to one domain.

## Path parameters

- `project_id` string, required: The project: its id, its brand domain (for example nike.example) or its exact project or brand name. Unknown or ambiguous references return not_found; call list_projects then.
- `keyword_id` string, required: The keyword id from list_keywords.

## Query parameters

- `view` 'advertisers' | 'ads'
- `sort` 'most-observed' | 'newest' | 'oldest' | 'name' | 'top-position' | 'lowest-position'
- `advertiser` string: Advertiser domain as it appears in list_advertisers, such as rival.example.
- `range` '7d' | '14d' | '30d' | '12m' | 'custom': Window ending today: 7d, 14d, 30d (default) or 12m. Use custom with from and to for fixed dates.
- `from` string: First local day, YYYY-MM-DD (custom range).
- `to` string: Last local day, YYYY-MM-DD, included in full (custom range).
- `time_zone` string: IANA time zone for day boundaries, such as America/New_York. Defaults to the time zone of the person the credential acts for.
- `engine` union: Search engine, or a list of engines combined with OR.
  - 'google' | 'bing'
  - string[]
- `device` union: Device, or a list combined with OR.
  - 'desktop' | 'mobile'
  - string[]
- `os` union: Operating system. unspecified matches checks that did not pin one. Must fit the chosen device.
  - 'windows' | 'macos' | 'android' | 'ios' | 'unspecified'
  - string[]
- `country` union: ISO 3166-1 alpha-2 country code such as US, or a list.
  - string
  - string[]
- `location` union: Saved location key: code:<location code>, name:<label> or country:<ISO code>. get_project_details lists the keys that have data.
  - string
  - string[]
- `cursor` string: The next_cursor value from the previous page. Omit it for the first page.

## Response `200`

Advertisers or distinct ads seen for one keyword

- object
  - `view` 'advertisers' | 'ads', required
  - `sort` 'most-observed' | 'newest' | 'oldest' | 'name' | 'top-position' | 'lowest-position', required
  - `total` integer, required: Rows in the whole selection, before paging.
  - `data` object[], required
    - `domain` string, required
    - `ads_observed` integer, required
    - `variations` integer, required: Distinct ads behind this row.
    - `checks_with_ads` integer, required
    - `best_position` integer, required
    - `engines` string[], required
    - `first_seen` string, required
    - `last_seen` string, required
    - `ad` object, nullable, required: The ad itself; null in view=advertisers.
      - `advertiser_name` string, nullable, required
      - `title` string, nullable, required
      - `description` string, nullable, required
      - `display_url` string, nullable, required
      - `url` string, nullable, required
      - `position` integer, required
      - `placement` 'top' | 'bottom', nullable, required: Where a Google ad was shown on the page; null for Bing and older observations.
      - `rank_absolute` integer, nullable, required: Position among every element of the page, when the search reported it.
      - `assets` union[], nullable, required: Ad assets shown with the ad (sitelinks, phone, promotion, price, image, extra description rows). null: not captured (older observations, imported studies); []: captured, none shown.
        - union
          - object
            - `kind` 'sitelink', required
            - `title` string, nullable, required
            - `url` string, nullable, required
            - `description` string, nullable, required
          - object
            - `kind` 'phone', required
            - `number` string, required
          - object
            - `kind` 'promotion', required
            - `text` string, required
            - `url` string, nullable, required
          - object
            - `kind` 'price', required
            - `displayed` string, nullable, required
            - `current` number, nullable, required
            - `regular` number, nullable, required
            - `max_value` number, nullable, required
            - `currency` string, nullable, required: ISO 4217 code when reported.
            - `is_range` boolean, nullable, required
          - object: The ad showed an image; it is not stored.
            - `kind` 'image', required
          - object
            - `kind` 'description_line', required
            - `text` string, required
      - `best_observation` object, required
        - `observation_id` string, required
        - `observed_at` string, required
        - `engine` 'google' | 'bing', required
        - `device` 'desktop' | 'mobile', required
        - `os` string, nullable, required
        - `country` string, required
        - `location` string, nullable, required
      - `latest_observation` object, required
        - `observation_id` string, required
        - `observed_at` string, required
        - `engine` 'google' | 'bing', required
        - `device` 'desktop' | 'mobile', required
        - `os` string, nullable, required
        - `country` string, required
        - `location` string, nullable, required
      - `screenshot` object, nullable, required: Picture of the results page where this ad (same domain, title and description) first appeared in the project; null when none was stored. Evidence of that page, not proof of spend.
        - `id` string, required: Download it over REST from /projects/{project_id}/screenshots/{id}.
        - `exact` boolean, required: true: the results page this ad was found on. false: only on older pictures, taken from a new load of the same search moments later, which may show different ads.
        - `captured_at` string, required
        - `app_url` string, required: Opens the picture in the app for a signed-in member of the project's account.
      - `landing_screenshot` object, nullable, required: Preview of saved HTML with scripts disabled. Static-assets previews fetch images, styles and fonts at render time; offline previews block external resources. Null when no preview exists.
        - `id` string, required
        - `captured_at` string, required
        - `app_url` string, required
        - `rendering` 'saved_html_offline' | 'saved_html_static_assets', required
    - `policy_review` object, nullable, required: Automated first reading of this ad against the advertising policy on trademarks and misrepresentation, as shown in the app. A triage aid, not a legal finding; null when the ad was not reviewed.
      - `status` 'pending' | 'complete' | 'failed', required
      - `verdict` 'likely_policy_concern' | 'needs_review' | 'likely_allowed' | 'insufficient_evidence', nullable, required
      - `confidence` 'low' | 'medium' | 'high', nullable, required
      - `summary` string, nullable, required
      - `reasons` string[], required
      - `limitations` string[], required
      - `reviewed_at` string, nullable, required
  - `next_cursor` string, nullable, required: Pass as cursor to get the next page; null on the last page.
  - `window` object, required
    - `from` string, required: First local day included, YYYY-MM-DD.
    - `to` string, required: Last local day included, YYYY-MM-DD.
    - `time_zone` string, required
    - `start` string, required: Inclusive start instant, ISO 8601.
    - `end` string, required: Exclusive end instant, ISO 8601.
  - `request_id` string

## Other responses

- `400`: Invalid parameters, cursor or body.
- `401`: Missing, invalid, expired or revoked credential.
- `403`: The credential lacks the write scope, the plan does not include the API, or the allowance is used up.
- `404`: Unknown project, keyword or run in this account.
- `409`: The idempotency key was already used for a different request.
- `429`: Rate limit reached. Retry after the Retry-After seconds.
- `503`: The requested service or file is temporarily unavailable.

---

[API](https://skmtc.dev/adslighthouse/apis/ads-lighthouse-api.md) · [All operations](https://skmtc.dev/adslighthouse/apis/ads-lighthouse-api/llms.txt) · [OpenAPI document](https://skmtc.dev/adslighthouse/apis/ads-lighthouse-api/revisions/e1a4a40b11a9?raw)
