{
  "data": {
    "id": "Y0XDsZPnAW5M5FjGb",
    "actId": "9dmbnR9XsX2wiSySN",
    "userId": "IYgBDiXtHOijAaUel",
    "startedAt": "2026-11-06T18:19:06.914Z",
    "finishedAt": "2026-11-06T18:19:18.195Z",
    "status": "SUCCEEDED",
    "meta": {
      "origin": "CLI"
    },
    "stats": {
      "durationMillis": 11199,
      "runTimeSecs": 11.199,
      "computeUnits": 0.012443333333333334,
      "imageSizeBytes": 363311616
    },
    "options": {
      "useCache": true,
      "betaPackages": false,
      "memoryMbytes": 4096,
      "diskMbytes": 8192
    },
    "createdByOrganizationMemberUserId": "QYo53EZkJk0prePWY",
    "exitCode": 0,
    "inputSchema": "{\n  \"title\": \"YouTube Ads Scraper Input\",\n  \"description\": \"Scrape YouTube ads from Google's Ads Transparency Center. Search by advertiser, keyword, or country, and export the results.\",\n  \"type\": \"object\",\n  \"schemaVersion\": 1,\n  \"properties\": {\n    \"advertisers\": {\n      \"title\": \"Advertisers\",\n      \"type\": \"array\",\n      \"description\": \"Advertiser names, AR-IDs, Transparency Center URLs, or landing domains to scrape YouTube ads for (e.g. 'Nike, Inc.', 'AR16735076323512287233', 'nike.com'). Names are matched to the strongest suggestion (exact name first, then ad count). Leave empty to use searchTerms.\",\n      \"editor\": \"stringList\",\n      \"items\": {\n        \"type\": \"string\"\n      }\n    },\n    \"searchTerms\": {\n      \"title\": \"Search Terms (keywords or domains)\",\n      \"type\": \"array\",\n      \"description\": \"Keywords or domains used to discover advertisers and domains, then scrape their YouTube ads (e.g. 'electric car', 'nike.com'). Keyword searches also use domain suggestions returned by Google.\",\n      \"editor\": \"stringList\",\n      \"items\": {\n        \"type\": \"string\"\n      },\n      \"prefill\": [\n        \"nike.com\"\n      ]\n    },\n    \"countries\": {\n      \"title\": \"Countries (queried regions)\",\n      \"type\": \"array\",\n      \"description\": \"ISO 3166-1 alpha-2 queried regions sent to the Transparency Center as the ad filter (e.g. US, GB). This is the region the ads were served in, not the advertiser's headquarters country. The advertiser's own country is reported separately as advertiserCountryCode.\",\n      \"editor\": \"select\",\n      \"items\": {\n        \"type\": \"string\",\n        \"enum\": [\n          \"AD\",\n          \"AE\",\n          \"AG\",\n          \"AI\",\n          \"AL\",\n          \"AM\",\n          \"AO\",\n          \"AQ\",\n          \"AR\",\n          \"AS\",\n          \"AT\",\n          \"AU\",\n          \"AW\",\n          \"AZ\",\n          \"BA\",\n          \"BB\",\n          \"BD\",\n          \"BE\",\n          \"BF\",\n          \"BG\",\n          \"BH\",\n          \"BI\",\n          \"BJ\",\n          \"BM\",\n          \"BN\",\n          \"BO\",\n          \"BQ\",\n          \"BR\",\n          \"BS\",\n          \"BT\",\n          \"BV\",\n          \"BW\",\n          \"BY\",\n          \"BZ\",\n          \"CA\",\n          \"CC\",\n          \"CD\",\n          \"CF\",\n          \"CG\",\n          \"CH\",\n          \"CI\",\n          \"CK\",\n          \"CL\",\n          \"CM\",\n          \"CN\",\n          \"CO\",\n          \"CR\",\n          \"CV\",\n          \"CW\",\n          \"CX\",\n          \"CY\",\n          \"CZ\",\n          \"DE\",\n          \"DJ\",\n          \"DK\",\n          \"DM\",\n          \"DO\",\n          \"DZ\",\n          \"EC\",\n          \"EE\",\n          \"EG\",\n          \"EH\",\n          \"ER\",\n          \"ES\",\n          \"ET\",\n          \"FI\",\n          \"FJ\",\n          \"FK\",\n          \"FM\",\n          \"FO\",\n          \"FR\",\n          \"GA\",\n          \"GB\",\n          \"GD\",\n          \"GE\",\n          \"GF\",\n          \"GG\",\n          \"GH\",\n          \"GI\",\n          \"GL\",\n          \"GM\",\n          \"GN\",\n          \"GP\",\n          \"GQ\",\n          \"GR\",\n          \"GS\",\n          \"GT\",\n          \"GU\",\n          \"GW\",\n          \"GY\",\n          \"HK\",\n          \"HM\",\n          \"HN\",\n          \"HR\",\n          \"HT\",\n          \"HU\",\n          \"ID\",\n          \"IE\",\n          \"IL\",\n          \"IM\",\n          \"IN\",\n          \"IO\",\n          \"IQ\",\n          \"IS\",\n          \"IT\",\n          \"JE\",\n          \"JM\",\n          \"JO\",\n          \"JP\",\n          \"KE\",\n          \"KG\",\n          \"KH\",\n          \"KI\",\n          \"KM\",\n          \"KN\",\n          \"KR\",\n          \"KW\",\n          \"KY\",\n          \"KZ\",\n          \"LA\",\n          \"LB\",\n          \"LC\",\n          \"LI\",\n          \"LK\",\n          \"LR\",\n          \"LS\",\n          \"LT\",\n          \"LU\",\n          \"LV\",\n          \"LY\",\n          \"MA\",\n          \"MC\",\n          \"MD\",\n          \"ME\",\n          \"MG\",\n          \"MH\",\n          \"MK\",\n          \"ML\",\n          \"MM\",\n          \"MN\",\n          \"MO\",\n          \"MP\",\n          \"MQ\",\n          \"MR\",\n          \"MS\",\n          \"MT\",\n          \"MU\",\n          \"MV\",\n          \"MW\",\n          \"MX\",\n          \"MY\",\n          \"MZ\",\n          \"NA\",\n          \"NC\",\n          \"NE\",\n          \"NF\",\n          \"NG\",\n          \"NI\",\n          \"NL\",\n          \"NO\",\n          \"NP\",\n          \"NR\",\n          \"NU\",\n          \"NZ\",\n          \"OM\",\n          \"PA\",\n          \"PE\",\n          \"PF\",\n          \"PG\",\n          \"PH\",\n          \"PK\",\n          \"PL\",\n          \"PM\",\n          \"PN\",\n          \"PR\",\n          \"PS\",\n          \"PT\",\n          \"PW\",\n          \"PY\",\n          \"QA\",\n          \"RE\",\n          \"RO\",\n          \"RW\",\n          \"SA\",\n          \"SB\",\n          \"SC\",\n          \"SE\",\n          \"SG\",\n          \"SH\",\n          \"SI\",\n          \"SJ\",\n          \"SK\",\n          \"SL\",\n          \"SM\",\n          \"SN\",\n          \"SO\",\n          \"SR\",\n          \"ST\",\n          \"SV\",\n          \"SX\",\n          \"SZ\",\n          \"TC\",\n          \"TD\",\n          \"TF\",\n          \"TG\",\n          \"TH\",\n          \"TJ\",\n          \"TK\",\n          \"TL\",\n          \"TM\",\n          \"TN\",\n          \"TO\",\n          \"TR\",\n          \"TT\",\n          \"TV\",\n          \"TW\",\n          \"TZ\",\n          \"UA\",\n          \"UG\",\n          \"UM\",\n          \"US\",\n          \"UY\",\n          \"UZ\",\n          \"VA\",\n          \"VC\",\n          \"VE\",\n          \"VG\",\n          \"VI\",\n          \"VN\",\n          \"VU\",\n          \"WF\",\n          \"WS\",\n          \"YE\",\n          \"YT\",\n          \"ZA\",\n          \"ZM\",\n          \"ZW\"\n        ],\n        \"enumTitles\": [\n          \"Andorra\",\n          \"United Arab Emirates\",\n          \"Antigua and Barbuda\",\n          \"Anguilla\",\n          \"Albania\",\n          \"Armenia\",\n          \"Angola\",\n          \"Antarctica\",\n          \"Argentina\",\n          \"American Samoa\",\n          \"Austria\",\n          \"Australia\",\n          \"Aruba\",\n          \"Azerbaijan\",\n          \"Bosnia and Herzegovina\",\n          \"Barbados\",\n          \"Bangladesh\",\n          \"Belgium\",\n          \"Burkina Faso\",\n          \"Bulgaria\",\n          \"Bahrain\",\n          \"Burundi\",\n          \"Benin\",\n          \"Bermuda\",\n          \"Brunei Darussalam\",\n          \"Bolivia, Plurinational State of\",\n          \"Bonaire, Sint Eustatius and Saba\",\n          \"Brazil\",\n          \"Bahamas\",\n          \"Bhutan\",\n          \"Bouvet Island\",\n          \"Botswana\",\n          \"Belarus\",\n          \"Belize\",\n          \"Canada\",\n          \"Cocos (Keeling) Islands\",\n          \"Congo, The Democratic Republic of the\",\n          \"Central African Republic\",\n          \"Congo\",\n          \"Switzerland\",\n          \"Côte d'Ivoire\",\n          \"Cook Islands\",\n          \"Chile\",\n          \"Cameroon\",\n          \"China\",\n          \"Colombia\",\n          \"Costa Rica\",\n          \"Cabo Verde\",\n          \"Curaçao\",\n          \"Christmas Island\",\n          \"Cyprus\",\n          \"Czechia\",\n          \"Germany\",\n          \"Djibouti\",\n          \"Denmark\",\n          \"Dominica\",\n          \"Dominican Republic\",\n          \"Algeria\",\n          \"Ecuador\",\n          \"Estonia\",\n          \"Egypt\",\n          \"Western Sahara\",\n          \"Eritrea\",\n          \"Spain\",\n          \"Ethiopia\",\n          \"Finland\",\n          \"Fiji\",\n          \"Falkland Islands (Malvinas)\",\n          \"Micronesia, Federated States of\",\n          \"Faroe Islands\",\n          \"France\",\n          \"Gabon\",\n          \"United Kingdom\",\n          \"Grenada\",\n          \"Georgia\",\n          \"French Guiana\",\n          \"Guernsey\",\n          \"Ghana\",\n          \"Gibraltar\",\n          \"Greenland\",\n          \"Gambia\",\n          \"Guinea\",\n          \"Guadeloupe\",\n          \"Equatorial Guinea\",\n          \"Greece\",\n          \"South Georgia and the South Sandwich Islands\",\n          \"Guatemala\",\n          \"Guam\",\n          \"Guinea-Bissau\",\n          \"Guyana\",\n          \"Hong Kong\",\n          \"Heard Island and McDonald Islands\",\n          \"Honduras\",\n          \"Croatia\",\n          \"Haiti\",\n          \"Hungary\",\n          \"Indonesia\",\n          \"Ireland\",\n          \"Israel\",\n          \"Isle of Man\",\n          \"India\",\n          \"British Indian Ocean Territory\",\n          \"Iraq\",\n          \"Iceland\",\n          \"Italy\",\n          \"Jersey\",\n          \"Jamaica\",\n          \"Jordan\",\n          \"Japan\",\n          \"Kenya\",\n          \"Kyrgyzstan\",\n          \"Cambodia\",\n          \"Kiribati\",\n          \"Comoros\",\n          \"Saint Kitts and Nevis\",\n          \"Korea, Republic of\",\n          \"Kuwait\",\n          \"Cayman Islands\",\n          \"Kazakhstan\",\n          \"Lao People's Democratic Republic\",\n          \"Lebanon\",\n          \"Saint Lucia\",\n          \"Liechtenstein\",\n          \"Sri Lanka\",\n          \"Liberia\",\n          \"Lesotho\",\n          \"Lithuania\",\n          \"Luxembourg\",\n          \"Latvia\",\n          \"Libya\",\n          \"Morocco\",\n          \"Monaco\",\n          \"Moldova, Republic of\",\n          \"Montenegro\",\n          \"Madagascar\",\n          \"Marshall Islands\",\n          \"North Macedonia\",\n          \"Mali\",\n          \"Myanmar\",\n          \"Mongolia\",\n          \"Macao\",\n          \"Northern Mariana Islands\",\n          \"Martinique\",\n          \"Mauritania\",\n          \"Montserrat\",\n          \"Malta\",\n          \"Mauritius\",\n          \"Maldives\",\n          \"Malawi\",\n          \"Mexico\",\n          \"Malaysia\",\n          \"Mozambique\",\n          \"Namibia\",\n          \"New Caledonia\",\n          \"Niger\",\n          \"Norfolk Island\",\n          \"Nigeria\",\n          \"Nicaragua\",\n          \"Netherlands\",\n          \"Norway\",\n          \"Nepal\",\n          \"Nauru\",\n          \"Niue\",\n          \"New Zealand\",\n          \"Oman\",\n          \"Panama\",\n          \"Peru\",\n          \"French Polynesia\",\n          \"Papua New Guinea\",\n          \"Philippines\",\n          \"Pakistan\",\n          \"Poland\",\n          \"Saint Pierre and Miquelon\",\n          \"Pitcairn\",\n          \"Puerto Rico\",\n          \"Palestine, State of\",\n          \"Portugal\",\n          \"Palau\",\n          \"Paraguay\",\n          \"Qatar\",\n          \"Réunion\",\n          \"Romania\",\n          \"Rwanda\",\n          \"Saudi Arabia\",\n          \"Solomon Islands\",\n          \"Seychelles\",\n          \"Sweden\",\n          \"Singapore\",\n          \"Saint Helena, Ascension and Tristan da Cunha\",\n          \"Slovenia\",\n          \"Svalbard and Jan Mayen\",\n          \"Slovakia\",\n          \"Sierra Leone\",\n          \"San Marino\",\n          \"Senegal\",\n          \"Somalia\",\n          \"Suriname\",\n          \"Sao Tome and Principe\",\n          \"El Salvador\",\n          \"Sint Maarten (Dutch part)\",\n          \"Eswatini\",\n          \"Turks and Caicos Islands\",\n          \"Chad\",\n          \"French Southern Territories\",\n          \"Togo\",\n          \"Thailand\",\n          \"Tajikistan\",\n          \"Tokelau\",\n          \"Timor-Leste\",\n          \"Turkmenistan\",\n          \"Tunisia\",\n          \"Tonga\",\n          \"Türkiye\",\n          \"Trinidad and Tobago\",\n          \"Tuvalu\",\n          \"Taiwan, Province of China\",\n          \"Tanzania, United Republic of\",\n          \"Ukraine\",\n          \"Uganda\",\n          \"United States Minor Outlying Islands\",\n          \"United States\",\n          \"Uruguay\",\n          \"Uzbekistan\",\n          \"Holy See (Vatican City State)\",\n          \"Saint Vincent and the Grenadines\",\n          \"Venezuela, Bolivarian Republic of\",\n          \"Virgin Islands, British\",\n          \"Virgin Islands, U.S.\",\n          \"Viet Nam\",\n          \"Vanuatu\",\n          \"Wallis and Futuna\",\n          \"Samoa\",\n          \"Yemen\",\n          \"Mayotte\",\n          \"South Africa\",\n          \"Zambia\",\n          \"Zimbabwe\"\n        ]\n      },\n      \"prefill\": [\n        \"US\"\n      ]\n    },\n    \"dateFrom\": {\n      \"title\": \"Shown during window: from (YYYY-MM-DD)\",\n      \"type\": \"string\",\n      \"description\": \"Keep ads whose observed flight overlaps this window. An ad is kept when firstShown <= dateTo and lastShown >= dateFrom, so ads that started earlier but were still running inside the window are included.\",\n      \"editor\": \"datepicker\",\n      \"pattern\": \"^\\\\d{4}-\\\\d{2}-\\\\d{2}$\"\n    },\n    \"dateTo\": {\n      \"title\": \"Shown during window: to (YYYY-MM-DD)\",\n      \"type\": \"string\",\n      \"description\": \"Keep ads whose observed flight overlaps this window (inclusive). Works together with dateFrom and is no longer compared only against firstShown.\",\n      \"editor\": \"datepicker\",\n      \"pattern\": \"^\\\\d{4}-\\\\d{2}-\\\\d{2}$\"\n    },\n    \"format\": {\n      \"title\": \"Ad format\",\n      \"type\": \"string\",\n      \"description\": \"Server-side creative format filter. TEXT, IMAGE and VIDEO map to Google's verified format codes 1, 2 and 3.\",\n      \"editor\": \"select\",\n      \"enum\": [\n        \"all\",\n        \"text\",\n        \"image\",\n        \"video\"\n      ],\n      \"enumTitles\": [\n        \"All formats\",\n        \"Text\",\n        \"Image\",\n        \"Video\"\n      ],\n      \"default\": \"all\",\n      \"prefill\": \"all\"\n    },\n    \"includeVideoDetails\": {\n      \"title\": \"Include creative detail enrichment\",\n      \"type\": \"boolean\",\n      \"description\": \"Fetch GetCreativeById for every creative to enrich last-shown dates, served regions and preview assets. Video IDs are resolved from previews even when this is off.\",\n      \"default\": false,\n      \"prefill\": false\n    },\n    \"resolveVideoIds\": {\n      \"title\": \"Resolve YouTube video IDs from previews\",\n      \"type\": \"boolean\",\n      \"description\": \"Extract videoId, watch URL, thumbnail and duration from creative previews (ytimg/youtube URLs). Missing IDs are omitted, never fabricated. Turn off to save preview requests.\",\n      \"default\": true,\n      \"prefill\": false\n    },\n    \"maxAdvertisersPerTerm\": {\n      \"title\": \"Max advertisers per search term\",\n      \"type\": \"integer\",\n      \"description\": \"Maximum advertiser matches (and domain suggestions) to scrape per keyword (when searchTerms is used).\",\n      \"minimum\": 1,\n      \"maximum\": 50,\n      \"default\": 5,\n      \"prefill\": 5\n    },\n    \"maxAdsPerAdvertiser\": {\n      \"title\": \"Max ads per advertiser\",\n      \"type\": \"integer\",\n      \"description\": \"Cursor-pagination cap per advertiser or domain, applied before the global maxItems cap.\",\n      \"minimum\": 1,\n      \"maximum\": 5000,\n      \"default\": 100,\n      \"prefill\": 3\n    },\n    \"maxItems\": {\n      \"title\": \"Max items\",\n      \"type\": \"integer\",\n      \"description\": \"Hard cap on total ad records returned (1-5000). Advertiser and run-summary records do not count toward this cap.\",\n      \"minimum\": 1,\n      \"maximum\": 5000,\n      \"default\": 100,\n      \"prefill\": 3\n    },\n    \"maxConcurrency\": {\n      \"title\": \"Max concurrency\",\n      \"type\": \"integer\",\n      \"description\": \"Advertisers scraped in parallel. Higher is faster but increases rate-limit risk.\",\n      \"minimum\": 1,\n      \"maximum\": 5,\n      \"default\": 2,\n      \"prefill\": 2\n    },\n    \"onlyNew\": {\n      \"title\": \"Only new ads (monitor mode)\",\n      \"type\": \"boolean\",\n      \"description\": \"Output only ad IDs not seen in earlier runs and mark them isNew: true. Reuse the same monitorStoreName for the same competitor list. The first run creates the baseline.\",\n      \"default\": false,\n      \"prefill\": false\n    },\n    \"monitorStoreName\": {\n      \"title\": \"Monitor store name\",\n      \"type\": \"string\",\n      \"description\": \"Key-value store that remembers seen ad IDs for monitor mode (default: youtube-ads-monitor).\",\n      \"default\": \"youtube-ads-monitor\",\n      \"prefill\": \"youtube-ads-monitor\",\n      \"editor\": \"textfield\"\n    },\n    \"outputFormat\": {\n      \"title\": \"Output format\",\n      \"type\": \"string\",\n      \"description\": \"Dataset always receives JSON records. Additionally export results as CSV, Excel, or HTML in the key-value store (OUTPUT.csv / OUTPUT.xlsx / OUTPUT.html).\",\n      \"editor\": \"select\",\n      \"enum\": [\n        \"json\",\n        \"csv\",\n        \"excel\",\n        \"html\"\n      ],\n      \"enumTitles\": [\n        \"JSON (dataset only)\",\n        \"CSV (OUTPUT.csv)\",\n        \"Excel (OUTPUT.xlsx)\",\n        \"HTML (OUTPUT.html)\"\n      ],\n      \"default\": \"json\",\n      \"prefill\": \"json\"\n    },\n    \"proxyConfiguration\": {\n      \"title\": \"Proxy Configuration\",\n      \"type\": \"object\",\n      \"description\": \"Optional proxy. For moderate traffic no proxy is needed. Enable Apify proxy for high-volume scraping.\",\n      \"editor\": \"proxy\"\n    }\n  }\n}",
    "readme": "# YouTube Ad Creative & Advertiser Tracker\r\n\r\nPull the ad creatives a brand is actually running on YouTube, straight from Google's public Ads Transparency Center. Hand it a keyword, a domain, an advertiser name, or an advertiser AR-ID and get back every matching ad creative with its thumbnail, format, queried region, flight dates, and — when Google exposes it — the YouTube `videoId`, watch URL, thumbnail, and duration.\r\n\r\n## What this actor does\r\n\r\n- **Four ways in:** advertiser names, AR-IDs, Transparency Center URLs, or landing domains\r\n- **Cursor pagination:** follows Google's `response.2` cursor back as `request.4` until `maxAdsPerAdvertiser` or `maxItems` is reached\r\n- **Server-side filters:** sends the queried region (`3.8`), format (`3.4`), and served-date window (`3.6`/`3.7`) to Google\r\n- **Correct date semantics:** keeps ads whose flight overlaps the requested window (`firstShown <= dateTo` and `lastShown >= dateFrom`), so `dateTo` no longer drops long-running ads\r\n- **YouTube metadata from previews:** resolves `videoId`, watch URL, `ytimg` thumbnail, and duration from `content.js` previews first, with `GetCreativeById` as a fallback\r\n- **Honest country fields:** `countryCode` is the queried region, `advertiserCountryCode` is the advertiser's headquarters, and `servedRegions` comes from Google's per-creative detail when enrichment is on\r\n- **Diagnostics:** distinguishes blocked, empty, filtered-empty and partial runs, and writes one `advertiser` record per target plus a `run_summary`\r\n- **Monitor mode:** `onlyNew` + `monitorStoreName` remembers seen ad IDs and outputs only new ads, marked `isNew: true`\r\n- **Multiple exports:** dataset JSON always, plus optional CSV, Excel, or HTML in the key-value store; every export includes `scrapedAt`\r\n\r\n## Dataset records\r\n\r\nEvery dataset item has a `recordType`:\r\n\r\n- `ad` — one YouTube ad creative (the main records)\r\n- `advertiser` — one row per resolved advertiser/domain with status, pages fetched, and ads collected\r\n- `run_summary` — one row per run with overall status, counts, filters, and diagnostics\r\n\r\n### Ad fields\r\n\r\n- `adId` — Google creative ID (e.g. `CR09196456782480801793`)\r\n- `advertiserId`, `advertiserName` — Google advertiser identity\r\n- `advertiserCountryCode` — advertiser headquarters country from suggestions, when known\r\n- `countryCode`, `queriedRegions` — region(s) used for the ad request (e.g. `US`, `anywhere`)\r\n- `servedRegions` — countries where the creative was served (normally from `includeVideoDetails`; may also appear when preview resolution triggers a detail fetch)\r\n- `format`, `mediaType` — `TEXT`/`image` mapping from Google's verified codes `1/2/3`\r\n- `imageUrl`, `imageWidth`, `imageHeight` — archived screenshot/thumbnail\r\n- `previewUrl` — Google's `content.js` preview bundle\r\n- `videoId` — YouTube video ID from a preview (`ytimg`/YouTube URL); omitted when Google does not expose it\r\n- `videoUrl` — direct `googlevideo.com` media URL when the creative exposes one (baseline-compatible)\r\n- `videoPageUrl` — `https://www.youtube.com/watch?v=<videoId>`\r\n- `landingUrl` — advertiser click URL decoded from the creative overlay when present\r\n- `videoThumbnailUrl` — `ytimg.com` thumbnail found in the preview\r\n- `videoDurationSeconds` — duration parsed from the preview (`dur=` or VAST)\r\n- `videoIdSource` — e.g. `preview:ytimg`, `detail-preview:youtube`, `item:ytimg`\r\n- `firstShown`, `lastShown` — observed flight timestamps\r\n- `daysShown` — inclusive days between first and last shown\r\n- `lastShownAgeDays` — days since `lastShown` at scrape time\r\n- `adCount`, `searchTerm`, `sourceUrl`, `scrapedAt`\r\n- `isNew` — only present in monitor mode\r\n\r\n## Input\r\n\r\n| Field | Type | Default | Description |\r\n|-------|------|---------|-------------|\r\n| `advertisers` | array | — | Advertiser names, AR-IDs, Transparency URLs, or domains (e.g. `Nike, Inc.`, `AR16735076323512287233`, `nike.com`). Names are matched to the strongest suggestion: exact name first, then prefix/containment, then ad count. |\r\n| `searchTerms` | array | — | Keywords or domains used to discover advertisers and domain suggestions before scraping. |\r\n| `countries` | array | — | Queried ISO-2 regions sent to Google. This is the ad-serving region, not the advertiser's HQ country. |\r\n| `dateFrom` | string | — | Flight-overlap window start (`YYYY-MM-DD`). |\r\n| `dateTo` | string | — | Flight-overlap window end (`YYYY-MM-DD`). Works correctly even when the ad started earlier. |\r\n| `format` | string | `all` | `all`, `text`, `image`, or `video`. Sent server-side as Google format codes `1/2/3`. |\r\n| `includeVideoDetails` | boolean | `false` | Fetch `GetCreativeById` for every creative to enrich last-shown dates, served regions, images, and preview fallbacks. |\r\n| `resolveVideoIds` | boolean | `true` | Resolve video metadata from previews. Missing IDs are omitted, never fabricated. |\r\n| `maxAdvertisersPerTerm` | integer | `5` | Advertiser matches (and domain suggestions) per keyword. |\r\n| `maxAdsPerAdvertiser` | integer | `100` | Cursor-pagination cap per advertiser/domain. |\r\n| `maxItems` | integer | `100` | Global ad-record cap (1–5000). Advertiser and summary records do not count. |\r\n| `maxConcurrency` | integer | `2` | Advertisers scraped in parallel (1–5). |\r\n| `onlyNew` | boolean | `false` | Monitor mode: output only ad IDs not seen in earlier runs. |\r\n| `monitorStoreName` | string | `youtube-ads-monitor` | Key-value store that remembers seen ad IDs for monitor mode. |\r\n| `outputFormat` | string | `json` | Also export `OUTPUT.csv`, `OUTPUT.xlsx`, or `OUTPUT.html`. |\r\n| `proxyConfiguration` | object | — | Optional Apify proxy for higher-volume runs. |\r\n\r\nAt least one of `advertisers` or `searchTerms` is required.\r\n\r\n### Example: discover by keyword or domain\r\n\r\n```json\r\n{\r\n  \"searchTerms\": [\"nike.com\", \"electric car\"],\r\n  \"countries\": [\"US\"],\r\n  \"format\": \"video\",\r\n  \"maxAdvertisersPerTerm\": 5,\r\n  \"maxAdsPerAdvertiser\": 100,\r\n  \"maxItems\": 200\r\n}\r\n```\r\n\r\n### Example: pull a known advertiser directly\r\n\r\n```json\r\n{\r\n  \"advertisers\": [\"AR16735076323512287233\"],\r\n  \"countries\": [\"US\", \"GB\"],\r\n  \"dateFrom\": \"2026-01-01\",\r\n  \"dateTo\": \"2026-10-31\",\r\n  \"maxAdsPerAdvertiser\": 150,\r\n  \"maxItems\": 300\r\n}\r\n```\r\n\r\n### Example: monitor a competitor for new ads\r\n\r\n```json\r\n{\r\n  \"advertisers\": [\"Nike, Inc.\"],\r\n  \"countries\": [\"US\"],\r\n  \"format\": \"video\",\r\n  \"onlyNew\": true,\r\n  \"monitorStoreName\": \"nike-youtube-monitor\",\r\n  \"maxAdsPerAdvertiser\": 100\r\n}\r\n```\r\n\r\nRun once to establish the baseline. Schedule the same input; later runs output only new ad IDs with `isNew: true` and still write the advertiser/run-summary diagnostics.\r\n\r\n### Example: window with preview-resolved video IDs\r\n\r\n```json\r\n{\r\n  \"searchTerms\": [\"nike\"],\r\n  \"countries\": [\"US\"],\r\n  \"dateFrom\": \"2026-01-01\",\r\n  \"dateTo\": \"2026-06-30\",\r\n  \"format\": \"video\",\r\n  \"includeVideoDetails\": true,\r\n  \"outputFormat\": \"csv\"\r\n}\r\n```\r\n\r\n## Use cases\r\n\r\n- **Competitive ad monitoring** — see which creatives a rival is running now\r\n- **Creative swipe files** — collect thumbnails, formats, durations, and video IDs\r\n- **Flight tracking** — compare `firstShown`/`lastShown`/`daysShown` across campaigns\r\n- **Agency reporting** — export to CSV/Excel with `scrapedAt` for provenance\r\n- **Market scans** — run a keyword or domain across multiple queried regions\r\n\r\n## FAQ and hard limits\r\n\r\n**Where does this data come from?**\r\nGoogle's public Ads Transparency Center, filtered to YouTube creatives. No login or API key is required.\r\n\r\n**How many creatives can one advertiser return?**\r\nMore than 40. The actor follows the server cursor (`response.2` → `request.4`) and pages until `maxAdsPerAdvertiser`/`maxItems` or Google stops returning a cursor. Large advertisers can return thousands of creatives.\r\n\r\n**Do the date filters really work server-side?**\r\nYes. `dateFrom`/`dateTo` are sent as `3.6`/`3.7` in `YYYYMMDD` form. The server applies a flight-overlap filter; the actor re-checks the same overlap locally. `dateTo` is no longer compared only against `firstShown`.\r\n\r\n**Does the format filter really work server-side?**\r\nYes. Google returns distinct result sets for `TEXT` (1), `IMAGE` (2), and `VIDEO` (3); the actor sends `3.4` and also enforces the format locally.\r\n\r\n**Why is `videoId` missing on some video ads?**\r\nGoogle only exposes the YouTube ID in some preview bundles. In our live probes about 80% of video creatives yielded an ID from the item preview or the detail preview; the rest had no `ytimg`/YouTube URL at all. Missing IDs are omitted rather than invented. `videoIdSource` tells you which preview produced the ID.\r\n\r\n**Why is `countryCode` different from the advertiser's country?**\r\n`countryCode` is the queried region sent to Google (the market whose ads you asked for). `advertiserCountryCode` is the advertiser's headquarters from Google's suggestions. `servedRegions` (with `includeVideoDetails`) lists the countries Google says the creative ran in.\r\n\r\n**What is the difference between blocked, empty, and partial?**\r\n`run_summary.status` is `blocked` when Google rate-limits/redirects the session, `empty` when the requests succeeded but no ads matched, `partial` when some advertisers/pages failed, and `success` when everything requested was collected. Per-advertiser rows also use `capped` when the per-advertiser or global cap stopped pagination and `filtered_empty` when returned creatives were all removed by the local date/format check. Blocked responses are not reported as empty results.\r\n\r\n**How far back does the data go?**\r\nGoogle's Transparency Center indexes ads from September 2023 onward and retains roughly the last year of commercial creatives; very old or low-volume creatives may not appear.\r\n\r\n**Is this affiliated with Google or YouTube?**\r\nNo. This is an independent actor that reads Google's publicly available Transparency Center data.\r\n",
    "actorDefinition": {
      "actorSpecification": 1,
      "name": "youtube-ad-creative-and-advertiser-tracker",
      "title": "YouTube Ad Creative & Advertiser Tracker",
      "description": "Pull YouTube ad creatives from Google's public Ads Transparency Center by advertiser, AR-ID, domain or keyword. Get media, video IDs, flight dates, regions, formats and advertiser records.",
      "version": "1.1",
      "buildTag": "latest",
      "meta": {
        "templateId": "python-empty"
      },
      "input": {
        "title": "YouTube Ads Scraper Input",
        "description": "Scrape YouTube ads from Google's Ads Transparency Center. Search by advertiser, keyword, or country, and export the results.",
        "type": "object",
        "schemaVersion": 1,
        "properties": {
          "advertisers": {
            "title": "Advertisers",
            "type": "array",
            "description": "Advertiser names, AR-IDs, Transparency Center URLs, or landing domains to scrape YouTube ads for (e.g. 'Nike, Inc.', 'AR16735076323512287233', 'nike.com'). Names are matched to the strongest suggestion (exact name first, then ad count). Leave empty to use searchTerms.",
            "editor": "stringList",
            "items": {
              "type": "string"
            }
          },
          "searchTerms": {
            "title": "Search Terms (keywords or domains)",
            "type": "array",
            "description": "Keywords or domains used to discover advertisers and domains, then scrape their YouTube ads (e.g. 'electric car', 'nike.com'). Keyword searches also use domain suggestions returned by Google.",
            "editor": "stringList",
            "items": {
              "type": "string"
            },
            "prefill": [
              "nike.com"
            ]
          },
          "countries": {
            "title": "Countries (queried regions)",
            "type": "array",
            "description": "ISO 3166-1 alpha-2 queried regions sent to the Transparency Center as the ad filter (e.g. US, GB). This is the region the ads were served in, not the advertiser's headquarters country. The advertiser's own country is reported separately as advertiserCountryCode.",
            "editor": "select",
            "items": {
              "type": "string",
              "enum": [
                "AD",
                "AE",
                "AG",
                "AI",
                "AL",
                "AM",
                "AO",
                "AQ",
                "AR",
                "AS",
                "AT",
                "AU",
                "AW",
                "AZ",
                "BA",
                "BB",
                "BD",
                "BE",
                "BF",
                "BG",
                "BH",
                "BI",
                "BJ",
                "BM",
                "BN",
                "BO",
                "BQ",
                "BR",
                "BS",
                "BT",
                "BV",
                "BW",
                "BY",
                "BZ",
                "CA",
                "CC",
                "CD",
                "CF",
                "CG",
                "CH",
                "CI",
                "CK",
                "CL",
                "CM",
                "CN",
                "CO",
                "CR",
                "CV",
                "CW",
                "CX",
                "CY",
                "CZ",
                "DE",
                "DJ",
                "DK",
                "DM",
                "DO",
                "DZ",
                "EC",
                "EE",
                "EG",
                "EH",
                "ER",
                "ES",
                "ET",
                "FI",
                "FJ",
                "FK",
                "FM",
                "FO",
                "FR",
                "GA",
                "GB",
                "GD",
                "GE",
                "GF",
                "GG",
                "GH",
                "GI",
                "GL",
                "GM",
                "GN",
                "GP",
                "GQ",
                "GR",
                "GS",
                "GT",
                "GU",
                "GW",
                "GY",
                "HK",
                "HM",
                "HN",
                "HR",
                "HT",
                "HU",
                "ID",
                "IE",
                "IL",
                "IM",
                "IN",
                "IO",
                "IQ",
                "IS",
                "IT",
                "JE",
                "JM",
                "JO",
                "JP",
                "KE",
                "KG",
                "KH",
                "KI",
                "KM",
                "KN",
                "KR",
                "KW",
                "KY",
                "KZ",
                "LA",
                "LB",
                "LC",
                "LI",
                "LK",
                "LR",
                "LS",
                "LT",
                "LU",
                "LV",
                "LY",
                "MA",
                "MC",
                "MD",
                "ME",
                "MG",
                "MH",
                "MK",
                "ML",
                "MM",
                "MN",
                "MO",
                "MP",
                "MQ",
                "MR",
                "MS",
                "MT",
                "MU",
                "MV",
                "MW",
                "MX",
                "MY",
                "MZ",
                "NA",
                "NC",
                "NE",
                "NF",
                "NG",
                "NI",
                "NL",
                "NO",
                "NP",
                "NR",
                "NU",
                "NZ",
                "OM",
                "PA",
                "PE",
                "PF",
                "PG",
                "PH",
                "PK",
                "PL",
                "PM",
                "PN",
                "PR",
                "PS",
                "PT",
                "PW",
                "PY",
                "QA",
                "RE",
                "RO",
                "RW",
                "SA",
                "SB",
                "SC",
                "SE",
                "SG",
                "SH",
                "SI",
                "SJ",
                "SK",
                "SL",
                "SM",
                "SN",
                "SO",
                "SR",
                "ST",
                "SV",
                "SX",
                "SZ",
                "TC",
                "TD",
                "TF",
                "TG",
                "TH",
                "TJ",
                "TK",
                "TL",
                "TM",
                "TN",
                "TO",
                "TR",
                "TT",
                "TV",
                "TW",
                "TZ",
                "UA",
                "UG",
                "UM",
                "US",
                "UY",
                "UZ",
                "VA",
                "VC",
                "VE",
                "VG",
                "VI",
                "VN",
                "VU",
                "WF",
                "WS",
                "YE",
                "YT",
                "ZA",
                "ZM",
                "ZW"
              ],
              "enumTitles": [
                "Andorra",
                "United Arab Emirates",
                "Antigua and Barbuda",
                "Anguilla",
                "Albania",
                "Armenia",
                "Angola",
                "Antarctica",
                "Argentina",
                "American Samoa",
                "Austria",
                "Australia",
                "Aruba",
                "Azerbaijan",
                "Bosnia and Herzegovina",
                "Barbados",
                "Bangladesh",
                "Belgium",
                "Burkina Faso",
                "Bulgaria",
                "Bahrain",
                "Burundi",
                "Benin",
                "Bermuda",
                "Brunei Darussalam",
                "Bolivia, Plurinational State of",
                "Bonaire, Sint Eustatius and Saba",
                "Brazil",
                "Bahamas",
                "Bhutan",
                "Bouvet Island",
                "Botswana",
                "Belarus",
                "Belize",
                "Canada",
                "Cocos (Keeling) Islands",
                "Congo, The Democratic Republic of the",
                "Central African Republic",
                "Congo",
                "Switzerland",
                "Côte d'Ivoire",
                "Cook Islands",
                "Chile",
                "Cameroon",
                "China",
                "Colombia",
                "Costa Rica",
                "Cabo Verde",
                "Curaçao",
                "Christmas Island",
                "Cyprus",
                "Czechia",
                "Germany",
                "Djibouti",
                "Denmark",
                "Dominica",
                "Dominican Republic",
                "Algeria",
                "Ecuador",
                "Estonia",
                "Egypt",
                "Western Sahara",
                "Eritrea",
                "Spain",
                "Ethiopia",
                "Finland",
                "Fiji",
                "Falkland Islands (Malvinas)",
                "Micronesia, Federated States of",
                "Faroe Islands",
                "France",
                "Gabon",
                "United Kingdom",
                "Grenada",
                "Georgia",
                "French Guiana",
                "Guernsey",
                "Ghana",
                "Gibraltar",
                "Greenland",
                "Gambia",
                "Guinea",
                "Guadeloupe",
                "Equatorial Guinea",
                "Greece",
                "South Georgia and the South Sandwich Islands",
                "Guatemala",
                "Guam",
                "Guinea-Bissau",
                "Guyana",
                "Hong Kong",
                "Heard Island and McDonald Islands",
                "Honduras",
                "Croatia",
                "Haiti",
                "Hungary",
                "Indonesia",
                "Ireland",
                "Israel",
                "Isle of Man",
                "India",
                "British Indian Ocean Territory",
                "Iraq",
                "Iceland",
                "Italy",
                "Jersey",
                "Jamaica",
                "Jordan",
                "Japan",
                "Kenya",
                "Kyrgyzstan",
                "Cambodia",
                "Kiribati",
                "Comoros",
                "Saint Kitts and Nevis",
                "Korea, Republic of",
                "Kuwait",
                "Cayman Islands",
                "Kazakhstan",
                "Lao People's Democratic Republic",
                "Lebanon",
                "Saint Lucia",
                "Liechtenstein",
                "Sri Lanka",
                "Liberia",
                "Lesotho",
                "Lithuania",
                "Luxembourg",
                "Latvia",
                "Libya",
                "Morocco",
                "Monaco",
                "Moldova, Republic of",
                "Montenegro",
                "Madagascar",
                "Marshall Islands",
                "North Macedonia",
                "Mali",
                "Myanmar",
                "Mongolia",
                "Macao",
                "Northern Mariana Islands",
                "Martinique",
                "Mauritania",
                "Montserrat",
                "Malta",
                "Mauritius",
                "Maldives",
                "Malawi",
                "Mexico",
                "Malaysia",
                "Mozambique",
                "Namibia",
                "New Caledonia",
                "Niger",
                "Norfolk Island",
                "Nigeria",
                "Nicaragua",
                "Netherlands",
                "Norway",
                "Nepal",
                "Nauru",
                "Niue",
                "New Zealand",
                "Oman",
                "Panama",
                "Peru",
                "French Polynesia",
                "Papua New Guinea",
                "Philippines",
                "Pakistan",
                "Poland",
                "Saint Pierre and Miquelon",
                "Pitcairn",
                "Puerto Rico",
                "Palestine, State of",
                "Portugal",
                "Palau",
                "Paraguay",
                "Qatar",
                "Réunion",
                "Romania",
                "Rwanda",
                "Saudi Arabia",
                "Solomon Islands",
                "Seychelles",
                "Sweden",
                "Singapore",
                "Saint Helena, Ascension and Tristan da Cunha",
                "Slovenia",
                "Svalbard and Jan Mayen",
                "Slovakia",
                "Sierra Leone",
                "San Marino",
                "Senegal",
                "Somalia",
                "Suriname",
                "Sao Tome and Principe",
                "El Salvador",
                "Sint Maarten (Dutch part)",
                "Eswatini",
                "Turks and Caicos Islands",
                "Chad",
                "French Southern Territories",
                "Togo",
                "Thailand",
                "Tajikistan",
                "Tokelau",
                "Timor-Leste",
                "Turkmenistan",
                "Tunisia",
                "Tonga",
                "Türkiye",
                "Trinidad and Tobago",
                "Tuvalu",
                "Taiwan, Province of China",
                "Tanzania, United Republic of",
                "Ukraine",
                "Uganda",
                "United States Minor Outlying Islands",
                "United States",
                "Uruguay",
                "Uzbekistan",
                "Holy See (Vatican City State)",
                "Saint Vincent and the Grenadines",
                "Venezuela, Bolivarian Republic of",
                "Virgin Islands, British",
                "Virgin Islands, U.S.",
                "Viet Nam",
                "Vanuatu",
                "Wallis and Futuna",
                "Samoa",
                "Yemen",
                "Mayotte",
                "South Africa",
                "Zambia",
                "Zimbabwe"
              ]
            },
            "prefill": [
              "US"
            ]
          },
          "dateFrom": {
            "title": "Shown during window: from (YYYY-MM-DD)",
            "type": "string",
            "description": "Keep ads whose observed flight overlaps this window. An ad is kept when firstShown <= dateTo and lastShown >= dateFrom, so ads that started earlier but were still running inside the window are included.",
            "editor": "datepicker",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "dateTo": {
            "title": "Shown during window: to (YYYY-MM-DD)",
            "type": "string",
            "description": "Keep ads whose observed flight overlaps this window (inclusive). Works together with dateFrom and is no longer compared only against firstShown.",
            "editor": "datepicker",
            "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
          },
          "format": {
            "title": "Ad format",
            "type": "string",
            "description": "Server-side creative format filter. TEXT, IMAGE and VIDEO map to Google's verified format codes 1, 2 and 3.",
            "editor": "select",
            "enum": [
              "all",
              "text",
              "image",
              "video"
            ],
            "enumTitles": [
              "All formats",
              "Text",
              "Image",
              "Video"
            ],
            "default": "all",
            "prefill": "all"
          },
          "includeVideoDetails": {
            "title": "Include creative detail enrichment",
            "type": "boolean",
            "description": "Fetch GetCreativeById for every creative to enrich last-shown dates, served regions and preview assets. Video IDs are resolved from previews even when this is off.",
            "default": false,
            "prefill": false
          },
          "resolveVideoIds": {
            "title": "Resolve YouTube video IDs from previews",
            "type": "boolean",
            "description": "Extract videoId, watch URL, thumbnail and duration from creative previews (ytimg/youtube URLs). Missing IDs are omitted, never fabricated. Turn off to save preview requests.",
            "default": true,
            "prefill": false
          },
          "maxAdvertisersPerTerm": {
            "title": "Max advertisers per search term",
            "type": "integer",
            "description": "Maximum advertiser matches (and domain suggestions) to scrape per keyword (when searchTerms is used).",
            "minimum": 1,
            "maximum": 50,
            "default": 5,
            "prefill": 5
          },
          "maxAdsPerAdvertiser": {
            "title": "Max ads per advertiser",
            "type": "integer",
            "description": "Cursor-pagination cap per advertiser or domain, applied before the global maxItems cap.",
            "minimum": 1,
            "maximum": 5000,
            "default": 100,
            "prefill": 3
          },
          "maxItems": {
            "title": "Max items",
            "type": "integer",
            "description": "Hard cap on total ad records returned (1-5000). Advertiser and run-summary records do not count toward this cap.",
            "minimum": 1,
            "maximum": 5000,
            "default": 100,
            "prefill": 3
          },
          "maxConcurrency": {
            "title": "Max concurrency",
            "type": "integer",
            "description": "Advertisers scraped in parallel. Higher is faster but increases rate-limit risk.",
            "minimum": 1,
            "maximum": 5,
            "default": 2,
            "prefill": 2
          },
          "onlyNew": {
            "title": "Only new ads (monitor mode)",
            "type": "boolean",
            "description": "Output only ad IDs not seen in earlier runs and mark them isNew: true. Reuse the same monitorStoreName for the same competitor list. The first run creates the baseline.",
            "default": false,
            "prefill": false
          },
          "monitorStoreName": {
            "title": "Monitor store name",
            "type": "string",
            "description": "Key-value store that remembers seen ad IDs for monitor mode (default: youtube-ads-monitor).",
            "default": "youtube-ads-monitor",
            "prefill": "youtube-ads-monitor",
            "editor": "textfield"
          },
          "outputFormat": {
            "title": "Output format",
            "type": "string",
            "description": "Dataset always receives JSON records. Additionally export results as CSV, Excel, or HTML in the key-value store (OUTPUT.csv / OUTPUT.xlsx / OUTPUT.html).",
            "editor": "select",
            "enum": [
              "json",
              "csv",
              "excel",
              "html"
            ],
            "enumTitles": [
              "JSON (dataset only)",
              "CSV (OUTPUT.csv)",
              "Excel (OUTPUT.xlsx)",
              "HTML (OUTPUT.html)"
            ],
            "default": "json",
            "prefill": "json"
          },
          "proxyConfiguration": {
            "title": "Proxy Configuration",
            "type": "object",
            "description": "Optional proxy. For moderate traffic no proxy is needed. Enable Apify proxy for high-volume scraping.",
            "editor": "proxy"
          }
        }
      },
      "output": {
        "actorOutputSchemaVersion": 1,
        "title": "YouTube Ad Creative & Advertiser Tracker Output",
        "description": "Dataset with one record per YouTube ad creative plus advertiser diagnostics and a run summary. Ad records include advertiser, queried region, format, thumbnail, YouTube video ID/watch URL/thumbnail/duration when exposed, first/last shown dates, days shown, and scrapedAt.",
        "properties": {
          "ads": {
            "type": "string",
            "title": "YouTube ad creatives, advertisers and run summary",
            "description": "Dataset containing ad records (recordType=ad), per-advertiser diagnostics (recordType=advertiser) and one run summary (recordType=run_summary).",
            "template": "{{links.apiDefaultDatasetUrl}}/items"
          }
        }
      },
      "dockerfile": "../Dockerfile",
      "readme": "# YouTube Ad Creative & Advertiser Tracker\r\n\r\nPull the ad creatives a brand is actually running on YouTube, straight from Google's public Ads Transparency Center. Hand it a keyword, a domain, an advertiser name, or an advertiser AR-ID and get back every matching ad creative with its thumbnail, format, queried region, flight dates, and — when Google exposes it — the YouTube `videoId`, watch URL, thumbnail, and duration.\r\n\r\n## What this actor does\r\n\r\n- **Four ways in:** advertiser names, AR-IDs, Transparency Center URLs, or landing domains\r\n- **Cursor pagination:** follows Google's `response.2` cursor back as `request.4` until `maxAdsPerAdvertiser` or `maxItems` is reached\r\n- **Server-side filters:** sends the queried region (`3.8`), format (`3.4`), and served-date window (`3.6`/`3.7`) to Google\r\n- **Correct date semantics:** keeps ads whose flight overlaps the requested window (`firstShown <= dateTo` and `lastShown >= dateFrom`), so `dateTo` no longer drops long-running ads\r\n- **YouTube metadata from previews:** resolves `videoId`, watch URL, `ytimg` thumbnail, and duration from `content.js` previews first, with `GetCreativeById` as a fallback\r\n- **Honest country fields:** `countryCode` is the queried region, `advertiserCountryCode` is the advertiser's headquarters, and `servedRegions` comes from Google's per-creative detail when enrichment is on\r\n- **Diagnostics:** distinguishes blocked, empty, filtered-empty and partial runs, and writes one `advertiser` record per target plus a `run_summary`\r\n- **Monitor mode:** `onlyNew` + `monitorStoreName` remembers seen ad IDs and outputs only new ads, marked `isNew: true`\r\n- **Multiple exports:** dataset JSON always, plus optional CSV, Excel, or HTML in the key-value store; every export includes `scrapedAt`\r\n\r\n## Dataset records\r\n\r\nEvery dataset item has a `recordType`:\r\n\r\n- `ad` — one YouTube ad creative (the main records)\r\n- `advertiser` — one row per resolved advertiser/domain with status, pages fetched, and ads collected\r\n- `run_summary` — one row per run with overall status, counts, filters, and diagnostics\r\n\r\n### Ad fields\r\n\r\n- `adId` — Google creative ID (e.g. `CR09196456782480801793`)\r\n- `advertiserId`, `advertiserName` — Google advertiser identity\r\n- `advertiserCountryCode` — advertiser headquarters country from suggestions, when known\r\n- `countryCode`, `queriedRegions` — region(s) used for the ad request (e.g. `US`, `anywhere`)\r\n- `servedRegions` — countries where the creative was served (normally from `includeVideoDetails`; may also appear when preview resolution triggers a detail fetch)\r\n- `format`, `mediaType` — `TEXT`/`image` mapping from Google's verified codes `1/2/3`\r\n- `imageUrl`, `imageWidth`, `imageHeight` — archived screenshot/thumbnail\r\n- `previewUrl` — Google's `content.js` preview bundle\r\n- `videoId` — YouTube video ID from a preview (`ytimg`/YouTube URL); omitted when Google does not expose it\r\n- `videoUrl` — direct `googlevideo.com` media URL when the creative exposes one (baseline-compatible)\r\n- `videoPageUrl` — `https://www.youtube.com/watch?v=<videoId>`\r\n- `landingUrl` — advertiser click URL decoded from the creative overlay when present\r\n- `videoThumbnailUrl` — `ytimg.com` thumbnail found in the preview\r\n- `videoDurationSeconds` — duration parsed from the preview (`dur=` or VAST)\r\n- `videoIdSource` — e.g. `preview:ytimg`, `detail-preview:youtube`, `item:ytimg`\r\n- `firstShown`, `lastShown` — observed flight timestamps\r\n- `daysShown` — inclusive days between first and last shown\r\n- `lastShownAgeDays` — days since `lastShown` at scrape time\r\n- `adCount`, `searchTerm`, `sourceUrl`, `scrapedAt`\r\n- `isNew` — only present in monitor mode\r\n\r\n## Input\r\n\r\n| Field | Type | Default | Description |\r\n|-------|------|---------|-------------|\r\n| `advertisers` | array | — | Advertiser names, AR-IDs, Transparency URLs, or domains (e.g. `Nike, Inc.`, `AR16735076323512287233`, `nike.com`). Names are matched to the strongest suggestion: exact name first, then prefix/containment, then ad count. |\r\n| `searchTerms` | array | — | Keywords or domains used to discover advertisers and domain suggestions before scraping. |\r\n| `countries` | array | — | Queried ISO-2 regions sent to Google. This is the ad-serving region, not the advertiser's HQ country. |\r\n| `dateFrom` | string | — | Flight-overlap window start (`YYYY-MM-DD`). |\r\n| `dateTo` | string | — | Flight-overlap window end (`YYYY-MM-DD`). Works correctly even when the ad started earlier. |\r\n| `format` | string | `all` | `all`, `text`, `image`, or `video`. Sent server-side as Google format codes `1/2/3`. |\r\n| `includeVideoDetails` | boolean | `false` | Fetch `GetCreativeById` for every creative to enrich last-shown dates, served regions, images, and preview fallbacks. |\r\n| `resolveVideoIds` | boolean | `true` | Resolve video metadata from previews. Missing IDs are omitted, never fabricated. |\r\n| `maxAdvertisersPerTerm` | integer | `5` | Advertiser matches (and domain suggestions) per keyword. |\r\n| `maxAdsPerAdvertiser` | integer | `100` | Cursor-pagination cap per advertiser/domain. |\r\n| `maxItems` | integer | `100` | Global ad-record cap (1–5000). Advertiser and summary records do not count. |\r\n| `maxConcurrency` | integer | `2` | Advertisers scraped in parallel (1–5). |\r\n| `onlyNew` | boolean | `false` | Monitor mode: output only ad IDs not seen in earlier runs. |\r\n| `monitorStoreName` | string | `youtube-ads-monitor` | Key-value store that remembers seen ad IDs for monitor mode. |\r\n| `outputFormat` | string | `json` | Also export `OUTPUT.csv`, `OUTPUT.xlsx`, or `OUTPUT.html`. |\r\n| `proxyConfiguration` | object | — | Optional Apify proxy for higher-volume runs. |\r\n\r\nAt least one of `advertisers` or `searchTerms` is required.\r\n\r\n### Example: discover by keyword or domain\r\n\r\n```json\r\n{\r\n  \"searchTerms\": [\"nike.com\", \"electric car\"],\r\n  \"countries\": [\"US\"],\r\n  \"format\": \"video\",\r\n  \"maxAdvertisersPerTerm\": 5,\r\n  \"maxAdsPerAdvertiser\": 100,\r\n  \"maxItems\": 200\r\n}\r\n```\r\n\r\n### Example: pull a known advertiser directly\r\n\r\n```json\r\n{\r\n  \"advertisers\": [\"AR16735076323512287233\"],\r\n  \"countries\": [\"US\", \"GB\"],\r\n  \"dateFrom\": \"2026-01-01\",\r\n  \"dateTo\": \"2026-10-31\",\r\n  \"maxAdsPerAdvertiser\": 150,\r\n  \"maxItems\": 300\r\n}\r\n```\r\n\r\n### Example: monitor a competitor for new ads\r\n\r\n```json\r\n{\r\n  \"advertisers\": [\"Nike, Inc.\"],\r\n  \"countries\": [\"US\"],\r\n  \"format\": \"video\",\r\n  \"onlyNew\": true,\r\n  \"monitorStoreName\": \"nike-youtube-monitor\",\r\n  \"maxAdsPerAdvertiser\": 100\r\n}\r\n```\r\n\r\nRun once to establish the baseline. Schedule the same input; later runs output only new ad IDs with `isNew: true` and still write the advertiser/run-summary diagnostics.\r\n\r\n### Example: window with preview-resolved video IDs\r\n\r\n```json\r\n{\r\n  \"searchTerms\": [\"nike\"],\r\n  \"countries\": [\"US\"],\r\n  \"dateFrom\": \"2026-01-01\",\r\n  \"dateTo\": \"2026-06-30\",\r\n  \"format\": \"video\",\r\n  \"includeVideoDetails\": true,\r\n  \"outputFormat\": \"csv\"\r\n}\r\n```\r\n\r\n## Use cases\r\n\r\n- **Competitive ad monitoring** — see which creatives a rival is running now\r\n- **Creative swipe files** — collect thumbnails, formats, durations, and video IDs\r\n- **Flight tracking** — compare `firstShown`/`lastShown`/`daysShown` across campaigns\r\n- **Agency reporting** — export to CSV/Excel with `scrapedAt` for provenance\r\n- **Market scans** — run a keyword or domain across multiple queried regions\r\n\r\n## FAQ and hard limits\r\n\r\n**Where does this data come from?**\r\nGoogle's public Ads Transparency Center, filtered to YouTube creatives. No login or API key is required.\r\n\r\n**How many creatives can one advertiser return?**\r\nMore than 40. The actor follows the server cursor (`response.2` → `request.4`) and pages until `maxAdsPerAdvertiser`/`maxItems` or Google stops returning a cursor. Large advertisers can return thousands of creatives.\r\n\r\n**Do the date filters really work server-side?**\r\nYes. `dateFrom`/`dateTo` are sent as `3.6`/`3.7` in `YYYYMMDD` form. The server applies a flight-overlap filter; the actor re-checks the same overlap locally. `dateTo` is no longer compared only against `firstShown`.\r\n\r\n**Does the format filter really work server-side?**\r\nYes. Google returns distinct result sets for `TEXT` (1), `IMAGE` (2), and `VIDEO` (3); the actor sends `3.4` and also enforces the format locally.\r\n\r\n**Why is `videoId` missing on some video ads?**\r\nGoogle only exposes the YouTube ID in some preview bundles. In our live probes about 80% of video creatives yielded an ID from the item preview or the detail preview; the rest had no `ytimg`/YouTube URL at all. Missing IDs are omitted rather than invented. `videoIdSource` tells you which preview produced the ID.\r\n\r\n**Why is `countryCode` different from the advertiser's country?**\r\n`countryCode` is the queried region sent to Google (the market whose ads you asked for). `advertiserCountryCode` is the advertiser's headquarters from Google's suggestions. `servedRegions` (with `includeVideoDetails`) lists the countries Google says the creative ran in.\r\n\r\n**What is the difference between blocked, empty, and partial?**\r\n`run_summary.status` is `blocked` when Google rate-limits/redirects the session, `empty` when the requests succeeded but no ads matched, `partial` when some advertisers/pages failed, and `success` when everything requested was collected. Per-advertiser rows also use `capped` when the per-advertiser or global cap stopped pagination and `filtered_empty` when returned creatives were all removed by the local date/format check. Blocked responses are not reported as empty results.\r\n\r\n**How far back does the data go?**\r\nGoogle's Transparency Center indexes ads from September 2023 onward and retains roughly the last year of commercial creatives; very old or low-volume creatives may not appear.\r\n\r\n**Is this affiliated with Google or YouTube?**\r\nNo. This is an independent actor that reads Google's publicly available Transparency Center data.\r\n",
      "storages": {
        "dataset": {
          "actorSpecification": 1,
          "title": "YouTube Ads",
          "fields": {
            "type": "object",
            "properties": {
              "recordType": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Record kind: ad, advertiser or run_summary"
              },
              "adId": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Google creative ID (CR...)"
              },
              "advertiserId": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Google advertiser ID (AR...)"
              },
              "advertiserName": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Advertiser display name from Google"
              },
              "advertiserCountryCode": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Advertiser headquarters country from SearchSuggestions (not the queried region)"
              },
              "countryCode": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Queried region(s) used for the ad request, e.g. US or anywhere"
              },
              "queriedRegions": {
                "type": [
                  "array",
                  "null"
                ],
                "description": "List of ISO-2 queried regions"
              },
              "servedRegions": {
                "type": [
                  "array",
                  "null"
                ],
                "description": "Countries where Google reports the creative was served (requires detail enrichment)"
              },
              "format": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Ad format: TEXT / IMAGE / VIDEO (Google codes 1/2/3)"
              },
              "mediaType": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "text / image / video"
              },
              "imageUrl": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Ad thumbnail / archived screenshot URL"
              },
              "imageWidth": {
                "type": [
                  "integer",
                  "null"
                ],
                "description": "Media width in pixels"
              },
              "imageHeight": {
                "type": [
                  "integer",
                  "null"
                ],
                "description": "Media height in pixels"
              },
              "previewUrl": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Creative preview bundle URL (content.js)"
              },
              "videoId": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "YouTube video ID resolved from the creative preview (omitted when not exposed)"
              },
              "videoUrl": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Direct googlevideo media URL when exposed by the creative"
              },
              "videoPageUrl": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "YouTube watch URL for videoId"
              },
              "landingUrl": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Advertiser click URL decoded from the creative overlay when present"
              },
              "videoThumbnailUrl": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "ytimg.com thumbnail found in the creative preview"
              },
              "videoDurationSeconds": {
                "type": [
                  "number",
                  "null"
                ],
                "description": "Video duration in seconds parsed from the preview"
              },
              "videoIdSource": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Where the video ID came from, e.g. preview:ytimg or detail-preview:youtube"
              },
              "firstShown": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "First shown timestamp (ISO 8601)"
              },
              "lastShown": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Last shown timestamp (ISO 8601)"
              },
              "daysShown": {
                "type": [
                  "integer",
                  "null"
                ],
                "description": "Inclusive days between firstShown and lastShown"
              },
              "lastShownAgeDays": {
                "type": [
                  "integer",
                  "null"
                ],
                "description": "Days since lastShown relative to the scrape date"
              },
              "adCount": {
                "type": [
                  "integer",
                  "null"
                ],
                "description": "Advertiser total ad count reported on the creative"
              },
              "adCountMin": {
                "type": [
                  "integer",
                  "null"
                ],
                "description": "Lower bound of Google's advertiser ad-count range"
              },
              "adCountMax": {
                "type": [
                  "integer",
                  "null"
                ],
                "description": "Upper bound of Google's advertiser ad-count range"
              },
              "searchTerm": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Keyword or domain that discovered this ad"
              },
              "domain": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Landing domain used for discovery"
              },
              "discoveryMethod": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "advertiser-id / advertiser-name / domain-input / domain-query / keyword-advertiser / keyword-domain"
              },
              "status": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Run or per-advertiser status: success, capped, partial, blocked, empty, filtered_empty, error, skipped, no_new_ads or no_advertisers_found"
              },
              "adsCollected": {
                "type": [
                  "integer",
                  "null"
                ],
                "description": "Ads collected for this advertiser"
              },
              "pagesFetched": {
                "type": [
                  "integer",
                  "null"
                ],
                "description": "SearchCreatives pages fetched"
              },
              "error": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Diagnostic error for this advertiser"
              },
              "isNew": {
                "type": [
                  "boolean",
                  "null"
                ],
                "description": "Monitor mode: ad was not seen in an earlier run"
              },
              "sourceUrl": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "Ads Transparency Center detail URL"
              },
              "scrapedAt": {
                "type": [
                  "string",
                  "null"
                ],
                "description": "ISO 8601 scrape timestamp (also included in exports)"
              }
            }
          },
          "views": {
            "overview": {
              "title": "YouTube Ads Overview",
              "transformation": {
                "fields": [
                  "recordType",
                  "advertiserName",
                  "countryCode",
                  "format",
                  "firstShown",
                  "lastShown",
                  "imageUrl",
                  "videoId",
                  "videoUrl",
                  "videoPageUrl"
                ]
              },
              "display": {
                "component": "table",
                "properties": {
                  "recordType": {
                    "label": "Record",
                    "format": "text"
                  },
                  "advertiserName": {
                    "label": "Advertiser",
                    "format": "text"
                  },
                  "countryCode": {
                    "label": "Queried region",
                    "format": "text"
                  },
                  "format": {
                    "label": "Format",
                    "format": "text"
                  },
                  "firstShown": {
                    "label": "First shown",
                    "format": "text"
                  },
                  "lastShown": {
                    "label": "Last shown",
                    "format": "text"
                  },
                  "imageUrl": {
                    "label": "Media",
                    "format": "image"
                  },
                  "videoId": {
                    "label": "Video ID",
                    "format": "text"
                  },
                  "videoPageUrl": {
                    "label": "Video",
                    "format": "link"
                  }
                }
              }
            }
          }
        }
      }
    },
    "buildNumber": "1.1.1",
    "imageDigest": "9f3e659fffddc38d2e88bdfa299eb0faf5f51686d8f2b1e08f62041434a98650",
    "actVersion": {
      "sourceType": "SOURCE_FILES",
      "buildTag": "latest",
      "versionNumber": "1.1"
    },
    "usage": {
      "ACTOR_COMPUTE_UNITS": 0.012443333333333334
    }
  }
}