Does the AdWords API support authentication via service accounts (OAuth 2.0)?

7,981 views
Skip to first unread message

Bobby

unread,
Oct 16, 2012, 1:19:55 PM10/16/12
to adwor...@googlegroups.com
Specifically, I am trying to run AdHoc reports without any user interaction.  Since it is a new application, it would be desirable to use the latest technology instead of using something that is already deprecated (i.e. ClientLogin).  Can one of the AdWords moderators please comment?  If this is not possible, please provide an alternate solution that will not require updating in the near future.  Thanks.

Win Ko Aye

unread,
Oct 18, 2012, 6:10:03 AM10/18/12
to adwor...@googlegroups.com
Hi,

Just sharing my experience with OAuth2 service account.

Step 1: Create 'Service Account' in 'API console'

- Log in to api console using the email that you used to connect adwords api. The email should be from your domain, for

example, adw...@yourdomain.com

https://code.google.com/apis/console/

- Create a new project if you havn't done so in the past.
- Go to 'API Access' page and 'Create client ID', choose 'Service Account' from the options.
- Download private key of the client service account, take note of 'Client ID' and 'Email address'. You'll see
something like;

Client ID        : 123456789012.apps.googleusercontent.com
Email address        : 123456...@developer.gserviceaccount.com
Public key fingerprints    : 123456789abcdef123456789abcdef123456789a

Private key's default filename is like '123456789abcdef123456789abcdef123456789a-privatekey.p12'


Step 2: Authorize api client in 'Google Apps for Business'

- You need domain administrator access to 'Google Apps for Business'. Log in to http://www.google.com/enterprise/apps/business/ with domain admin account.

- Go to 'Advanced Tools > Manage client API access'.
- Enter client ID, from above example that's '123456789012.apps.googleusercontent.com' in 'Client Name' field.
- Enter 'https://adwords.google.com/api/adwords' in 'One or More API Scopes' field.
- Hit 'Authorize'

Here's the page to detail instructions

OAuth: Managing API client access
http://support.google.com/a/bin/answer.py?hl=en&answer=162106


Step 3: Coding using java client libraries

- I use 'Google API Client Library for Java, version 1.11.0-beta'
https://code.google.com/p/google-api-java-client/downloads/detail?name=google-api-java-client-1.11.0-beta.zip&can=2&q=


- And follow the OAuth2 example from
https://code.google.com/p/google-api-ads-java/source/browse/examples/adwords_axis/src/main/java/adwords/axis/v201209/misc/OAuth2Example.java

But replace getOAuth2Credential() with

private static Credential getOAuth2Credential() throws Exception {

    File keyFile = new File("123456789abcdef123456789abcdef123456789a-privatekey.p12");
         
    GoogleCredential serviceAccountCredential = new GoogleCredential.Builder()
        .setTransport(new NetHttpTransport())
        .setJsonFactory(new JacksonFactory())
        .setServiceAccountId("123456...@developer.gserviceaccount.com")
        .setServiceAccountScopes("https://adwords.google.com/api/adwords")
        .setServiceAccountPrivateKeyFromP12File(keyFile)
        .setServiceAccountUser("adw...@yourdomain.com")
        .build();
       
    return serviceAccountCredential;
}

You can ignore CALLBACK_URL, CLIENT_ID and CLIENT_SECRET. They are use for interactive web server application.

Check 'ads.properties' file

api.adwords.email=adw...@yourdomain.com
api.adwords.password=*******
api.adwords.clientCustomerId.prod=123-456-7890
api.adwords.environment=production

That's it and good luck.

Win Ko

Bobby

unread,
Oct 19, 2012, 4:32:59 PM10/19/12
to adwor...@googlegroups.com
Win Ko Aye,

Thanks for your help.  Your instructions helped me get it working.

Bobby

Micah Ransdell

unread,
Nov 9, 2012, 3:25:51 PM11/9/12
to adwor...@googlegroups.com
Win Ko Aye,

I am trying to follow your instructions, but I am unable to complete Step 2 because we are not using Google Apps for Business. I am able to complete the other steps, and when I try to access the CampaignService I receive "AuthenticationError.NOT_ADS_USER" when trying to access the campaigns for one of the client accounts.

All the messages I can find in this forum revolve around people seeing that error in the Sandbox, but this is in Production for me. 

Any help is appreciated.

Micah
        .setServiceAccountId("123456789012@developer.gserviceaccount.com")

        .setServiceAccountScopes("https://adwords.google.com/api/adwords")
        .setServiceAccountPrivateKeyFromP12File(keyFile)
        .setServiceAccountUser("adwords...@yourdomain.com")

Micah Ransdell

