title: How to query OData API using PHP with a API Key and API Secret? Getting 'No URL set!' curl error
body: <p>I am new to APIs and I am trying to create an application which would fetch some data from an OData API provided by Cornerstone OnDemand LMS. Its called Reporting API. The Cornerstone OnDemand documentation says, I need to obtain the API Key and API secret and then acquire the session token. It explains the process until generating the API session signature and provides a sample PHP code with it. However I am not sure how to go beyond that after the signature is generated. </p>
  
  <p>Here is the sample PHP code available in Cornerstone OnDemand documentation. </p>
  
  <pre><code>//signature to acquire a session
  $apiId = '&lt;insert Api ID&gt;';
  $apiSecret = '&lt;Insert API Secret&gt;';
  
  //build the string to sign
  //note the order of the entries is important.
  //The http headers must be in alphabetical order by key name
  $httpMethod = 'POST';
  $apiKey = 'x-csod-api-key:'.$apiId;
  $httpUrl = '/services/api/sts/session';
  
  date_default_timezone_set('UTC');
  $date = 'x-csod-date:'.date('Y-m-d').'T'.date('H:i:s').'.000';
  $stringToSign = $httpMethod."\n".$apiKey."\n".$date."\n".$httpUrl;
  
  /* produces the following string:
  *  POST\nx-csod-api-key:1lie8ficql9h5\nx-csod-date:2015-09-08T11:27:32.000\n/services/api/sts/session
  */
  
  //Generate the signature
  $secretKey = base64_decode($apiSecret);
  $signature = base64_encode(hash_hmac('sha512', $stringToSign, $secretKey, true));
  </code></pre>
  
  <p>I am not sure what to do after the signature is generated. A REST API sample C# code is available on the GitHub repository of Cornerstone OnDemand at <a href="https://github.com/csodedge/csod-rest-api-sample-code-POST" rel="nofollow noreferrer">https://github.com/csodedge/csod-rest-api-sample-code-POST</a> however I can't find anything that I could use for PHP.</p>
  
  <p>I look forward to some help from the StackOverflow community. I will be very grateful for any help. </p>
  
  <p>EDIT 1:
  After some research, I figured that I need to form the headers and use Curl to send the request. I have added the curl code, however I am now getting a bad request error. Here is the updated code. Any help is much appreciated.</p>
  
  <pre><code>//signature to acquire a session
      $apiId = '&lt;removed for safety&gt;';
      $apiSecret = '&lt;removed for safety&gt;';
  
      //build the string to sign
      //note the order of the entries is important.
      //The http headers must be in alphabetical order by key name
      $httpMethod = 'POST';
      $apiKey = 'x-csod-api-key:'.$apiId;
      $httpUrl = 'https://clientdomain.csod.com/services/api/sts/session?userName=clientuserid&amp;alias=jk01';
  
      date_default_timezone_set('UTC');
      $date = 'x-csod-date:'.date('Y-m-d').'T'.date('H:i:s').'.000';
      $stringToSign = $httpMethod."\n".$apiKey."\n".$date."\n".$httpUrl;
  
      //Generate the signature
      $secretKey = base64_decode($apiSecret);
      $signature = base64_encode(hash_hmac('sha512', $stringToSign, $secretKey, true));
  
      $crl = curl_init();
  
      curl_setopt($crl, CURLOPT_URL, $httpUrl); 
      curl_setopt($crl, CURLOPT_HTTPHEADER, array (
        'x-csod-api-key: '.$apiId,
        'x-csod-date: '.date('Y-m-d').'T'.date('H:i:s').'.000',
        'x-csod-signature: '.$signature
      ));
      curl_setopt($crl, CURLOPT_POST,true);
      $rest = curl_exec($crl);
      if ($rest === false)
      {
          // throw new Exception('Curl error: ' . curl_error($crl));
          print_r('Curl error: ' . curl_error($crl));
      }
  
      curl_close($crl);
      print_r($rest);
  </code></pre>
  
  <p>This code is now giving me the following error:</p>
  
  <p>Bad Request
  Your browser sent a request that this server could not understand.
  Reference #7.9dde387d.1532191458.b66f123 1</p>
  
  <p>Please help.</p>