AuthorizationError.USER_PERMISSION_DENIED While accessing campaigns

5,182 views
Skip to first unread message

Bikram Bhuyan

unread,
Oct 31, 2013, 7:30:39 PM10/31/13
to adwor...@googlegroups.com, Bikram Keshari Bhuyan
Hello,

We have a test mcc account and a test customer id. Also we have got the pending developer token for our production account. I generated the OAuth2ClientId, OAuth2ClientSecret & OAuth2RefreshToken successfully by following the steps. Now when I make a the api call to fetch the list of campaign associated with my test customer id, I am getting "AuthorizationError.USER_PERMISSION_DENIED" error.

Could you please suggest if I am missing any set up process?

If you want I can send you my IDs and token currently I used in the application.

Thanks,
Bikram.
AuthorizationError.txt

Takeshi Hagikura (AdWords API Team)

unread,
Nov 6, 2013, 3:25:16 AM11/6/13
to adwor...@googlegroups.com, Bikram Keshari Bhuyan
Hi Bikram,

My first guess is you are making an API call against a client account that is different from the account you authenticated with using OAuth2. 
Can you please share the SOAP request xml (please remove sensitive info before posting) log and the email you used when you authenticated using OAuth2?

Best,
- Takeshi, AdWords API Team

Bikram Bhuyan

unread,
Nov 6, 2013, 12:59:39 PM11/6/13
to adwor...@googlegroups.com, Bikram Keshari Bhuyan
Hello Takeshi,

Thanks for the reply. I suspect the same as well. But I am making the calls based on the account information that is provided by google adwords team after applying for the account set up. So I am not sure where is the issues. I am attaching the API logs as per your message below.

Could you please tell me where I am making wrong? If you want I can email my account information to your email for further investigation (if you give me the email address).

Thanks,
Bikram.
Request & Response Of API Call.txt

Takeshi Hagikura (AdWords API Team)

unread,
Nov 6, 2013, 10:57:59 PM11/6/13
to adwor...@googlegroups.com, Bikram Keshari Bhuyan
Thanks for the logs. 

Your clientCustomerId header looks in the request looks fine. 

For the next step, you need to make sure the client account is linked to the MCC account with which you got your OAuth2 credential. 
What email address did you use when you got the OAuth2 credential (access_token,  refresh_token)?
If you don't want to post it here, you can select "Reply to author" from the top right corner.

Best,
- Takeshi, AdWords API Team
Message has been deleted

Bikram Bhuyan

unread,
Nov 7, 2013, 7:31:15 PM11/7/13
to adwor...@googlegroups.com, Bikram Keshari Bhuyan
Hi Takeshi,

I finally able to find the right MCC account for and user that to generate the tokens and am able to access the API now. That issues is resolved now. So thanks a lot for your help.

Now I have a different issues to deal with. Looking at the refresh token generation process, I see that we need to open the web page and give access to our MCC account manually and then the refresh token is generated which can be used to make the API call. Now for our requirement, we have a windows service which runs in the background, and we have several clients who are using our application. Now the question is how do our application get access API access to their AdWords accounts and proceed with fetching the data etc.

Say for an example we have 2 separate account AdWords1 and Adwords2. How do we get access to these different accounts in code. I understand they have to give access our account somehow, but I don't get the process correctly and how it can be implemented in a background running program.

If you could help me in providing some details on this, that will be really helpful.

Thanks,
Bikram.

Takeshi Hagikura (AdWords API Team)

unread,
Nov 8, 2013, 1:08:43 AM11/8/13
to adwor...@googlegroups.com, Bikram Keshari Bhuyan
HI Bikram,

Glad to hear your issue has resolved. 

As for the next question, I'm assuming following account structures. 

MCC1 
 | -- AdWords1
 | -- AdWords2

If client accounts are linked to the MCC, getting a refresh token is required only once. 
You can use the same credential of MCC1 when you access to AdWords1 and AdWords2. 

So once, you need to get a refresh token manually like opening a web browser and grant your application access to your MCC data. 
Then store the refresh token, you can use the same refresh token for both AdWords1 and AdWords2. 
(if you use one of our client libraries, it automatically refresh expires access tokens. Note: An access token expires in one hour)

