
14.10.2025
Regularly monitoring the destination URLs of your Google Ads campaigns is one of the most effective ways to protect your ad budget. Broken or misdirected pages waste paid clicks, lower your Quality Score, and hurt your conversion rates.
In this article we’ll walk you step-by-step through building an automation system that exports Google Ads destination URL data into Google Sheets, checks whether those URLs are working, and—if a problem is found—sends alert emails via Gmail.
We won’t focus solely on code snippets; our emphasis is on API connection structure, data flow, authentication processes, and the logical design of the automation.
The provided Python examples give you a solid, extensible foundation—so you can adapt this solution to your own use case, and expand it to other API endpoints or data sources.
Throughout the article we’ll examine how to set the system up from scratch, which integrations kick in at each stage, and the technical details you may encounter. If you have additions that would improve the reports or any feedback (positive or critical), we’d love to hear it.
With this system, you’ll be able to:
To set up this system, you’ll need the following components:
Start by creating a new project in Google Cloud Console.
Once your project is ready, enable the following APIs:

These APIs will allow us to both retrieve ad data and manage Sheets operations directly through Python.
To use the Google Ads API, you’ll need four key pieces of information:
You can find this in your Google Ads account under Admin -> API Center -> API Access.
If you don’t already have a token, the newly issued one will start at Test Access level. To upgrade to Basic Access, you’ll need to submit an additional application explaining your API usage purpose in a brief documentation format.

You can create it in Google Cloud Console under APIs & Services -> Credentials -> OAuth 2.0 Client IDs.

It’s required to ensure automatic token renewal when access expires.
By now, you should have your Developer Token, Client ID, and Client Secret ready. You’ll also need a Gmail account that has access to the Google Ads account.
You can quickly generate your Refresh Token using Google’s official tool, OAuth 2.0 Playground:
We store all of this information in the “google-ads.yaml” file using the following format:
developer_token: “your_developer_token”
client_id: “your_client_id”
client_secret: “your_client_secret”
refresh_token: “your_refresh_token”
login_customer_id: 1111111111 # MCC hesabınız
use_proto_plus: True
Keep this file in your project directory.
Create a new spreadsheet in Google Sheets.
This file will store campaign URLs, sitelinks, and their error statuses.
Create two sheets (you can rename them as you like):
Make sure to note the Spreadsheet ID.
You can find it in the URL of your Google Sheet, between /d/ and /edit.
To access the Sheets API, create a service account:
Here’s an example of a “service_account.json” file structure:
{
“type”: “service_account”,
“project_id”: “your_project_id”,
“private_key_id”: “your_private_key_id”,
“private_key”: “—–BEGIN PRIVATE KEY—–\your_privete_key\n—–END PRIVATE KEY—–\n”,
“client_email”: “your_client_email_name@abiding-hull-471108-q5.iam.gserviceaccount.com”,
“client_id”: “your_client_id”,
“auth_uri”: “https://accounts.google.com/o/oauth2/auth”,
“token_uri”: “https://oauth2.googleapis.com/token”,
“auth_provider_x509_cert_url”: “https://www.googleapis.com/oauth2/v1/certs”,
“client_x509_cert_url”: “https://www.googleapis.com/robot/v1/metadata/x509/your_client_email_name%40abiding-hull-471108-q5.iam.gserviceaccount.com”,
“universe_domain”: “googleapis.com”
}


