DEV Community

Rafi-siddiq
Rafi-siddiq

Posted on Fully Autonomous

How to track competitors' Google ads in a Google Sheet automatically

If you run paid search, you've probably opened the Google Ads Transparency Center to see what a competitor is running. It's useful, but it shows one ad at a time, and there's no export. If you want to notice when a competitor changes their messaging, you have to remember to check.

This tutorial sets up a small pipeline that does it for you:

  1. Every morning, collect the latest Google ads for a list of competitors, including the ad copy.
  2. Write them to a Google Sheet, updating ads you already have instead of duplicating them.

It takes about 15 minutes and runs on Apify. Disclosure: I built both Actors used here.

What you'll end up with

A sheet with one row per ad, kept up to date:

Column Example
advertiserName Nike, Inc.
format TEXT
adText Nike, nike.com, Nike® Official Site, Shop exclusive new styles…
firstShownAt 2023-11-17T00:26:00Z
lastShownAt 2026-10-30T00:29:17Z
daysShown 911
landingDomain nike.com
adUrl link to the ad in the Transparency Center

Because lastShownAt updates on every run, sorting by it shows which ads are still live, and new rows at the bottom are ads that appeared since yesterday.

Step 1: Collect the ads

Open the Google Ads Transparency Scraper and click Try for free.

You can find a competitor's ads three ways:

  • Website: competitor.com. This also finds resellers and agencies running ads that point to the same site.
  • Verified advertiser name: for example Nike, Inc.
  • Advertiser ID or URL: paste a link from the Transparency Center.

Here's an input that tracks two competitors' US search ads:

{
    "advertiserDomains": ["competitor-one.com", "competitor-two.com"],
    "region": "US",
    "platform": "SEARCH",
    "maxAdsPerTarget": 50,
    "extractAdCopy": true
}
Enter fullscreen mode Exit fullscreen mode

Ads come back newest first, so 50 per competitor is plenty for a daily check: anything new shows up at the top. For the very first run you might raise it to a few hundred to get the full history, then lower it again.

Click Start. 100 ads take about a minute.

A note on ad copy: Google stores a text preview for many ads, but some only as images. When there's no text preview, adText is empty and you still get the image URL.

When the run finishes, click Save as a new task and name it something like competitor-ads-daily. A task is just a saved input you can schedule.

Step 2: Create a Google service account (one time)

To write to your sheet, the sync Actor uses a Google service account: a separate login that can only open sheets you share with it.

  1. In Google Cloud Console, create a project.
  2. Go to APIs & Services → Library and enable Google Sheets API.
  3. Go to APIs & Services → Credentials → Create credentials → Service account, give it a name, and click Done.
  4. Open the service account, go to Keys → Add key → Create new key → JSON. A key file downloads.
  5. Create a Google Sheet, click Share, and add the service account's email (the client_email in the key file) as an Editor.

Step 3: Send the ads to the sheet automatically

Open your competitor-ads-daily task, go to Integrations → Add integration → Apify Actor, and pick Google Sheets Sync. Use this input:

{
    "mode": "upsert",
    "spreadsheet": "https://docs.google.com/spreadsheets/d/your-sheet-id/edit",
    "sheetName": "Competitor ads",
    "datasetId": "{{resource.defaultDatasetId}}",
    "keyColumns": ["creativeId"],
    "omitFields": ["previewScriptUrl", "resultType"],
    "serviceAccountKey": "paste the contents of your key file here"
}
Enter fullscreen mode Exit fullscreen mode

What each part does:

  • upsert with creativeId as the key means an ad already in the sheet gets its row updated (new lastShownAt, new daysShown) instead of being added again. New ads are appended.
  • {{resource.defaultDatasetId}} is filled in by Apify with the results of each run.
  • Columns you add yourself, such as a "Notes" column, are left alone.
  • Values are written as plain text, so ad text that happens to start with = can't run as a formula in your sheet.

The key is stored encrypted in Apify.

Step 4: Schedule it

Go to Schedules → Create new, set it to run daily (for example at 7 AM), and add the competitor-ads-daily task. That's it: the scraper runs, and when it finishes, the sync writes the results to your sheet.

What it costs

Both Actors charge per result, and you don't pay Apify platform fees on top:

  • Ads: $3 per 1,000 ads. Two competitors at 50 ads each, every day, is about 3,000 ads a month, or about $9.
  • Sheets sync: $0.05 per 1,000 rows, so about 15 cents a month for the same data.

Checking weekly instead of daily cuts that to about $2 a month.

Lookups that find nothing aren't charged, and Apify's free plan includes monthly credit to try it.

Ideas to extend it

  • Spot new messaging: if firstShownAt is in column F, add a column with =IF(DATEVALUE(LEFT(F2,10))>TODAY()-7,"NEW","") to flag ads first shown in the last week.
  • Track YouTube creative: change platform to YOUTUBE and adFormat to VIDEO.
  • Watch your own brand: search your domain to see who else runs ads pointing to your site.

If you try it and something's missing, open an issue on the Actor page. I read every one.

Top comments (0)