I have recently been doing some work for a client building an automated task in python that accesses the Google Ads API using a Service Account and got stumped by a very persistent “NOT_ADS_USER
” error.
Despite the fact that we only wanted to use the API for reporting purposes (generating and downloading aggregate campaign statistics), the process Google makes you navigate to access the API is… arduous. It involves creating the Service Account (fair enough), enabling an API and generating a developer token in Google Ads, then make a DOMAIN WIDE DELEGATION to the service account! Anyway, I won’t go into detail on those steps here as the documentation for those steps is decent, but let’s look at a key step which I couldn’t find mentioned in the documentation anywhere.
Where I got stuck, and if you are reading this I guess you did too, is the that when you make your requests, you get an “NOT_ADS_USER
“, “User in the cookie is not a valid Ads user.
” error. It turned out my previous experience with using a service account with Domain Wide Delegation to access a GMail account (which actually makes sense) provided the key.
Basically, a Domain Wide Delegation allows a service account to impersonate a another user’s account for a specific service (e.g. their email, or in this case, their Google Ads account). However, to do this, we have to add the subject
parameter when we initialize the credentials object and provide the email of a user that has access to the Google Ads account.
In short, your code in python should look something like this:
from google.oauth2.service_account import Credentials
from google.ads.googleads.client import GoogleAdsClient
SCOPES = ['https://www.googleapis.com/auth/adwords']
PATH_TO_SERVICE_ACCOUNT_JSON = ''
CUSTOMER_ID = ''
DEVELOPER_TOKEN = ''
QUERY = ''
credentials = Credentials.from_service_account_file(PATH_TO_SERVICE_ACCOUNT_JSON, scopes=SCOPES, subject="<AN ACTUAL USER'S EMAIL HERE>")
googleads_client = GoogleAdsClient(credentials=credentials, developer_token=DEVELOPER_TOKEN, version="v7")
ga_service = googleads_client.get_service("GoogleAdsService")
response = ga_service.search(customer_id=CUSTOMER_ID, query=QUERY)
I couldn’t find any examples anywhere showing this, so hopefully I can save people some time with the above code template for python.
P.S. Google, get your act together. How can it be a 17 step process that includes making a DOMAIN WIDE DELEGATION to access a reporting API? Just to programmatically download aggregate campaign statistics, the same ones that can be downloaded by anyone from the Google Ads dashboard.
Did you also have to submit for basic or standard access? Your got me over a major hurdle (thank you!) but I’m not understanding how to access the API with a test account.
message: “The developer token is only approved for use with test accounts. To access non-test accounts, apply for Basic or Standard access.”
To be honest it was a little while ago since I did this and I have moved on from the place where I did the setup so I can’t check to see. From the message it does sound like you will need to generate a token with standard or basic access, that a test token can only access test accounts.