Im building an app with google ads api using a service account auth flow (server to server).

The problem: the auth part is not working... I keep getting a 401 error.

Sample of the request:

const request = require('request'); .... request({   'method': 'GET',   'url': 'https://googleads.googleapis.com/v6/customers/XXXXXXXX',   'headers': {     'Authorization': 'Bearer XXXXXXXX',     'developer-token': 'XXXXXXXX',     'Content-Type': 'application/json'   } }) ... 

or

curl --location --request GET 'https://googleads.googleapis.com/v6/customers/XXXXXXXX' \ --header 'Authorization: Bearer XXXXXXXX' \ --header 'developer-token: XXXXXXXX' \ --header 'Content-Type: application/json' 

[ERROR] Response from google ads api:

{         "code": 401,         "message": "Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",         "status": "UNAUTHENTICATED"     } 

I cant seem to find out why Im getting this authentication error.

What I have tried:

  1. Following this guide step by step -> https://developers.google.com/google-ads/api/docs/oauth/service-accounts
  2. Using the python library -> https://github.com/googleads/googleads-python-lib
  3. Using the google ads API with REST (no library)
  4. On localhost server
  5. On the production server (the www.g-suite.com domain linked to the account)

Whatever method or environment I try, it results in the same error.

Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential 

Steps I have implemented:

  • Created a google ads manager account
  • Generated a valid developer token for that account
  • Created project in Google cloud platform
  • Opened a service account inside the project
  • Created a private key for the service account
  • Granting impersonation abilities in the G Suite domain for this scope: https://www.googleapis.com/auth/adwords
  • Enabled domain-wide delegation on the service account
  • Generated the access token with the key json file.

Generating the access token:

const { google } = require('googleapis'); const getAccessToken = async () => {     const SCOPES = ['https://www.googleapis.com/auth/adwords'];     const authClient = new google.auth.GoogleAuth({         keyFile: './pathtokeyfile.json',         scopes: SCOPES,     });     const token = await authClient.getAccessToken();     return token; }; 

I am surely missing something, but am not sure what it is..

Will be super grateful if someone can share a solution!! thanks champs 👍

Tag:google-ads-api, google-api, google-cloud-platform, service-accounts

Only one comment.

  1. Raymen

    ** NOT_ADS_USER SOLVED *** !!!

    Now it's all working.

    Turns out I was not creating the token precisely the correct way.

    Here's a sample of the code I use to generate the correct access token in NodeJs:

    const private_key = require('./key.json').private_key; const token = jwt.sign( { iss: SERVICE_ACCOUNT_EMAIL, sub: GOOGLE_MMC_MANAGER_EMAIL, scope: 'https://www.googleapis.com/auth/adwords', aud: 'https://oauth2.googleapis.com/token', exp: Math.round(Date.now() / 1000) + 3600, iat: Math.round(Date.now() / 1000), }, private_key, { algorithm: 'RS256' }, ); // console.log(token); try { const response = await http.post('https://oauth2.googleapis.com/token', { grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer', assertion: token, }); const accesstoken = response.data; console.log(accesstoken); } catch (error) { console.log(error.data); } };

    I was missing this part in signing the token: sub: GOOGLE_MMC_MANAGER_EMAIL,

    GOOGLE_MMC_MANAGER_EMAIL is the email that you created the MMC account with.

Add a new comment.