This grants your Python script direct write access to the spreadsheet.
Assuming your Python environment is already set up with the latest version, install the required libraries via your terminal or command prompt:
pip install google-ads google-api-python-client google-auth requests
At the end of the automation, if a broken URL is detected, the system will automatically send an email via Gmail.
To enable this, you need to create a Gmail App Password:
This password can be used securely in your code along with your Gmail account to send emails automatically.
Now that the setup is complete, the automation workflow is as follows:
To run this system at a specific time every day, you can set up a scheduler.
Since you’re using Windows, you can accomplish this via Task Scheduler.
You can also test the code manually.
In the terminal, run:
python check_urls.py
If everything is set up correctly:
In this section, we’ll explain what each part of the code (check_url.py) does and the results it produces when executed.
The following codes load external libraries and API clients that the project will use.
from google.ads.googleads.client import GoogleAdsClient
from google.oauth2 import service_account
from googleapiclient.discovery import build
import requests
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
This code snippet sets up the configuration for our project.
It defines all the connection details and authentication files required for Google Ads API, Google Sheets, and email notifications.
GOOGLE_ADS_CONFIG_PATH = “google-ads.yaml”
CUSTOMER_ID = “your_customer_id”
SERVICE_ACCOUNT_FILE = “service_account.json”
SPREADSHEET_ID = “your_spreadsheet_id”
SHEET1_NAME = “Sheet1”
SITELINKS_SHEET_NAME = “Sheet2”
EMAIL_SENDER = “your_email”
EMAIL_RECEIVER = “your_email”
EMAIL_PASSWORD = “your_app_password”
The “send_email” function is used to automatically send an email notification once the process is complete
def send_email(subject, body):
msg = MIMEMultipart()
msg[“From”] = EMAIL_SENDER
msg[“To”] = EMAIL_RECEIVER
msg[“Subject”] = subject
msg.attach(MIMEText(body, “plain”))
try:
with smtplib.SMTP_SSL(“smtp.gmail.com”, 465) as server:
server.login(EMAIL_SENDER, EMAIL_PASSWORD)
server.send_message(msg)
print(“The email has been sent.”)
except Exception as e:
print(f”The email could not be sent.: {e}”)
The “check_url” function is used to verify the accessibility of a given URL.
def check_url(url):
if not url:
return “”
try:
r = requests.get(url.strip(), timeout=5)
if r.status_code == 200:
return “OK”
else:
return f”Error {r.status_code}”
except requests.exceptions.RequestException as e:
return f”Failed: {e.__class__.__name__}”
The “get_search_campaigns” function is used to retrieve the ad URLs from active Search and Display campaigns in a Google Ads account.
def get_search_campaigns(client, customer_id):
ga_service = client.get_service(“GoogleAdsService”)
query = “””
SELECT
campaign.id,
campaign.name,
ad_group_ad.ad.id,
ad_group.name,
ad_group_ad.ad.final_urls,
campaign.advertising_channel_type
FROM ad_group_ad
WHERE campaign.status = ‘ENABLED’
AND campaign.advertising_channel_type IN (‘SEARCH’, ‘DISPLAY’)
ORDER BY campaign.id
“””
results = []
response = ga_service.search(customer_id=customer_id, query=query)
for row in response:
final_urls = [str(url) for url in row.ad_group_ad.ad.final_urls] if row.ad_group_ad.ad.final_urls else []
results.append((
row.campaign.id,
row.campaign.name,
row.ad_group_ad.ad.id,
row.ad_group.name,
“, “.join(final_urls),
“SEARCH/DISPLAY”
))
return results
The “get_account_sitelinks” function is used to retrieve account-level Sitelink extensions.
def get_account_sitelinks(google_ads_client, customer_id):
ga_service = google_ads_client.get_service(“GoogleAdsService”)
query = “””
SELECT
customer_asset.asset,
customer_asset.status,
asset.name,
asset.sitelink_asset.link_text,
asset.sitelink_asset.description1,
asset.sitelink_asset.description2,
asset.final_urls
FROM customer_asset
WHERE asset.type = ‘SITELINK’
“””
results = []
response = ga_service.search(customer_id=customer_id, query=query)
for row in response:
final_urls = [str(url) for url in row.asset.final_urls] if row.asset.final_urls else []
results.append((“”, “”, row.asset.name, row.asset.sitelink_asset.link_text, row.asset.sitelink_asset.description1 or “”, “, “.join(final_urls)))
return results
Using the same approach, we run separate functions to retrieve PMax and campaign-level sitelink URLs.
These URLs are then written into the corresponding fields in the Google Sheet.
You can access the full code via the following link.
https://github.com/mehmetakifc/google-ads-url-checker
The Sheet1 page containing the campaign URL information looks like this:

The Sitelinks page containing the sitelink URL information looks like this:

The email notification looks like this:

In this article, we outlined how to build a fully automated system that regularly checks and reports Google Ads Final URLs and Sitelink URLs, detecting any broken links.
This system allows you to:
In short, this solution makes your ad accounts healthier, more transparent, and more efficient—both technically and operationally.
Perfist Blog
Similar Articles

Regularly monitoring the destination URLs of your Google Ads campaigns is one of the most effective ways to protect your ad budget. Broken or misdirected pages waste paid clicks, lower your Quality Score, and hurt your conversion rates. In this article we’ll walk you step-by-step through building an automation system that exports Google Ads destination […]
Read More
Senior Level Performance Marketing
In this guide, we will explain what a session is in Google Analytics 4 (GA4), why session duration matters, which session metrics are available, and how to configure these settings. What is a Session in GA4? A session represents the group of interactions a user has with your website or mobile app within a given […]
Read More
Beginner Level Web/App Analytics
What is GEO (Generative Engine Optimization)? GEO is a new generation optimization method that ensures content stands out in AI-supported search systems. It aims to produce content that can provide quick and clear answers to user questions. In addition to traditional SEO, a simple and understandable language that appeals to artificial intelligence is used. Why […]
Read More
Mid Level SEO
GEO is an optimization method developed to ensure that content is better understood and recommended by AI-powered search engines. Previously, when writing content, the goal was solely to rank high on Google. Now, however, AI systems read these contents and present summaries to users. This is exactly where GEO steps in. It ensures that content […]
Read More
Mid Level Content Marketing