unread,
Nov 13, 2012, 12:12:35 PM11/13/12
to Win Ko Aye, adwor...@googlegroups.com
Thank you for the information. I'll see if I can find another way to get my API client recognized.

[cc'ing the list]

On Sun, Nov 11, 2012 at 5:52 PM, Win Ko Aye <w...@adzcentral.com> wrote:
Hi Micah,

That's because OAuth2 server doesn't recognize the api client ID you passed in CampaignService call. You need to get your api client ID authorized first before using it. As far as I know, Google App console is the only place you can authorize client service account, as of now. Maybe they will expose that functionality in the api someway in the future.

Another method is to use Web Service account that requires user interaction but doesn't need to use Google App.

Hope that helps.

Win Ko



--
=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~
Also find us on our blog and discussion group:
http://adwordsapi.blogspot.com
http://groups.google.com/group/adwords-api
=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~=~
 
You received this message because you are subscribed to the Google
Groups "AdWords API Forum" group.
To post to this group, send email to adwor...@googlegroups.com
To unsubscribe from this group, send email to
adwords-api...@googlegroups.com
For more options, visit this group at
http://groups.google.com/group/adwords-api?hl=en


Pianoman

unread,
Nov 13, 2012, 3:59:42 PM11/13/12
to adwor...@googlegroups.com, Win Ko Aye
Dear Google Adwords API Team,

As you are recommending we start authenticating using OAuth 2.0, could you (Eric Koleda for example) please either organise a hangout and/or create a screencast, explaining how to go about OAuth 2.0 authentication using the PHP Client Library?

The only PHP Client Library screencast help I can see online is here, but that's pretty dated now.

I am unfamiliar with OAuth 2.0.
For now I am sticking to the deprecated authentication system, but would like to migrate to OAuth 2.0.

Regards,
--
Paul

Anash P. Oommen

unread,
Nov 13, 2012, 9:50:38 PM11/13/12
to adwor...@googlegroups.com, Win Ko Aye
Hi Paul,

The AdWords API PHP library already has a code example that shows how to use OAuth2 with AdWords API. You can find it here: http://code.google.com/p/google-api-adwords-php/source/browse/trunk/examples/v201209/Misc/UseOAuth2.php. Also, service accounts allow you to call AdWords API without any user interaction, but that is not the only way to achieve server-to-server call. If you care only about offline call without user interaction and not about impersonating users, then you can use regular OAuth2 call with offline = true as explained here: https://developers.google.com/accounts/docs/OAuth2WebServer#offline. To summarize,

1. You need to get an OAuth2 clientId and secret from https://code.google.com/apis/console. When creating the token, select "Installed Application" and select "Other" in the "Installed Application type".
2. Substitute these values in UseOAuth2.php example and run it. This code example will generate an access token and refresh token. The access token will expire after an hour, refresh token doesn't.
3. When your access token expires, refresh it using $user->RefreshOAuth2AccessToken call.

You could generate a refresh token for your parent MCC once and continue using it without requiring user interaction.

Cheers,
Anash P. Oommen,
AdWords API Advisor.

Dale Olson

unread,
Nov 14, 2012, 7:09:45 PM11/14/12
to adwor...@googlegroups.com, Win Ko Aye
I am intensely interested in this thread, and it seems to be drifting away from the original question - how to run an adwords adhoc report without user input to authenticate/authorize using OAuth2. Win Ko Aye responded with a very helpful and detailed set of steps to create a service account and create the request, which I followed to the letter but I am still struggling to get working.
For the service account approach, I get all the way through creating the token and try to call the service and get back :
com.google.api.ads.common.lib.exception.OAuthException: OAuth2 token could not be refreshed.
...
Caused by: com.google.api.client.auth.oauth2.TokenResponseException: 400 Bad Request
{
"error" : "invalid_grant"
}
When looking into what might cause this there are conflicting reports on whether you can even use a service account with the adwords API and the error seems to be saying that I am authenticated but not authorized to use the service. Any ideas here?
Anash, regarding your suggestion to create an installed app account this does not seem to satisfy the original request for a way to set up application to application access with no user input required. Please let me know if i misunderstood something here.

Chirag

unread,
Nov 16, 2012, 6:23:55 AM11/16/12
to adwor...@googlegroups.com, Win Ko Aye
Hello Anash,

Yes, I am also looking for that.
How i can define Authinfo for any report download.

$oauthInfo = array('oauth_consumer_key' => 'consumer_key', 'oauth_consumer_secret' => 'consumer secret', 'oauth_token' => token, 'oauth_token_secret' => token_secret);
 $user = new AdWordsUser(OAUTH_PATH, NULL, NULL, NULL, NULL, NULL, NULL, OAUTH_SETTINGS_PATH, NULL, $oauthInfo);

In Above Example how to define $oauthInfo for oAuth 2.0 use? and which parameter i need to pass?

Thanks,
Chirag

Remco Hendriks

unread,
Nov 16, 2012, 4:59:28 PM11/16/12
to adwor...@googlegroups.com
This is working for me - thank you very much.

Do not forget to pass redirect_uri argument to the flow constructor (use_oauth2.py:49), i.e. redirect_uri='urn:ietf:wg:oauth:2.0:oob' or any other redirect uri from the api console.

Remco

Paul Matthews

unread,
Nov 22, 2012, 11:10:29 AM11/22/12
to adwor...@googlegroups.com, Win Ko Aye
Hi Chirag,

The simplest way to pass OAuth2 configuration to the AdWordsUser is to use an empty constructor and call the setter ->SetOAuth2Info. For an example of this, pelase see the OAuth2 example.

Please bear in mind, that to process the OAuth2 user journey offline, you'll need to first obtain a refresh token online. For more information on this please see the OAuth2 Information page.

A quick example of configuring the user could be:

$user = new AdWordsUser();
$user->SetOAuth2Info(array(
    'client_id'     => '8819981768.apps.googleusercontent.com',
    'client_secret' => '************************',
));
$authorizationUrl = $user->GetOAuth2AuthorizationUrl(NULL, TRUE);
...

Currently the AdWords client library alone doesn't support serviced accounts.

Regards,

- Paul, AdWords API Team.

John Lister

unread,
Dec 29, 2012, 3:53:16 PM12/29/12
to adwor...@googlegroups.com
Hi, has anyone found a way to authorise a service client id to access the adwords api without using google apps for business? I'm struggling with the NOT_ADS_USER error as well...

I've created the service account id and key using my MCC account details, but do I need to create it as a normal user for the account I'd like access to? Secondly reading some info on service accounts implies I need to authorise the service account email address to access the api I'd like to use. Do I need to register this as an adwords user? On the api console, I don't see the adwords api listed so can't enable it from there...

Thanks

John

Kevin Winter (AdWords API Team)

unread,
Jan 3, 2013, 10:58:28 AM1/3/13
to adwor...@googlegroups.com
Hi John,
  I think the core issue is that service accounts are designed for much more than simply making requests without user interaction.  This mechanism is also intended to allow impersonating other users on a domain, which isn't possible without google apps for your domain.

Another alternative is to use a regular OAuth2 token that you've authorized for offline access.  The way this could work is:

- Perform the OAuth2 flow once initially for setup, authorize for offline access (this is similar to the one-time setup that service accounts require).
- Use the refresh token to obtain a new access token prior to making requests.
- Profit by making API calls without any user interaction.

The access token is valid for only 1 hour, but the refresh token can be used to obtain new access tokens until it has been revoked.

- Kevin Winter
AdWords API Team

John Lister

unread,
Jan 6, 2013, 4:45:28 PM1/6/13
to adwor...@googlegroups.com
Thanks, I'm using the refresh token now - but was trying to get the service accounts working as that is what I'd used with other apis, eg: analytics, etc

Thanks

web...@adaptiveaudience.com

unread,
Apr 30, 2013, 12:16:08 PM4/30/13
to adwor...@googlegroups.com
Please Help!

I have a service account, but have not seen a PHP example of how to set this up for google adwords.  Any assistance will be appreciated!  Thank you in advance!  On another note, I am currently getting incomplete_signup error.  Info: Customer ID: 667-082-2778 .  Hope you have a great day.

Best regards,

David Paul

br...@parkinginmotion.com

unread,
May 1, 2013, 8:06:47 PM5/1/13
to adwor...@googlegroups.com
Speaking about the Python lib:

Firstly, I cannot seem to acquire anything from the API Console for AdWords that has a "client_secret", so all the interactive examples do not work for me. So if that was solvable I would not have gone down this second path which is:

I have not seen anything that shows how to use a service account authentification to create the AdWords client object. All of the example for using the adwords with oauth require having a client_secret which we do not have (and cannot create for AdWords AFAIK). I can authenticate using the OAuthExample at: /google-api-python-client/samples/service_account and substituting AdWords for Tasks, but this hands me back an http object which I am unclear how I tie that into the adwords API.

Specifically here: 
    credentials = SignedJwtAssertionCredentials(
        key,
    http = httplib2.Http()
    http = credentials.authorize(http)

So what do I do now with that http object? The Java examples seems to hand back a authentification object which can be passed to the Adwords Client. Is any of that correct? It seems like other people are able to accomplish this, but I am lost.

Any help would be really appreciated.

Kevin Winter (AdWords API Team)

unread,
May 3, 2013, 10:38:00 AM5/3/13
to adwor...@googlegroups.com
Hi all,
  The PHP does not currently support service accounts out-of-the-box - it requires a combination of Google Client Libs integration to achieve this.

For Python, you can pass that credentials object into the AdWordsClient constructor like this: https://code.google.com/p/google-api-ads-python/source/browse/trunk/examples/adspygoogle/adwords/v201302/misc/use_oauth2.py#75 .  However, you need to explicitly impersonate a user.

Can I ask why you are using service accounts?  Service accounts are used to impersonate specific users while using Google Apps for your Domain.  For most cases, simply performing the auth flow once and persisting the refresh token is sufficient for non-interactive usage of the API.

We're working to make it easier to use OAuth2 with the various client libraries and would appreciate feedback.

- Kevin Winter
AdWords API Team

Kevin Winter (AdWords API Team)

unread,
May 3, 2013, 2:37:14 PM5/3/13
to adwor...@googlegroups.com
Hi Brent,

"It seemed to me that service account was my only option, not an option I chose. I initially started down the path of doing exactly what you described, even using the Django sample included in the OAuth lib. However, all these examples, and in fact all API's except for service accounts seemed to require a "client_secret" which I do not see in my account. (I get a client_id obviously). What I do see is the p12 key, which tends to lead you to believe that you should be using that, and I believe the only type that uses that is using a Service Account.

I would have no problem using the more typical interactive authorization as the application does have a web interface, but I could not see how to get the API Console to give me a client_secret for the AdWords API. (I tried a couple of other API's out and they provide the client_secret and the OAuth examples work just fine).

Hopefully I am mistaken and there is a way to obtain a client_secret for AdWords and I can go down the simpler path of interactive authentification."

If I navigate to https://code.google.com/apis/console/ and choose my project, then click on "API Access", I see the attached screenshot that has the client ID and secret (that I previously created).  If you haven't already, you can create a client ID to use OAuth2 - service accounts are not the only way (and certainly not the easiest way).  What we recommend is to use the client ID and secret (from that page) to perform the OAuth2 flow once (for each account you would normally use an email and password with for ClientLogin) - save the refresh token and use it to obtain a fresh Access Token any time you need to make API calls.

- Kevin Winter
AdWords API Team

Screenshot from 2013-05-03 14:31:22.png

Nick Tulip

unread,
Oct 8, 2013, 2:21:32 PM10/8/13
to adwor...@googlegroups.com, Win Ko Aye
It looks like the example v201209/Misc/UseOAuth2.php has been removed the lib. Do we know why or if it is even possible anymore to use the PHP Lib with OAuth2 for service accounts?

Paul Matthews (AdWords API Team)

unread,
Oct 14, 2013, 11:02:18 AM10/14/13
to adwor...@googlegroups.com, Win Ko Aye
Hi Nick,

The UseOAuth2 example has been moved to GetRefreshToken.php, which demonstrates retrieving and configuring a refresh token (used by OAuth2). For further information on this, please see the OAuth2 wiki page.

Currently the PHP has no official support for serviced accounts. The only work around is to use the google-api-php-client to handle the authentication and pass the result to the google-api-adwords-php library. To request official support for serviced accounts in the PHP client library, please log a feature request.

Regards,

- Paul, AdWords API Team.

Arpit Agrawal

unread,
Nov 26, 2019, 4:36:45 AM11/26/19
to AdWords API and Google Ads API Forum
I am currently in testing phase, I have created one test manager account with one test client account inside it. This is associated with email abc....@gmail.com
Then I had created one Production Manager account associated with abc...@mycompany.com(Gmail Business Account).

In this case, service account should be created from which email address ?
        .setServiceAccountId("123456789012@developer.gserviceaccount.com")

        .setServiceAccountScopes("https://adwords.google.com/api/adwords")
        .setServiceAccountPrivateKeyFromP12File(keyFile)
        .setServiceAccountUser("adwords...@yourdomain.com")

Google Ads API Forum Advisor Prod

unread,
Nov 26, 2019, 12:22:12 PM11/26/19
to agrawal...@gmail.com, adwor...@googlegroups.com

Hi Arpit,

As a credential generated for an Google Ads manager account can be used to access all its child accounts. It will be sufficient for you to generate credentials for each MCC manager account. Since you have both the test manager account and production manager account, it depends on which account you would like to have access for your application. If you would like to have access for both accounts then you need to create service accounts for both manager accounts separately. Please refer to this guide for more details on generating credentials and creating service accounts. Please let us know if you have any further questions.

Thanks and regards,
Xiaoming, Google Ads API Team



ref:_00D1U1174p._5001UODI0L:ref
Reply all
Reply to author
Forward
0 new messages