{
  "openapi": "3.0.1",
  "info": {
    "title": "Google Ads Transparency Scraper & Change Monitor",
    "description": "Extract every live Google ad creative for any advertiser: image, video and text, with real asset URLs and first/last-seen dates. See what a competitor launched and stopped since your last run. Domain search catches every ad account, incl. agencies. A zero-ad run is never silent: the log says why.",
    "version": "0.1",
    "x-build-id": "1ESpX3KceXdGoDeKd"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/broken-not-dead~google-ads-transparency-scraper-change-monitor/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-broken-not-dead-google-ads-transparency-scraper-change-monitor",
        "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/broken-not-dead~google-ads-transparency-scraper-change-monitor/runs": {
      "post": {
        "operationId": "runs-sync-broken-not-dead-google-ads-transparency-scraper-change-monitor",
        "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/broken-not-dead~google-ads-transparency-scraper-change-monitor/run-sync": {
      "post": {
        "operationId": "run-sync-broken-not-dead-google-ads-transparency-scraper-change-monitor",
        "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",
        "required": [
          "queries"
        ],
        "properties": {
          "queries": {
            "title": "Advertiser domains or names",
            "type": "array",
            "description": "One per line. A domain (nike.com) is strongly preferred — it returns ads from EVERY advertiser account promoting that domain, including media agencies and resellers. A brand name (Nike) is matched to the highest-volume advertiser accounts instead. The default pair is a demo: nike.com is huge (you will see the honest partial-scan warning), brewdog.com is small enough to scan fully — run it twice and the second run labels real launches and pauses.",
            "default": [
              "nike.com",
              "brewdog.com"
            ],
            "items": {
              "type": "string"
            }
          },
          "region": {
            "title": "Country",
            "enum": [
              "US",
              "GB",
              "DE",
              "FR",
              "CA",
              "AU",
              "IN",
              "BR",
              "JP",
              "NL",
              "ES",
              "IT",
              "AD",
              "AE",
              "AF",
              "AL",
              "AM",
              "AO",
              "AR",
              "AT",
              "AZ",
              "BA",
              "BD",
              "BE",
              "BG",
              "BH",
              "BO",
              "BY",
              "CH",
              "CL",
              "CN",
              "CO",
              "CR",
              "CY",
              "CZ",
              "DK",
              "DO",
              "DZ",
              "EC",
              "EE",
              "EG",
              "ET",
              "FI",
              "GE",
              "GH",
              "GR",
              "GT",
              "HK",
              "HN",
              "HR",
              "HU",
              "ID",
              "IE",
              "IL",
              "IQ",
              "IS",
              "JM",
              "JO",
              "KE",
              "KH",
              "KR",
              "KW",
              "KZ",
              "LB",
              "LK",
              "LT",
              "LU",
              "LV",
              "MA",
              "MD",
              "MK",
              "MT",
              "MX",
              "MY",
              "NG",
              "NI",
              "NO",
              "NP",
              "NZ",
              "OM",
              "PA",
              "PE",
              "PH",
              "PK",
              "PL",
              "PR",
              "PT",
              "PY",
              "QA",
              "RO",
              "RS",
              "RU",
              "SA",
              "SE",
              "SG",
              "SI",
              "SK",
              "SN",
              "SV",
              "TH",
              "TN",
              "TR",
              "TW",
              "TZ",
              "UA",
              "UG",
              "UY",
              "VE",
              "VN",
              "ZA"
            ],
            "type": "string",
            "description": "Ads are reported per country. An advertiser can run thousands of ads in one country and none in another.",
            "default": "GB"
          },
          "maxResultsPerQuery": {
            "title": "Max ads per query",
            "minimum": 1,
            "maximum": 100000,
            "type": "integer",
            "description": "Upper bound on creatives returned for each query. Large advertisers can have hundreds of thousands. Set it above the advertiser's total inventory to enable confirmed change labels (new / paused); a capped scan cannot tell a paused ad from one beyond the limit, so it stays quiet.",
            "default": 50
          },
          "maxRunMinutes": {
            "title": "Max run time (minutes)",
            "minimum": 1,
            "maximum": 1440,
            "type": "integer",
            "description": "Hard wall-clock budget for the whole run. Large scans are deliberately paced to avoid Google's per-IP request limit, which makes them slow — roughly 90 seconds per advertiser at full depth. Without this cap, 200 advertisers would run for about five hours. When the budget is reached the run stops cleanly, keeps everything collected so far, and does NOT charge for advertisers it never scanned.",
            "default": 60
          },
          "formats": {
            "title": "Ad formats",
            "type": "array",
            "description": "Which creative formats to keep. All three are extracted correctly; video and text ads store their content differently from images, and are commonly dropped by other scrapers.",
            "items": {
              "type": "string",
              "enum": [
                "image",
                "video",
                "text"
              ],
              "enumTitles": [
                "Image",
                "Video",
                "Text"
              ]
            },
            "default": [
              "image",
              "video",
              "text"
            ]
          },
          "trackChanges": {
            "title": "Track changes between runs",
            "type": "boolean",
            "description": "Remember each run and label every ad as new, unchanged or paused. The first run records a baseline; every run after that tells you what your competitor launched or killed. Labels are only applied when the run scanned the advertiser's full inventory — on a partial scan every row says 'baseline' and the log tells you what to raise maxResultsPerQuery to, instead of guessing at changes.",
            "default": true
          },
          "onlyChanges": {
            "title": "Only output what changed",
            "type": "boolean",
            "description": "Return only new and paused ads. Runs with nothing to report — the first run, a quiet day, or any partial scan (see trackChanges) — return no rows and charge only the scan fee. The baseline is still updated in full. Ideal for a daily scheduled run feeding Slack, a webhook or a dashboard.",
            "default": false
          },
          "stateStoreName": {
            "title": "State store name",
            "type": "string",
            "description": "Named key-value store holding the baselines. Change it to keep separate tracking histories (for example one per client).",
            "default": "ads-transparency-state"
          },
          "activeWithinDays": {
            "title": "Only ads active in the last N days",
            "minimum": 1,
            "maximum": 3650,
            "type": "integer",
            "description": "Ask Google for ads shown in the last N days instead of an advertiser's entire history. This is applied on Google's side, so it is dramatically faster and cheaper: for nike.com the full history is ~10,000 ads while the last day is ~900. It is also more accurate for monitoring, because the full history includes ads that stopped running long ago. Recommended: 7 for a daily monitor. Leave empty for all-time."
          },
          "onlyAdsShownSince": {
            "title": "Only ads last shown since",
            "type": "string",
            "description": "Absolute-date version of the option above: return only ads shown on or after this date. Also applied on Google's side. Ignored if 'Only ads active in the last N days' is set. Note that Google evaluates the date in Pacific time, so the boundary is accurate to within a day."
          },
          "includeCreativeHtml": {
            "title": "Include raw creative HTML",
            "type": "boolean",
            "description": "Adds the raw HTML fragment for image ads. Off by default to keep the dataset small; asset URLs are always included.",
            "default": false
          },
          "minFillRate": {
            "title": "Minimum asset fill rate",
            "minimum": 0,
            "maximum": 1,
            "type": "number",
            "description": "Warn if fewer than this fraction of creatives have an asset URL. A sudden drop means Google changed its response shape and extraction is silently degrading. Lower it only if you know why.",
            "default": 0.5
          },
          "proxyConfiguration": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Optional. Google throttles by request volume per IP address, not by fingerprint — ordinary runs never come close to the limit, so most runs need no proxy. Without one, each query is capped at about 4,800 ads to protect the IP. Enable RESIDENTIAL proxies for very large scans or if a run reports a bot challenge.",
            "default": {
              "useApifyProxy": false
            }
          }
        }
      },
      "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
                  }
                }
              },
              "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}