{
  "openapi": "3.0.1",
  "info": {
    "title": "Google Ads Transparency Scraper & Competitor Ad Monitor",
    "description": "Competitor ad monitor: only the new Google ads your competitors started running, daily or weekly. Google Ads checker: does a website run Google ads? Bulk check domains running Google ads, yes or no per domain. Google Ads Transparency data by brand, domain or ID. Search ad text by OCR.",
    "version": "0.7",
    "x-build-id": "pdCvzBnTKbYWJEkT9"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/solidfetch~google-ads-transparency-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-solidfetch-google-ads-transparency-scraper",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    },
    "/acts/solidfetch~google-ads-transparency-scraper/runs": {
      "post": {
        "operationId": "runs-sync-solidfetch-google-ads-transparency-scraper",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor and returns information about the initiated run in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/runsResponseSchema"
                }
              }
            }
          }
        }
      }
    },
    "/acts/solidfetch~google-ads-transparency-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-solidfetch-google-ads-transparency-scraper",
        "x-openai-isConsequential": false,
        "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
        "tags": [
          "Run Actor"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inputSchema"
              }
            }
          }
        },
        "parameters": [
          {
            "name": "token",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Enter your Apify token here"
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "inputSchema": {
        "type": "object",
        "properties": {
          "search": {
            "title": "Search: brand, domain or advertiser",
            "type": "array",
            "description": "What to look up. One entry per line: a brand name (Nike), a domain or website (nike.com), an advertiser ID (AR16735076323512287233) or an advertiser page URL from adstransparency.google.com. The type is detected for you, so brands, domains and IDs can be mixed. Through the API you can also send one text separated by commas or line breaks (a name with a comma, such as \"Nike, Inc.\", goes on its own line). Ads mode: the ads of each entry. Domain check: the domains. Advertiser lookup: the names and domains. The separate lists below still work and are added to this one.",
            "items": {
              "type": "string"
            }
          },
          "mode": {
            "title": "What to get",
            "enum": [
              "ads",
              "domainCheck",
              "advertisers"
            ],
            "type": "string",
            "description": "Ads: every ad of the brands, domains or advertiser IDs below, charged per ad. Domain check: one row per domain in the domains in the search box saying whether it advertises on Google, with up to 5 advertisers, the rounded ad count, the most recent shown date and the formats seen, charged per domain. Domain check uses only Domains and Country. Advertiser lookup: one row per advertiser account that matches a name in the search box or runs ads for a domain in the domains in the search box, with its ID, country, rounded ad count and the account the Ads mode would pick, charged per advertiser. Advertiser lookup uses only names, Domains and Country.",
            "default": "ads"
          },
          "region": {
            "title": "Country",
            "type": "string",
            "description": "Country code (ISO 3166-1, e.g. US, PL, DE) or English country name (e.g. Poland, United Kingdom). The form starts with US; clear it for all countries (the API default when the field is missing). Domain check: whether the domain has ads shown in this country. Advertiser lookup: the best match prefers an advertiser from this country, and a domain lists the advertisers of ads shown here."
          },
          "maxAds": {
            "title": "Max ads per search",
            "minimum": 1,
            "maximum": 100000,
            "type": "integer",
            "description": "Each name, the ID list and each domain stop after this many ads. Ads found by an earlier search are not saved or charged again. When left empty, each search stops at 100 ads and the log says so. Set it when you start the actor from Clay, Make or another tool, together with the maximum cost per run."
          },
          "advertiserNames": {
            "title": "Brand or advertiser names",
            "type": "array",
            "description": "One search per name, for example Nike, Allegro, Temu. The actor picks the matching advertiser with the most ads, or the brand's domain when the ads run under another legal name. Names that differ only in case or punctuation are searched once. Advertiser lookup: every advertiser whose name contains the name, up to 500 names and domains per run. To paste a column from a spreadsheet, use \"Names as text\" below.",
            "items": {
              "type": "string"
            }
          },
          "advertiserNamesText": {
            "title": "Names as text",
            "type": "string",
            "description": "The same as \"Brand or advertiser names\", pasted as one text: one name per line, or names separated by commas when there is no line break. A name with a comma goes on its own line. Meant for tools such as Clay and Google Sheets that send a whole column as one value."
          },
          "domains": {
            "title": "Domains",
            "type": "array",
            "description": "Ads: one search per domain, ads from every advertiser that sends traffic there, for example nike.com. Domain check: the list of domains to check, up to 10,000 per run, one row each with your value in \"input\". Advertiser lookup: the advertisers whose ads lead to the domain. Full URLs work too; the scheme, path and www. are removed, internationalised names are saved as punycode and duplicates are checked once. IP addresses, e-mail addresses and names without a public suffix are not domains: domain check returns a free row with an error for them. To paste a column from a spreadsheet, use \"Domains as text\" below.",
            "items": {
              "type": "string"
            }
          },
          "domainsText": {
            "title": "Domains as text",
            "type": "string",
            "description": "The same as \"Domains\", pasted as one text: separated by line breaks, spaces, commas or semicolons. Meant for tools such as Clay and Google Sheets that send a whole column as one value."
          },
          "advertiserIds": {
            "title": "Advertiser IDs",
            "type": "array",
            "description": "Advertiser IDs (AR followed by 20 digits) or advertiser page URLs from the Transparency Center. All IDs are searched together. An ID that is not valid is skipped and saved as a free row with the reason; the valid ones are still searched.",
            "items": {
              "type": "string"
            }
          },
          "startUrls": {
            "title": "Transparency Center URLs",
            "type": "array",
            "description": "Links copied from adstransparency.google.com: an advertiser page or a creative page (that advertiser is searched, joined with the IDs above) and a domain search page (that domain is searched). A link with a country (region=PL) sets Country when it is empty. Anything else is skipped and saved as a free row.",
            "items": {
              "type": "object",
              "required": [
                "url"
              ],
              "properties": {
                "url": {
                  "type": "string",
                  "title": "URL of a web page",
                  "format": "uri"
                }
              }
            }
          },
          "dateFrom": {
            "title": "Shown from",
            "type": "string",
            "description": "Only ads shown at some point on or after this date (YYYY-MM-DD). An ad that started earlier and still ran after it is included. For ads that are new since a date, use onlyNewSinceLastRun."
          },
          "dateTo": {
            "title": "Shown until",
            "type": "string",
            "description": "Only ads shown at some point on or before this date (YYYY-MM-DD)."
          },
          "shownInLastDays": {
            "title": "Shown in the last N days",
            "minimum": 1,
            "maximum": 364,
            "type": "integer",
            "description": "Only ads shown at some point in the last N days, today included (1 to 364). This is not the same as ads that started in that window; for new ads use onlyNewSinceLastRun. Use it instead of the two dates in saved tasks and schedules, so the range moves with every run."
          },
          "format": {
            "title": "Ad format",
            "enum": [
              "ALL",
              "TEXT",
              "IMAGE",
              "VIDEO"
            ],
            "type": "string",
            "description": "Keep only ads of one format: TEXT (search text ads), IMAGE (display and shopping image ads), VIDEO (YouTube and video ads) or ALL for every format. Ads of other formats are skipped before saving, so they are not charged. Use VIDEO together with video links to collect the YouTube links of a brand's video ads.",
            "default": "ALL"
          },
          "platform": {
            "title": "Platform",
            "enum": [
              "ALL",
              "SEARCH",
              "YOUTUBE",
              "SHOPPING",
              "MAPS",
              "PLAY"
            ],
            "type": "string",
            "description": "Only ads Google showed on this platform: Google Search, YouTube, Google Shopping, Google Maps or Google Play.",
            "default": "ALL"
          },
          "minDaysShown": {
            "title": "Only ads shown at least N days",
            "minimum": 1,
            "maximum": 3650,
            "type": "integer",
            "description": "Ads mode only. Keep only ads Google served for at least this many days (the daysShown column), to find the ads advertisers keep running. Ads below it are not saved and not charged; ads with an unknown number of days are left out too. Every ad also has isLongRunning (true from 30 days). Google lists the most recently shown ads first, so raise Max ads per search to look deeper for old ones."
          },
          "onlyWithProducts": {
            "title": "Only ads with product data",
            "type": "boolean",
            "description": "Keep only shopping ads that come with product titles and prices. Other ads are skipped before saving, so they are not charged. Max ads then counts the ads kept.",
            "default": false
          },
          "videoLinks": {
            "title": "YouTube links for video ads",
            "type": "boolean",
            "description": "Adds videoUrl and thumbnailUrl to video ads by reading one preview file per video ad. When left empty, it is on for the Video format and off for the others."
          },
          "previewImages": {
            "title": "Pictures for image ads",
            "type": "boolean",
            "description": "Fills imageUrl for image ads that Google only shows through a preview, by reading one preview file per such ad (about 0.2 MB each, 4 at a time). Turn it off for the fastest run. When left empty, it is on.",
            "default": true
          },
          "includeAdText": {
            "title": "Ad text (headline, description, call to action)",
            "type": "boolean",
            "description": "Adds headline, longHeadline, description, displayUrl, callToAction, landingUrls and adTextStatus by reading the preview file of video and image ads (4 at a time; a preview already read for the picture or the YouTube link is not read again). On by default. The extra cost is one request per video ad that is not already read, for the first \"Ad text for the first N ads\" ads of the run. Search text ads that Google archives as a picture have no text unless \"Read search text ads with OCR\" is on. Same price per ad.",
            "default": true
          },
          "adTextLimit": {
            "title": "Ad text for the first N ads",
            "minimum": 0,
            "maximum": 100000,
            "type": "integer",
            "description": "Caps how many ads of a run have their preview read for ad text, so a run of thousands of ads does not get slower. Later ads are saved with adTextStatus \"not-fetched\". Set 0 to read every ad.",
            "default": 50
          },
          "readTextAdsWithOcr": {
            "title": "Read search text ads with OCR",
            "type": "boolean",
            "description": "Off by default. Google keeps a classic search text ad only as a picture, so without this option its headline, description and displayUrl are null. With it on, each such picture is downloaded and read with OCR (one at a time on the default 256 MB memory), the three fields are filled, and the row says adTextSource \"ocr\". OCR is not exact: it can drop or change words and it reads English best, so accented letters and symbols are often wrong. A text ad picture shows no landing page, so landingUrl stays null. A picture that cannot be read leaves the text null and adTextOcrError says why. \"Ad text for the first N ads\" also caps the pictures read. No extra charge: same price per ad.",
            "default": false
          },
          "adDetails": {
            "title": "EU ad details (impressions, targeting, countries)",
            "type": "boolean",
            "description": "Adds impressionsMin, impressionsMax, targeting and regionStats (per-country first and last shown dates and impression ranges) by reading each ad's detail page. Google publishes impressions and targeting for ads shown in the EU and a few other European countries. Costs one extra request per ad, so runs take longer.",
            "default": false
          },
          "flattenRegions": {
            "title": "Flat columns per country (with EU ad details)",
            "type": "boolean",
            "description": "Needs \"EU ad details\". Adds flat columns for each country in the ad's regionStats, only for the countries that ad ran in: impressions_DE_min, impressions_DE_max, shown_DE_first and shown_DE_last (DE stands for any two-letter country code). Meant for per-country tables in Sheets and slides. regionStats stays in the row. Ads that ran in different countries have different columns.",
            "default": false
          },
          "downloadCreatives": {
            "title": "Download the ad images",
            "type": "boolean",
            "description": "Saves the image of each ad (the archived ad image or the picture from its preview) as a file in the run's key-value store and adds its link as creativeFileUrl. Video ads keep their YouTube link, the video itself is not downloaded. Each stored file is charged as one creative-file event on top of the ad. Files over 5 MB and failed downloads are skipped and not charged.",
            "default": false
          },
          "overviewOnly": {
            "title": "Preview only: advertiser overview",
            "type": "boolean",
            "description": "Ads mode. Saves one free overview row per name, domain or ID list instead of the ads: Google's rounded total of ads, ads per format and ads shown in the last 30 days in the first page of results, the first and last shown dates, and the estimated cost of saving all ads at your current price per ad. Nothing is charged for ads. Uses one page of results per search; Max ads per search and the ad options are not used. Cannot be combined with Only ads new since the last run.",
            "default": false
          },
          "detailed": {
            "title": "Detailed domain check",
            "type": "boolean",
            "description": "Domain check only. Adds last30DaysFormatCounts to each row: the ads on the fetched page that were shown in the last 30 days, counted by format (text, image, video). adsLast30Days is always in the row. Google does not say on which channel (Search, YouTube, Shopping, Display, Play) an ad ran in the list this check reads, so there is no channel split.",
            "default": false
          },
          "onlyNewSinceLastRun": {
            "title": "Only ads new since the last run",
            "type": "boolean",
            "description": "For scheduled runs: save only ads this search has not returned before. The first run saves every matching ad as the baseline, free of charge. Ads seen by earlier runs are skipped and not charged. Google lists the most recently shown ads first, so Max ads per search is how deep each run looks.",
            "default": false
          },
          "monitorName": {
            "title": "Monitor name",
            "type": "string",
            "description": "Optional. Runs with the same name share the list of ads already seen. With Watch the domains for changes it is required: runs with the same name share the last answer of each domain. Leave empty to get one list per search: the names, domains, IDs, country and format. Letters, digits and !-_.'() only."
          },
          "includeLastShownChanges": {
            "title": "Also ads whose last-shown date moved",
            "type": "boolean",
            "description": "Also save ads seen before whose last-shown date is later than in the last run, that is ads still running. These rows have changeType lastShownChanged and previousLastShown.",
            "default": false
          },
          "webhookUrl": {
            "title": "Webhook URL for the digest",
            "type": "string",
            "description": "Optional, with \"Only ads new since the last run\" or Watch the domains for changes. At the end of a run with new ads (or, for a domain watch, with changed domains), one JSON digest is posted here: per search the number of new ads and up to 5 sample ads (advertiser, format, first shown, link), plus a Slack-ready text field. Works with a Slack incoming webhook or any URL that accepts a JSON POST. A failed post never fails the run: it is logged as a warning and reported in the run's status message. Nothing is posted for a run without new ads, unless the next option is on."
          },
          "webhookOnEmpty": {
            "title": "Post the digest also when no ad is new",
            "type": "boolean",
            "description": "Posts the digest at the end of every run, also when it found no new ads and on the first (baseline) run. Needs a webhook URL.",
            "default": false
          },
          "monitorGroups": {
            "title": "Monitor several clients in one run",
            "type": "array",
            "description": "Optional, an alternative to the search fields above: a list of groups, one per client, for example [{\"name\": \"Client A\", \"domains\": [\"rival.com\"], \"advertiserNames\": [\"Rival Inc\"], \"advertiserIds\": []}]. Each group is a monitor of its own (its own list of seen ads, free first run, summary rows and webhook digest), checked one after the other with the country, dates, format and max ads set above. Turns \"Only ads new since the last run\" on. Up to 20 groups; leave the Search box and the brand, domain and ID fields empty when you use it. Rows and the digest carry the group name as clientName."
          },
          "watchChanges": {
            "title": "Watch the domains for changes",
            "type": "boolean",
            "description": "Domain check only, for scheduled runs. Every row gets change (started-advertising, stopped-advertising, owner-changed, unchanged or first-check) compared with the previous run that used the same Monitor name, plus previousOwner and previousCheckedAt. Needs a Monitor name. The first run saves the answers as the baseline (first-check). \"Stopped advertising\" means no ad is shown in the Transparency Center now, with Google's data delay. Charging is the same as a domain check: a domain with ads is charged, one without is free.",
            "default": false
          },
          "onlyChanges": {
            "title": "Save only domains that changed",
            "type": "boolean",
            "description": "Domain check with Watch the domains for changes. On by default: domains whose answer did not change are left out of the dataset, so they are not charged. Turn it off to get a row for every domain; domains with ads are then charged as in a plain domain check.",
            "default": true
          },
          "proxyConfiguration": {
            "title": "Proxy",
            "type": "object",
            "description": "Google answers with a CAPTCHA page when one IP sends many requests. The actor then switches to a new proxy IP and retries. With the default Apify Proxy, the first CAPTCHA moves the run to Apify residential proxy when the run has access to it. Apify Proxy is recommended.",
            "default": {
              "useApifyProxy": true
            }
          }
        }
      },
      "runsResponseSchema": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "actId": {
                "type": "string"
              },
              "userId": {
                "type": "string"
              },
              "startedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "finishedAt": {
                "type": "string",
                "format": "date-time",
                "example": "2025-01-08T00:00:00.000Z"
              },
              "status": {
                "type": "string",
                "example": "READY"
              },
              "meta": {
                "type": "object",
                "properties": {
                  "origin": {
                    "type": "string",
                    "example": "API"
                  },
                  "userAgent": {
                    "type": "string"
                  }
                }
              },
              "stats": {
                "type": "object",
                "properties": {
                  "inputBodyLen": {
                    "type": "integer",
                    "example": 2000
                  },
                  "rebootCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "restartCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "resurrectCount": {
                    "type": "integer",
                    "example": 0
                  },
                  "computeUnits": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "options": {
                "type": "object",
                "properties": {
                  "build": {
                    "type": "string",
                    "example": "latest"
                  },
                  "timeoutSecs": {
                    "type": "integer",
                    "example": 300
                  },
                  "memoryMbytes": {
                    "type": "integer",
                    "example": 1024
                  },
                  "diskMbytes": {
                    "type": "integer",
                    "example": 2048
                  }
                }
              },
              "buildId": {
                "type": "string"
              },
              "defaultKeyValueStoreId": {
                "type": "string"
              },
              "defaultDatasetId": {
                "type": "string"
              },
              "defaultRequestQueueId": {
                "type": "string"
              },
              "buildNumber": {
                "type": "string",
                "example": "1.0.0"
              },
              "containerUrl": {
                "type": "string"
              },
              "usage": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "integer",
                    "example": 1
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              },
              "usageTotalUsd": {
                "type": "number",
                "example": 0.00005
              },
              "usageUsd": {
                "type": "object",
                "properties": {
                  "ACTOR_COMPUTE_UNITS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATASET_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "KEY_VALUE_STORE_WRITES": {
                    "type": "number",
                    "example": 0.00005
                  },
                  "KEY_VALUE_STORE_LISTS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_READS": {
                    "type": "integer",
                    "example": 0
                  },
                  "REQUEST_QUEUE_WRITES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_INTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "DATA_TRANSFER_EXTERNAL_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_SERPS": {
                    "type": "integer",
                    "example": 0
                  },
                  "PROXY_UNBLOCKER_UNITS": {
                    "type": "integer",
                    "example": 0
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}