title: 400 Bad Request when using Google.Apis.Analytics.v3
body: <p>I'm trying to connect to Google Analytics to retrieve some information and put it into the database, my code, thus far, is this:</p>
  
  <pre><code>using System;
  using System.Collections.Generic;
  using System.IO;
  using System.Linq;
  using System.Net;
  using System.Security.Cryptography.X509Certificates;
  using System.Text;
  using System.Threading.Tasks;
  
  // Google API
  using DotNetOpenAuth.Messaging;
  using DotNetOpenAuth.OAuth2;
  using Google.Apis.Analytics.v3;
  using Google.Apis.Analytics.v3.Data;
  using Google.Apis.Authentication.OAuth2;
  using Google.Apis.Authentication.OAuth2.DotNetOpenAuth;
  using Google.Apis.Services;
  using Google.Apis.Util;
  
  
  namespace CCQ.GoogleToSharePoint
  {
      class Program
      {
          static void Main(string[] args)
          {
              //This is the API url which we're storing to a string
              string scope = AnalyticsService.Scopes.AnalyticsReadonly.GetStringValue();
  
              //For whatever reason, this is labelled wrong. It is the email address
              //that you have added as a user to your Analytics account
  
              string clientId = "&lt;redacted&gt;@gmail.com";
  
  
              //This is the physical path to the file we downloaded earlier
              //To demonstrate this, I've kept the full path to my key file.
              //Obviously, you will need to change this to match where you've
              //stored yours.
              string keyFile = @"&lt;redacted&gt;";
  
              //The password Google gives you, probably the same as the one below
              string keyPassword = "notasecret";
  
  
              //Store the authentication description
              AuthorizationServerDescription desc = GoogleAuthenticationServer.Description;
  
              //Create a certificate object to use when authenticating
              X509Certificate2 key = new X509Certificate2(keyFile, keyPassword, X509KeyStorageFlags.Exportable);
  
              //Now, we will log in and authenticate, passing in the description
              //and key from above, then setting the accountId and scope
              AssertionFlowClient client = new AssertionFlowClient(desc, key)
              {
                  ServiceAccountId = clientId,
                  Scope = scope
              };
  
              //Finally, complete the authentication process
              //NOTE: This is the first change from the update above
              OAuth2Authenticator&lt;AssertionFlowClient&gt; auth =
                  new OAuth2Authenticator&lt;AssertionFlowClient&gt;(client, AssertionFlowClient.GetState);
  
              //First, create a new service object
              //NOTE: this is the second change from the update
              //above. Thanks to James for pointing this out
              AnalyticsService gas = new AnalyticsService(new BaseClientService.Initializer() { Authenticator = auth });
  
              //Create our query
              //The Data.Ga.Get needs the parameters:
              //Analytics account id, starting with ga:
              //Start date in format YYYY-MM-DD
              //End date in format YYYY-MM-DD
              //A string specifying the metrics
              DataResource.GaResource.GetRequest r = gas.Data.Ga.Get("ga:&lt;redacted&gt;", "2013-09-09", "2013-09-23", "ga:visitors");
  
              //Specify some addition query parameters
              r.Dimensions = "ga:visitorType";
              r.Sort = "-ga:visitors";
              r.MaxResults = 5;
  
              //Execute and fetch the results of our query
              try
              {
                  //Write the column headers
                  GaData d = r.Execute();
  
                  foreach (var h in d.ColumnHeaders)
                  {
                      Console.WriteLine(h.Name);
                  }
  
                  //Write the data
                  foreach (var row in d.Rows)
                  {
                      Console.WriteLine(row[0] + " ------ " + row[1]);
                  }
              }
              catch (ProtocolException webEx)
              {
                  Console.WriteLine("Protocol Exception: {0}\n\n", webEx.ToString());
                  Console.WriteLine("Stack Trace: {0}", webEx.StackTrace);
  
                  throw;
              }
  
          }
      }
  }
  </code></pre>
  
  <p>Unfortunately I'm throwing an error on my execute line, this one specifically:</p>
  
  <pre><code>//Write the column headers
  GaData d = r.Execute();
  </code></pre>
  
  <p>The error itself is:</p>
  
  <blockquote>
    <p>Error occurred while sending a direct message or getting the response.</p>
  </blockquote>
  
  <p><a href="https://developers.google.com/analytics/devguides/reporting/core/v2/gdataReferenceDataFeed" rel="nofollow">Google's API documentation</a> says that a 400:Bad Response header will be sent under the following conditions:</p>
  
  <blockquote>
    <p>400 Bad Request Types of bad requests include:</p>
    
    <ul>
    <li><p>Invalid dimensions and/or metrics</p></li>
    <li><p>Quantity: either no metric, or too many dimensions/metrics</p></li>
    <li><p>Using OR on a filter where one side is a metric and the other a    dimension</p></li>
    <li><p>Invalid filter/segment syntax</p></li>
    <li><p>Illegal dimension/metric combination or advanged segment</p></li>
    </ul>
  </blockquote>
  
  <p>However from what I've seen I don't meet any of those - so I'm eternally confused. How can I further go about debugging this issue?</p>
  
  <p>The stack trace for this error is:</p>
  
  <blockquote>
    <p>StackTrace    "   at
    Google.Apis.Requests.ClientServiceRequest`1.Execute() in
    c:\code.google.com\google-api-dotnet-client\default_3\Tools\Google.Apis.Release\bin\Debug\output\default\Src\GoogleApis\Apis\Requests\ClientServiceRequest.cs:line
    96\r\n   at CCQ.GoogleToSharePoint.Program.Main(String[] args) in
    i:\dev\CCQ.GoogleToSharePoint\CCQ.GoogleToSharePoint\Program.cs:line
    121\r\n   at System.AppDomain._nExecuteAssembly(RuntimeAssembly
    assembly, String[] args)\r\n   at
    System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence
    assemblySecurity, String[] args)\r\n   at
    Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()\r\n 
    at System.Threading.ThreadHelper.ThreadStart_Context(Object state)\r\n
    at System.Threading.ExecutionContext.RunInternal(ExecutionContext
    executionContext, ContextCallback callback, Object state, Boolean
    preserveSyncCtx)\r\n   at
    System.Threading.ExecutionContext.Run(ExecutionContext
    executionContext, ContextCallback callback, Object state, Boolean
    preserveSyncCtx)\r\n   at
    System.Threading.ExecutionContext.Run(ExecutionContext
    executionContext, ContextCallback callback, Object state)\r\n   at
    System.Threading.ThreadHelper.ThreadStart()"  string</p>
  </blockquote>