i am having issues accessing API

178 views
Skip to first unread message

Gilberto Galvez @ Healthcare

unread,
Jul 9, 2015, 8:51:18 AM7/9/15
to adwor...@googlegroups.com

Greetings to all, I have an Authentication issue using the AdWords API:

 

Currently I have a MCC account (499-xxx-xxx) with two sub-accounts:

1.       Sub-account 1: 476-xxx-xxx

2.       Sub-account 2: 120-xxx-xxx

 

At the MCC, we have a developer token inside the AdWords API Center with “Basic access”. The developer token starts KiPxxxxxxxxxxxxxxxxx. Client manager API, 818-xxx-xxxx that is linked to the MCC. Access type is “User interface and API”.

 

We are using the AdWords API to ingest campaign data for each account into our internal business reporting solution.

 

The issue is that I am only able to get data from one of the two accounts. Account 476-xxx-xxx returns back data when running on its own. When trying to capture data from 120-xxx-xxx, the ingestion process fails.

 

The error message we are receiving are:

AdWordsReportsException: Report download errors occurred.

Error: AuthorizationError.USER_PERMISSION_DENIED, Trigger: <null>

 

We contacted Google AdWords support on 7/6 to see they could understand why. The Google AdWords rep was super-helpful, and spent more than an hour reviewing. She analyzed the differences between the two AdWords accounts: 476-xxx-xxx and 120-xxx-xxx, to see if there were any obvious differences between the two. 476-xxx-xxx is the older account, created before the MCC account was created. Account 120-xxx-xxx, on the other hand, was created via the MCC account. One noticeable difference between account is that 120-xxx-xxx did not have an login email address associated with it, and so at the suggestion of the support rep, we subsequently added a new user to 120-xxx-xxx. This did not resolve the issue.

 

So we’re stuck on what the issue could be. Possibly it’s something related to how we’re pulling the data.

 

The piece of code I am using it is very straight forward:

 

General Configurations:

 

private const string DeveloperTokenHealth = "KiPZxxxxxxxxxxxxxx";

        private const string CustomerIdHealth = "476-XXX-XXXX";

        private const string CustomerIdMedicare = "120-XXX-XXXX";

        const String ClientId = "XXXXXXXXXXXX-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.apps.googleusercontent.com";

        const String ClientSecret = "WDZOxxxxxxxxxxxxxxxxxx";

 

Authentication Method:

            {

                var scopes = new[]

                {

                   "https://www.googleapis.com/auth/adwords"

                };

               

                UserCredential credential =

                    GoogleWebAuthorizationBroker.AuthorizeAsync(new ClientSecrets

                    {

                        ClientId = GetClientId(Subvertical),

                        ClientSecret = GetClientSecret(Subvertical)

                    },

                        scopes,

                        Environment.UserName,

                        CancellationToken.None,

                        new FileDataStore("localhost.GoogleAdWords.Auth.Store")).Result;

                return credential;

            }

 

Main Method for returning API Data:

var userCredential = Authentication(subVertical);

                var config = new Dictionary<string, string>

                {

                    {"DeveloperToken", GetDeveloperToken(subVertical)},

                    {"ClientCustomerId", GetCustomerId(subVertical)},                   

                    {"OAuth2ClientSecret", GetClientSecret(subVertical)},

                    {"OAuth2AccessToken", userCredential.Token.AccessToken},

                    {"OAuth2ClientId", GetClientId(subVertical)},

                    {"OAuth2RefreshToken", userCredential.Token.RefreshToken},

                    {"OAuth2Scope","https://www.googleapis.com/auth/adwords"}

 

                };

 

                var user = new AdWordsUser(config);

                return Run(user, dateFrom, dateTo, CustomerId[subVertical]);

 

Method for running API Data:

