title: Why do I keep getting 403 User does not have sufficient permission for this profile error from Analytics API
body: <p>EDIT: Also I have read the following posts on Stack Overflow, but I don't think they have the solution I am looking for:</p>
  
  <p><a href="https://stackoverflow.com/questions/17714515/google-analytics-throws-403-error">Google Analytics throws 403 error</a>
  <a href="https://stackoverflow.com/questions/20959942/google-analytics-api-user-does-not-have-sufficient-permissions-for-this-accoun">Google Analytics API: &quot;User does not have sufficient permissions for this account.&quot;</a></p>
  
  <p>I am creating an installed application in C# to access and display my Google Analytics Data.</p>
  
  <p>I have read Google's documentation for OAuth v2.0 and the Analytics v3 API, and I cannot retrieve my analytics data. Here is what I have done so far.</p>
  
  <ol>
  <li><p>Navigate to the following URL in a Web Browser where I am prompted to log in to my Google Account (the account that owns the Analytics Account and has full ownership and permission) or if my browser has saved my login, an accept screen comes up asking me to confirm that I want to allow the app to access my analytics data. Here is the URL:
  <code>https://accounts.google.com/o/oauth2/auth?redirect_uri=urn:ietf:wg:oauth:2.0:oob&amp;response_type=code&amp;client_id=XXXXXX.apps.googleusercontent.com&amp;scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fanalytics.readonly&amp;approval_prompt=force&amp;access_type=offline");</code></p></li>
  <li><p>After the code is successfully returned and retrieved from the browser title window as the OAuth 2.0 documentation specifies for installed applications, I take this code and Create the following request which successfully returns an access token:</p>
  
  <pre><code>    WebRequest request = WebRequest.Create("https://accounts.google.com/o/oauth2/token");
      string body = String.Format("code={0}&amp;client_id=XXXXXXXXXXX.apps.googleusercontent.com&amp;client_secret=XXXXXXXXXXX&amp;redirect_uri=urn:ietf:wg:oauth:2.0:oob&amp;grant_type=authorization_code"
          ,browser.OAuthCode);
      request.Method = "POST";
      byte[] reqBytes = Encoding.UTF8.GetBytes(body);
      request.ContentType = "application/x-www-form-urlencoded";
      request.ContentLength = reqBytes.Length;
      request.GetRequestStream();
      Stream stream = request.GetRequestStream();
      stream.Write(reqBytes, 0, (int)request.ContentLength);
  
      WebResponse response = request.GetResponse();
      Stream s = response.GetResponseStream();
      StreamReader sr = new StreamReader(s);
  
      string json = sr.ReadToEnd();
  
      OAuthResponse tokenHolder = new OAuthResponse();
      tokenHolder = Newtonsoft.Json.JsonConvert.DeserializeObject&lt;OAuthResponse&gt;(json);
  
      return tokenHolder.AccessToken;
  </code></pre></li>
  <li><p>Finally, after successfully retrieving an access token, I create another Request to retrieve my analytics data like so:</p>
  
  <pre><code>public WebRequest ApiRequest()
  {
      string oAuthToken = OAuthToken();
  
  
      //need to change this so people can select different ones
      string idParam = "ids=ga:XXXXXX";
  
      startDate = "start-date=" + startDate;
      endDate = "end-date=" + endDate;
  
      string totalEventsMetric = "ga:totalEvents";
      string uniqueEventsMetric = "ga:uniqueEvents";
  
      string categoryDimension = "ga:eventCategory";
      string actionDimension = "ga:eventAction";
      string labelDimension = "ga:eventLabel";
  
      string parameters = "";
  
      if ((bool)this._showTotalEvents.IsChecked)
          parameters += "metrics=" + totalEventsMetric;
      if ((bool)this._shwoUniqueEvents.IsChecked)
          if (parameters != "")
              parameters += "," + uniqueEventsMetric;
          else
              parameters += "metrics=" + uniqueEventsMetric;
      if ((bool)this._showCategory.IsChecked)
          if (parameters != "")
              parameters += "&amp;dimensions=" + categoryDimension;
          else
              parameters += "dimensions=" + categoryDimension;
      if ((bool)this._showAction.IsChecked)
          if (parameters != "" &amp; parameters.Contains("dimensions"))
              parameters += "," + actionDimension;
          else if (parameters != "" &amp; !parameters.Contains("dimensions"))
              parameters += "&amp;dimensions=" + actionDimension;
          else
              parameters += "dimensions=" + actionDimension;
      if ((bool)this._showLabel.IsChecked)
          if (parameters != "" &amp; parameters.Contains("dimensions"))
              parameters += "," + labelDimension;
          else if (parameters != "" &amp; !parameters.Contains("dimensions"))
              parameters += "&amp;dimensions=" + labelDimension;
          else
              parameters += "dimensions=" + labelDimension;
  
      if (parameters != "")
      {
          parameters += "&amp;" + idParam;
          parameters += "&amp;" + startDate;
          parameters += "&amp;" + endDate;
      }
      else
      {
          parameters += idParam;
          parameters += "&amp;" + startDate;
          parameters += "&amp;" + endDate;
          parameters += "&amp;metrics=" + totalEventsMetric;
          parameters += "," + uniqueEventsMetric;
      }
  
      string url = string.Format("https://www.googleapis.com/analytics/v3/data/ga?{0}", parameters);
      WebRequest request = WebRequest.Create(url);
      request.Method = "GET";
      request.Headers.Add("Authorization: Bearer " + oAuthToken);
      return request;
  }
  </code></pre></li>
  </ol>
  
  <p>My url ends up looking something like this:</p>
  
  <p><code>https://www.googleapis.com/analytics/v3/data/ga?metrics=ga:totalEvents,ga:uniqueEvents&amp;dimensions=ga:eventCategory,ga:eventAction,ga:eventLabel&amp;ids=ga:XXXXX&amp;start-date=2013-12-01&amp;end-date=2014-01-01</code></p>
  
  <p>And my Header:</p>
  
  <p><code>{Authorization: Bearer oAuthTokenGoesHere}</code></p>
  
  <p>And the error I get every time:</p>
  
  <p><code>{"error":{"errors":[{"domain":"global","reason":"insufficientPermissions","message":"User does not have sufficient permissions for this profile."}],"code":403,"message":"User does not have sufficient permissions for this profile."}}</code></p>
  
  <p>I cannot figure out why I am getting this error when this is an installed program. I log into the actual account in the web browser that opens up before I click accept and retrieve the OAuth code to exchange for a token. I have tried adding the App Engine and Compute Engine email address form the developer's console to my analytics account using the web interface, but this does not help. There is no email address associated with client ids for installed applications either, presumably because you have to log in in a browser before you can get a code.</p>
  
  <p>I also tried passing the token in as a parameter instead of a header, but that did not work either.</p>
  
  <p>I am not sure what to do from here.</p>