Does that answer your question?

Best,
- Takeshi, AdWords API Team

Bikram Bhuyan

unread,
Nov 8, 2013, 12:18:31 PM11/8/13
to adwor...@googlegroups.com, Bikram Keshari Bhuyan
Hi Takeshi,

Thanks for your detailed explanation. You are absolutely right. If both the accounts are under our MCC account then everything should work fine as you mentioned. I am trying to connect to our clients AdWords account which will definitely be not under our MCC account. So I am trying to figure out what will be the best mechanism to implement it.

Also please let me know what is the durability of our refresh token. Will not ever change after we give access and generate it.

Thanks,
Bikram.

Takeshi Hagikura (AdWords API Team)

unread,
Nov 12, 2013, 2:43:24 AM11/12/13
to adwor...@googlegroups.com, Bikram Keshari Bhuyan
Hi Bikram,

If the accounts are not linked to your MCC, you need to get a separate access token (and a refresh token) for each client account. 
In that case, I think an installed application mechanism is not practical because it requires manual process for each account. 

You can use the web application flow by preparing a web server that doesn't require manual process in your side when a client grants your application access to their data. 


> Also please let me know what is the durability of our refresh token. Will not ever change after we give access and generate it.
A refresh token never expires unless you explicitly revoke the access. 

Best,
- Takeshi, AdWords API Team

Christian Gibbs

unread,
Dec 10, 2013, 10:01:29 AM12/10/13
to adwor...@googlegroups.com, Bikram Keshari Bhuyan
I am trying to access accounts that are not linked to our MCC by the consent of the user.

It first starts here,

$user = new AdWordsUser();
$user->SetOAuth2Info(array(
   "response_type" => 'code',
   "client_id" => $clientId,
   "client_secret" => $clientSecret,
   "access_token" => $access, 
   "refresh_token" => $refresh,
   "scope" => 'offline'
));
$params = array(
   "response_type" => 'code',
   "client_id" => $clientId,
   "client_secret" => $clientSecret,
   "access_token" => $access, 
   "refresh_token" => $refresh,
   "scope" => 'offline'
);
 
/*
 *  public function GetAuthorizationUrl(array $credentials,
      $redirectUri = NULL, $offline = NULL, array $params = NULL) {
      */
 
// Generate an authorization URL given the callback URL
try{
$OAuth2Handler = $user->GetOAuth2Handler();
$OAuth2Handler->scope = 'https://adwords.google.com/api/adwords/';
print_r( $OAuth2Handler );
$authUrl = $OAuth2Handler->GetAuthorizationUrl($params, $callbackUrl, true, null);
}catch( Exception $e ){
print_r($e->getMessage());
}
 
header("Location: $authUrl");



Then it takes you to the consent page.

After login is successful,


Not sure if I need to set scope = 'offline' Paul Matthews said something about that but wasnt clear. There is another scope but it is a URL so I dont know what hes talking about. Maybe you can shed some light on that.

Anyway, the callback url runs this code,


$user = new AdWordsUser();
$user->SetOAuth2Info(array(
   "response_type" => 'code',
   "client_id" => $clientId,
   "client_secret" => $clientSecret,
   "access_token" => $access, 
   "refresh_token" => $refresh,
   "scope" => 'offline'
));
$authCode = $_REQUEST["code"];
//GetOAuth2Credential function copied below

$oauth2Info = $this->Google_model->GetOAuth2Credential($user, $authCode, $callbackUrl);
$user->SetOAuth2Info($oauth2Info);
$user->SetAuthToken( $authCode );
 