private static bool Run(AdWordsUser user, DateTime dateFrom, DateTime dateTo, String customerId)

        {

 

            var definition = new ReportDefinition

            {

                reportName = "CAMPAIGN_PERFORMANCE_REPORT",

                reportType = ReportDefinitionReportType.CAMPAIGN_PERFORMANCE_REPORT,

                downloadFormat = DownloadFormat.CSV,

                dateRangeType = ReportDefinitionDateRangeType.CUSTOM_DATE

            };

 

            var selector = new Selector

            {

                fields = new[]

                {

                    "Date", "CampaignStatus", "CampaignName", "CampaignId", "TotalBudget", "ServingStatus", "Clicks",

                    "Impressions", "Ctr", "AverageCpc", "Cost", "AveragePosition","ConversionsManyPerClick", 
                    "CostPerConversionManyPerClick", "ConversionRateManyPerClick","ViewThroughConversions", "Labels"

                }

            };

 

            selector.predicates = new Predicate[] { };

 

            var daterange = new DateRange {min = dateFrom.ToString("yyyyMMdd"), max = dateTo.ToString("yyyyMMdd")};

            selector.dateRange = daterange;

 

            definition.selector = selector;

            definition.includeZeroImpressions = true;

           

            string filePath = String.Format("c:\\adwords_campaign-{0}.csv",customerId);

 

            try

            {

                var utilities = new ReportUtilities(user, "v201502", definition);

                var response = utilities.GetResponse())

        catch (Exception ex)

            {

}

 

 

So always when I use CustomerIdMedicare = "120-XXX-XXXX"; the application goes by Exception

 

Any suggestions or ideas of what the issue might be?

Anthony Madrigal

unread,
Jul 9, 2015, 12:35:30 PM7/9/15
to adwor...@googlegroups.com, autom...@healthcare.com
Hi Gilberto,

Could you please Reply privately to author the SOAP request and response in which you are getting this error?

Thanks,
Anthony
AdWords API Team

Gilberto Galvez @ Healthcare

unread,
Jul 17, 2015, 5:50:42 PM7/17/15
to adwor...@googlegroups.com, autom...@healthcare.com
Hi Anthony,
Thanks for your response again from last week about our AdWords API reporting issue. Based on your response, I think you're saying that the email account associated with the Google Developers Console that is used to generate the refresh token MUST have access to the MCC account that we're seeking reporting on.
That wasn't the case with us, and perhaps that is the reason we're getting the error when trying to pull data on the 120-xxx-xxx account.  
The first refresh token was generated using the account: autom...@healthcare.com, which does not have MCC access.  Perhaps it had access to one of the AdWords accounts directly, but not to the MCC.
Is what you're saying that we need to open up a Developers Console account using an email address that already has AdWords MCC access, and then we should be able to pull data from both AdWords accounts under the MCC?

howardyeh[3:43 PM]We're going about this already, but would like to confirm with you that we're on the right track. Thanks.

Anthony Madrigal

unread,
Jul 20, 2015, 11:02:47 AM7/20/15
to adwor...@googlegroups.com, autom...@healthcare.com
HI Gilberto,

Yes, once you have a Refresh Token generated from an email with access to the MCC account, use the link provided in an incognito window. You should log in using the AdWords account you would like to grant access to. After that, you should be able to pull data from both of your AdWords accounts under the MCC.

Please let me know if you run into any other issues regarding this.

Regards,
Anthony
AdWords API Team

Gilberto Galvez @ Healthcare

unread,
Jul 21, 2015, 7:45:37 PM7/21/15
to AdWords API Forum, Howard Yeh
Awesome Anthony, i tried what you told, but now  i am receiving this error:

Message:

Failed to refresh access token.
{
  "error" : "unauthorized_client"
}

Stack Trace:

   at Google.Api.Ads.Common.Lib.OAuth2ProviderForApplications.RefreshAccessTokenInOfflineMode()
   at Google.Api.Ads.Common.Lib.OAuth2ProviderForApplications.RefreshAccessToken()
   at Google.Api.Ads.Common.Lib.OAuth2ProviderBase.RefreshAccessTokenIfExpiring()
   at Google.Api.Ads.Common.Lib.OAuth2ProviderBase.GetAuthHeader()
   at Google.Api.Ads.AdWords.Util.Reports.ReportUtilities.BuildRequest(String downloadUrl, String postBody)
   at Google.Api.Ads.AdWords.Util.Reports.ReportUtilities.DownloadReport(String downloadUrl, String postBody)
   at Google.Api.Ads.AdWords.Util.Reports.ReportUtilities.GetReport()
   at Google.Api.Ads.Common.Util.Reports.AdsReportUtilities.GetResponse()

if found something but it really does not solves my issue:


do you think is there something you can share/advise to me ?

Thanks looking forward on this solution,

Anthony Madrigal

unread,
Jul 22, 2015, 2:53:03 PM7/22/15
to AdWords API Forum, autom...@healthcare.com, how...@healthcare.com
Hi Gilberto,

The unauthorized_client error means the OAuth client ID/secret pair is not authorized to use the authorization method. This can happen if you use a different client ID/secret from the one that was used to generate the refresh token.

Please note that you don't actually need a separate client ID/secret for every refresh token you want to use. The client ID/secret is specific to the application, not the user. You can create one client ID/secret in the Developer's Console and use it to get OAuth credentials for multiple users.

Gilberto Galvez @ Healthcare

unread,
Jul 22, 2015, 5:34:09 PM7/22/15
to AdWords API Forum, how...@healthcare.com
ok, i understand your point, but i re-created credentials (@ console.developers.google.com/project/<project-name>/apiui/credential ) because i tried with the new token but did not work neither, so i thought that new OAuth Id & Secret were required, 

if i use the same Id & Secrets with the new Token i am still unable to obtain data for 120-xxx-xxxx such as i was at the beginning of this conversation/forum 

Do you think there is something else i can check or i am missing in configuration ?

Anthony Madrigal

unread,
Jul 23, 2015, 3:02:08 PM7/23/15
to AdWords API Forum, autom...@healthcare.com, how...@healthcare.com, autom...@healthcare.com
Hi Gilberto,

It does not appear as you are missing anything in your configuration. Could you please try using the ManagedCustomerService and see what you get back? The service should return the accounts under the MCC.
Reply all
Reply to author
Forward
0 new messages