title: Coinbase API Invalid Signature error when using Create Address PHP curl request
body: <p>From the Coinbase API documentation, to create a new address:</p>
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-html lang-html prettyprint-override"><code>curl https://api.coinbase.com/v2/accounts/82de7fcd-db72-5085-8ceb-bee19303080b/addresses \
    -X POST \
    -H 'Content-Type: application/json' \
    -H 'Authorization: Bearer abd90df5f27a7b170cd775abf89d632b350b7c1c9d53e08b340cd9832ce52c2c' \
    -d '{"name": "New receive address"}'</code></pre>
  </div>
  </div>
  </p>
  <p>Here's my curl request in PHP:</p>
  <pre><code>private function api_settings($request_path, $method, $options = [])
  {
      $api_url = &quot;https://api.coinbase.com&quot;;
      $secret = $this-&gt;api_secret;
      $timestamp = json_decode(file_get_contents(&quot;https://api.coinbase.com/v2/time&quot;), true)[&quot;data&quot;][&quot;epoch&quot;];;
      $url = $api_url . $request_path;
  
      $string = $timestamp . $method . $request_path;
      $sig = hash_hmac(&quot;sha256&quot;, $string, $secret);
  
      $ch = curl_init();
      curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
      curl_setopt($ch, CURLOPT_URL, $url);
  
      curl_setopt($ch, CURLOPT_VERBOSE, true);
  
      if ($method == &quot;POST&quot;) {
          curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
          curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($options));
          curl_setopt($ch, CURLOPT_POST, TRUE);
  
      } elseif($method == &quot;PUT&quot;) {
          curl_setopt($ch, CURLOPT_CUSTOMREQUEST, &quot;PUT&quot;);
          // curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($options));
      }
  
      $headers = [
          &quot;CB-ACCESS-KEY: $this-&gt;api_key&quot;,
          &quot;CB-ACCESS-SIGN: $sig&quot;,
          &quot;CB-ACCESS-TIMESTAMP: $timestamp&quot;,
          &quot;CB_VERSION: 2022-03-12&quot;,
          &quot;accept: application/json;charset=utf-8&quot;
      ];
  
      curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
      return curl_exec($ch);
  }
  </code></pre>
  <p>Here's how I try to call the <code>api_settings()</code>:</p>
  <pre><code>$api_settings = $this-&gt;api_settings('/v2/accounts/' . $this-&gt;account_id . '/addresses', 'POST', array('name' =&gt; $this-&gt;label));
      $result = \GuzzleHttp\json_decode($api_settings, true);
  </code></pre>
  <p>I do it by passing an array as an optional function parameter for the <code>POST</code>.</p>
  <p>This always returns <code>{&quot;errors&quot;:[{&quot;id&quot;:&quot;authentication_error&quot;,&quot;message&quot;:&quot;invalid signature&quot;}]}</code> no matter what I do. I've tried using both <code>json_encode</code> and <code>http_build_query</code> for <code>CURLOPT_POSTFIELDS</code> and it still doesn't work.</p>
  <p>What could be wrong here?</p>