function GetOAuth2Credential($user, $code, $redirectUri = NULL) {
  
 $offline = TRUE;
 // Get the authorization URL for the OAuth2 token.
 // No redirect URL is being used since this is an installed application. A web
 // application would pass in a redirect URL back to the application,
 // ensuring it's one that has been configured in the API console.
 // Passing true for the second parameter ($offline) will provide us a refresh
 // token which can used be refresh the access token when it expires.
 $OAuth2Handler = $user->GetOAuth2Handler();
 $authorizationUrl = $OAuth2Handler->GetAuthorizationUrl(
     $user->GetOAuth2Info(), $redirectUri, $offline);
 // In a web application you would redirect the user to the authorization URL
 // and after approving the token they would be redirected back to the
 // redirect URL, with the URL parameter "code" added. For desktop
 // or server applications, spawn a browser to the URL and then have the user
 // enter the authorization code that is displayed.
 printf("Log in to your AdWords account and open the following URL:\n%s\n\n",
     $authorizationUrl);
 //print "After approving the token enter the authorization code here: ";
 
 // Get the access token using the authorization code. Ensure you use the same
 // redirect URL used when requesting authorization.
 $user->SetOAuth2Info(
$OAuth2Handler->GetAccessToken(
   $user->GetOAuth2Info(), $code, $redirectUri));
 // The access token expires but the refresh token obtained for offline use
 // doesn't, and should be stored for later use.
 return $user->GetOAuth2Info();
}





I still get the alert, [AuthorizationError.USER_PERMISSION_DENIED @ ; trigger:'']

Christian Gibbs

unread,
Dec 10, 2013, 2:50:40 PM12/10/13
to adwor...@googlegroups.com, Bikram Keshari Bhuyan
I GOT IT!!!!!!!!!



After getting the ?code=   from the URL


   $params = array(
"code" => $authCode,
"client_id" => $clientId,
"client_secret" => $clientSecret,
"redirect_uri" => $callbackUrl,
"grant_type" => "authorization_code"
   );
 
   $curl = curl_init();
   curl_setopt($curl, CURLOPT_URL, $url);
   curl_setopt($curl, CURLOPT_HEADER, false);
   curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
   curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
   curl_setopt($curl, CURLOPT_POST, true);
   curl_setopt($curl, CURLOPT_POSTFIELDS, $params);
   curl_setopt($curl, CURLOPT_ENCODING, "");
   $curlData = curl_exec($curl);
   curl_close($curl);
$result = json_decode ($curlData);
print_r( $result );
 
$access_token = $result->access_token;



$user = new AdWordsUser();
$user->SetOAuth2Info(array(
   "client_id" => $clientId,
   "client_secret" => $clientSecret,
   "access_token" => $access_token,
   "refresh_token" => ""
));

I save the Auth Info and I was able to pull the other account data!

Takeshi Hagikura (AdWords API Team)

unread,
Dec 11, 2013, 8:01:52 PM12/11/13
to adwor...@googlegroups.com, Bikram Keshari Bhuyan
Great. Thanks for sharing. 

Best,
- Takeshi, 

adwmc...@gmail.com

unread,
Feb 12, 2014, 2:13:38 AM2/12/14
to adwor...@googlegroups.com, Bikram Keshari Bhuyan

Dear Bikram and Takeshi,

I'm new to Adwords API and I'm having the same problem.

I have following accounts now. (all emails are dummy)

·         produc...@gmail.com (production MCC account) and clie...@gmail.com client account created under mentioned MCC account

·         tes...@gmail.com (MCC Test account) and testc...@gmail.com client account created under mentioned MCC Test account

 

1.       Which account should I use to get OAuth2 details?

2.       Which account should I use to get the developer token?

3.       Which account should I used as client Customer to get clientCustomerId?

Thanks,
Kasun

Bikram Bhuyan

unread,
Feb 12, 2014, 2:13:46 AM2/12/14
to adwmc...@gmail.com, adwor...@googlegroups.com
Hi Kasun,

I believe there is no concept of Test MCC account. Always we have the production MCC account where the developer token is pending if it is not approved till now. Could you please confirm this scenario. Also please confirm if you see the TEST Client account under the MCC account. 

If you see the TEST Client account under MCC then you can use either of the email to generate the token and then specify the customer account of the test client to access the data. If you dont see the test client account under MCC then you have to use the test client account to generate the oauth.

And always remember, the developer token belongs to the MCC account (not to any client account).

Hope this information helps. If you need more details, then please let us know more description about the linking of MCC and Client account.

Thanks,
Bikram.

