# YouTube Ad Creative & Advertiser Tracker (`nimbryxo-studio/youtube-ad-creative-and-advertiser-tracker`) Actor

Find the video and image ad creatives an advertiser is running on YouTube, discovered by keyword, advertiser name, or advertiser ID, with country, format, and first/last-shown dates.

- **URL**: https://apify.com/nimbryxo-studio/youtube-ad-creative-and-advertiser-tracker.md
- **Developed by:** [Nimbryxo-studio](https://apify.com/nimbryxo-studio) (community)
- **Categories:** Videos, Social media, Automation
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.49 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## YouTube Ad Creative & Advertiser Tracker

Pull the ad creatives a brand is actually running on YouTube, straight from Google's public Ads Transparency Center. Hand it a keyword, an advertiser name, or an advertiser AR-ID and get back every matching ad creative with its thumbnail, format, country, and the dates it was first and last shown.

### What this actor does

- **Two ways in:** pass advertiser names/AR-IDs directly, or give keywords and let the actor discover matching advertisers first
- **YouTube-scoped:** every creative returned was served on YouTube, not Google's wider display network
- **Country and date filters:** narrow by ISO-2 country code and by first-shown date window
- **Multiple export formats:** dataset JSON always, plus optional CSV, Excel, or HTML written to the key-value store
- **Empty fields are omitted** — a record only carries the values Google actually returned for that creative

### Output per ad creative

- `adId` — the creative's unique ID (e.g. `CR09196456782480801793`)
- `advertiserId` — the advertiser's AR-ID
- `advertiserName` — advertiser display name
- `countryCode` — ISO-2 country this creative was matched under (omitted when advertisers were passed directly by AR-ID)
- `format` — `VIDEO` or `IMAGE`
- `mediaType` — `video` or `image`
- `imageUrl`, `imageWidth`, `imageHeight` — the creative's thumbnail/preview image and its dimensions
- `videoUrl` — resolved playable video URL, only present when `includeVideoDetails` is enabled and Google exposes it
- `firstShown`, `lastShown` — timestamps the creative was first and most recently observed running
- `adCount` — total creative count Google reports for the advertiser at query time
- `searchTerm` — the keyword that surfaced this advertiser (present only for keyword-discovered results)
- `sourceUrl` — the Ads Transparency Center page for this exact creative
- `scrapedAt` — when the actor fetched the record

When no ad creatives match the input at all, the dataset instead gets a single status row (`recordType: "status"`, `status: "no_ads_found"`) echoing back the `searchTerms`/`countries`/`dateFrom`/`dateTo` that were tried, so an empty dataset always comes with an explanation.

### Input

| Field | Type | Default | Description |
|-------|------|---------|-------------|
| `advertisers` | array | — | Advertiser names or AR-IDs to pull ads for directly (e.g. `Nike, Inc.`, `AR16735076323512287233`). |
| `searchTerms` | array | – | Keywords used to discover advertisers before pulling their ads. |
| `countries` | array | – | ISO-2 country codes to match advertisers against. Leave empty for all countries. |
| `dateFrom` | string | — | Keep only creatives first shown on or after this `YYYY-MM-DD` date. |
| `dateTo` | string | — | Keep only creatives first shown on or before this `YYYY-MM-DD` date. |
| `includeVideoDetails` | boolean | `false` | Also fetch each creative's detail page to try to resolve a playable video URL. |
| `maxAdvertisersPerTerm` | integer | `5` | Advertisers to pull per keyword in `searchTerms` (1–50). |
| `maxItems` | integer | `100` | Hard cap on total ad creative records returned (1–5000). |
| `maxConcurrency` | integer | `2` | Advertisers processed in parallel (1–5). |
| `outputFormat` | string | `json` | Also export to the key-value store as `OUTPUT.csv`, `OUTPUT.xlsx`, or `OUTPUT.html`. |
| `proxyConfiguration` | object | — | Optional Apify proxy for higher-volume runs. |

At least one of `advertisers` or `searchTerms` is required.

#### Example: discover advertisers by keyword

```json
{
  "searchTerms": ["electric car"],
  "countries": ["US"],
  "maxAdvertisersPerTerm": 5,
  "maxItems": 50
}
```

#### Example: pull a known advertiser's creatives directly

```json
{
  "advertisers": ["AR16735076323512287233"],
  "countries": ["US", "GB"],
  "maxItems": 40
}
```

#### Example: narrow window with resolved video URLs

```json
{
  "searchTerms": ["nike"],
  "dateFrom": "2026-01-01",
  "dateTo": "2026-03-31",
  "includeVideoDetails": true,
  "outputFormat": "csv"
}
```

### Use cases

- **Competitive ad monitoring** — see which creatives a rival brand is currently running on YouTube
- **Creative swipe files** — collect thumbnails and formats from an industry to spot creative trends
- **Flight tracking** — watch `firstShown`/`lastShown` to know when a competitor's campaign started or stopped
- **Agency reporting** — export a client's or competitor's ad library to CSV/Excel for a deck
- **Market scans** — run a keyword across multiple countries to see who is advertising where

### FAQ

**Where does this data come from?**
Google's own public Ads Transparency Center, filtered to creatives shown on YouTube — the same tool anyone can browse at adstransparency.google.com.

**Do I need an API key, login, or cookies?**
No. The Transparency Center is public and the actor reads it without any authentication.

**Why is there no YouTube video ID or embeddable video for most ads?**
Google's Transparency Center does not publish the underlying YouTube video ID for most creatives, only a thumbnail and the ad's detail page. Enabling `includeVideoDetails` resolves a playable video URL when Google's detail page exposes one.

**Why is `countryCode` missing on some records?**
It's only populated when an advertiser was found through keyword search. When you pass an advertiser AR-ID directly, Google's API doesn't expose that advertiser's country, so the field is left out.

**How far back does the data go?**
Google's Transparency Center indexes ads from September 2023 onward, and it isn't a complete archive — older or very low-volume creatives may not appear.

**Is there a limit on how many creatives one advertiser can return?**
Yes, Google's own library caps each advertiser's results at roughly 40 creatives per query; the actor returns the most recent ones and deduplicates by `adId` across repeated queries.

**What's the difference between the `advertisers` and `searchTerms` inputs?**
`advertisers` goes straight to a known advertiser's ad library. `searchTerms` runs a keyword search first to find matching advertisers, then pulls each one's ads — useful when you don't already know the advertiser's exact name or AR-ID.

**Is this affiliated with Google or YouTube?**
No. This is an independent actor that reads Google's publicly available Ads Transparency Center data.

# Actor input Schema

## `advertisers` (type: `array`):

Advertiser names or AR-IDs to scrape YouTube ads for (e.g. 'Nike, Inc.', 'AR16735076323512287233'). Leave empty to use searchTerms.

## `searchTerms` (type: `array`):

Keywords or domain names to discover advertisers, then scrape their YouTube ads (e.g. 'electric car', 'nike.com').

## `countries` (type: `array`):

Country codes to filter ads by (ISO 3166-1 alpha-2).

## `dateFrom` (type: `string`):

Only return ads first shown on or after this date (YYYY-MM-DD).

## `dateTo` (type: `string`):

Only return ads last shown on or before this date (YYYY-MM-DD).

## `includeVideoDetails` (type: `boolean`):

Fetch the ad detail page for each ad to resolve the video URL and format (slower, but gives the actual video asset for video ads).

## `maxAdvertisersPerTerm` (type: `integer`):

Maximum advertisers to scrape per keyword (when searchTerms is used).

## `maxItems` (type: `integer`):

Hard cap on total ad records returned (1-5000).

## `maxConcurrency` (type: `integer`):

Advertisers scraped in parallel. Higher is faster but increases rate-limit risk.

## `outputFormat` (type: `string`):

Dataset always receives JSON records. Additionally export results as CSV, Excel, or HTML in the key-value store (OUTPUT.csv / OUTPUT.xlsx / OUTPUT.html).

## `proxyConfiguration` (type: `object`):

Optional proxy. For moderate traffic no proxy is needed. Enable Apify proxy for high-volume scraping.

## Actor input object example

```json
{
  "advertisers": [
    "Nike, Inc.",
    "Samsung Electronics America"
  ],
  "searchTerms": [
    "electric car"
  ],
  "countries": [
    "US"
  ],
  "includeVideoDetails": false,
  "maxAdvertisersPerTerm": 5,
  "maxItems": 50,
  "maxConcurrency": 2,
  "outputFormat": "json"
}
```

# Actor output Schema

## `ads` (type: `string`):

Dataset containing all scraped YouTube ad creative records.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "searchTerms": [
        "electric car"
    ],
    "countries": [
        "US"
    ],
    "includeVideoDetails": false,
    "maxAdvertisersPerTerm": 5,
    "maxItems": 50,
    "maxConcurrency": 2,
    "outputFormat": "json"
};

// Run the Actor and wait for it to finish
const run = await client.actor("nimbryxo-studio/youtube-ad-creative-and-advertiser-tracker").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "searchTerms": ["electric car"],
    "countries": ["US"],
    "includeVideoDetails": False,
    "maxAdvertisersPerTerm": 5,
    "maxItems": 50,
    "maxConcurrency": 2,
    "outputFormat": "json",
}

# Run the Actor and wait for it to finish
run = client.actor("nimbryxo-studio/youtube-ad-creative-and-advertiser-tracker").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "searchTerms": [
    "electric car"
  ],
  "countries": [
    "US"
  ],
  "includeVideoDetails": false,
  "maxAdvertisersPerTerm": 5,
  "maxItems": 50,
  "maxConcurrency": 2,
  "outputFormat": "json"
}' |
apify call nimbryxo-studio/youtube-ad-creative-and-advertiser-tracker --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,nimbryxo-studio/youtube-ad-creative-and-advertiser-tracker"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/9dmbnR9XsX2wiSySN/builds/5d8QxabyrsPwre1lD/openapi.json