adwmc...@gmail.com

unread,
Feb 12, 2014, 3:32:47 AM2/12/14
to adwor...@googlegroups.com, Bikram Keshari Bhuyan

Hi Bikram,

Thanks for the info. I tried as you sugested.

Below are my steps

  1. I logged in to my live adwords client account (not the mcc account).
  2. I logged in to the API console at https://cloud.google.com/console/ using the same email
  3. I created a OAuth client and got the client ID and Client secret
  4. Then I used the https://accounts.google.com/o/oauth2/auth?client_id=CLIENT_ID&response_type=code&scope=https%3A%2F%2Fadwords.google.com%2Fapi%2Fadwords%2F&redirect_uri=urn:ietf:wg:oauth:2.0:oob&access_type=offline&approval_prompt=auto
    to generate the code.
  5. Then I used that code in the GetRefreshToken.php file and ran it, and got the refresh token.
  6. Then I pasted that in to the auth.ini file.
  7. I got the developer token from the person who is handling the Adwords account and pasted it to developerToken
  8. Then I added the email to the userAgent in the same auth.ini
  9. I added the client id and client secret generated on the step 3
  10. And I ran the file GetKeywordIdeas.php file.

I got the following error.

An error has occurred: [QuotaCheckError.INVALID_TOKEN_HEADER @ ; trigger:'MY_DEVELOPER_TOKEN]


What is I'm doing wrong. Please help.

Mcc Test

unread,
Feb 12, 2014, 5:40:07 AM2/12/14
to Bikram Bhuyan, adwor...@googlegroups.com
Dear Bikram,

Really sorry for bugging. What has happen was, person who handles the MCC account has given me wrong developer token. He had typed B instead for 6. I can't understand why he haven't copy and pasted it.
Thank you very much for help.

Thanks
Kasun


On Wed, Feb 12, 2014 at 3:17 PM, Mcc Test <adwmc...@gmail.com> wrote:
I found a article on google and it had this Test MCC account procedure.https://developers.google.com/adwords/api/docs/test-accounts?hl=fr

The Client account I use to test is visible under the MCC account. I used the email of the Client Account and created the OAuth details and added them to the auth.ini
And then I used that OAuth Client Id in the https://accounts.google.com/o/oauth2/auth?client_id=CLIENT_ID&response_type=code&scope=https%3A%2F%2Fadwords.google.com%2Fapi%2Fadwords%2F&redirect_uri=urn:ietf:wg:oauth:2.0:oob&access_type=offline&approval_prompt=auto this url and got the pass code.

Then I pasted it to the getRefreshToken.php and got the refresh token. And I ran the file GetKeywordIdeas.php file.


I got the following error.

An error has occurred: [QuotaCheckError.INVALID_TOKEN_HEADER @ ; trigger:'MY_DEVELOPER_TOKEN]

Mcc Test

unread,
Feb 12, 2014, 4:47:55 AM2/12/14
to Bikram Bhuyan, adwor...@googlegroups.com
I found a article on google and it had this Test MCC account procedure.https://developers.google.com/adwords/api/docs/test-accounts?hl=fr

The Client account I use to test is visible under the MCC account. I used the email of the Client Account and created the OAuth details and added them to the auth.ini
And then I used that OAuth Client Id in the https://accounts.google.com/o/oauth2/auth?client_id=CLIENT_ID&response_type=code&scope=https%3A%2F%2Fadwords.google.com%2Fapi%2Fadwords%2F&redirect_uri=urn:ietf:wg:oauth:2.0:oob&access_type=offline&approval_prompt=auto this url and got the pass code.

Then I pasted it to the getRefreshToken.php and got the refresh token. And I ran the file GetKeywordIdeas.php file.

I got the following error.

An error has occurred: [QuotaCheckError.INVALID_TOKEN_HEADER @ ; trigger:'MY_DEVELOPER_TOKEN]

On Wed, Feb 12, 2014 at 12:43 PM, Bikram Bhuyan <bikram...@gmail.com> wrote:

micde...@gmail.com

unread,
May 6, 2014, 11:47:20 PM5/6/14
to adwor...@googlegroups.com, Bikram Keshari Bhuyan
hi,Takeshi
   I got same troubles.I called the api against a test account.
   You noticed that " you need to make sure the client account is linked to the MCC account with which you got your OAuth2 credential" and i found this "You cannot link a test MCC account or a test AdWords account with a production MCC account, or vice versa" on the test account doc,i am a little confused,could you help me?

Josh Radcliff (AdWords API Team)

unread,
May 7, 2014, 11:40:44 AM5/7/14
to adwor...@googlegroups.com, Bikram Keshari Bhuyan
Hi,

This is a common point of confusion -- a developer token can be used to issue requests against any AdWords account (regardless of the accounts linked to the token's MCC) with the restriction that a pending developer token can only be used for requests on a test account.  Of course, if you issue a request against an AdWords account for which your OAuth credentials do not grant access, the request will fail.

In your case, you do not (and you can not) link your test accounts with your production MCC.  Instead, you should obtain a refresh token while logged in as your test account, and then use that in combination with your production MCC's developer token to make your API requests.

Cheers,
Josh, AdWords API Team

Iuliya Echevarria

unread,
Feb 23, 2015, 5:58:41 PM2/23/15
to adwor...@googlegroups.com, bikram...@gmail.com
Hi Bikram, I am wondering if you made that work ( I mean, if you could access Adword accounts that are not related to any MCC)

I am new to adwords api and I can not find anywhere a confirmation of if it is possible to access a separated adwords account using adwords api 

If this is possible I would like to know:
- do I need to have a production mcc token?
- what clientCustomerId I need to specify?
- what happen if the customerId specified is different from the oauth credentials?

Bikram Bhuyan

unread,
Feb 23, 2015, 7:16:10 PM2/23/15
to Iuliya Echevarria, adwor...@googlegroups.com
Hi Luliya,

Yah it is working fine at our end. Yes, it is common to go though the initial analysis as it is little confusing to get our head around how it really work.

Below are the steps we have to follow.
1. First you should have your production MCC account. After you that you can register your OAuth account which will give you ("oAuthClientId" & "oAuthClientSecret").
2. Also I hope you must have your "developerToken". This is required to connect to the API.

After this is done, you have to register the OAuth process where the client can visit your page and give access to the above OAuth account.
This step will generate "oAuthRefreshToken".

Please note that "oAuthClientId", "oAuthClientSecret" & "developerToken" will be common for your application which you can store in your config file. But "oAuthRefreshToken" will be unique for each client who give access to register against your MCC account.

After the registration is complete, you can use "oAuthRefreshToken" & "CustomerId" to make the API call. I hope this will give you the steps which need to be followed.

Let me know if you still have any questions.

Thanks,
Bikram.

Sofia Agboatwalla

unread,
Mar 10, 2015, 6:28:45 PM3/10/15
to adwor...@googlegroups.com, iechev...@gmail.com
Hi Bikram,

I am trying to send data to other Adwords accounts which are not related to my MCC.


You wrote:
"After this is done, you have to register the OAuth process where the client can visit your page and give access to the above OAuth account.
This step will generate "oAuthRefreshToken"."

Can you  give me details on the above note? How do we register the OAuth process? Which page does the client need to visit for giving access to us?
 

Currently, I am using my own "oAuthRefreshToken" in the API call and hence am seeing this seeing  [AuthorizationError.USER_PERMISSION_DENIED @ ; trigger:''] returned from Adwords.

Thanks for for help.

Josh Radcliff (AdWords API Team)

unread,
Mar 11, 2015, 12:58:43 AM3/11/15
to adwor...@googlegroups.com, iechev...@gmail.com
Hi,

If the AdWords accounts you are trying to access are not linked to your MCC, then you can still access those accounts via the API but you will need to get a separate refresh token for each account using the OAuth flow described in our Authentication guide.

Once you have a refresh token for an account, you can use that to generate access tokens as needed. If you are using one of our client libraries, please see the list of OAuth utilities that will help you with this process.

Thanks,
Josh, AdWords API Team
Reply all
Reply to author
Forward
0 new messages