in reply to Coinbase API

This fixed version works for me:

use Modern::Perl; use LWP::UserAgent; use JSON; use Digest::SHA qw(hmac_sha256_base64 hmac_sha256_hex hmac_sha256); use MIME::Base64; use Time::Piece; my $uri = 'https://api-public.sandbox.pro.coinbase.com'; my $api_key = '6dc071df2d42724c019f79a53464d006'; my $secret = 'vjYZFn39LEFfbJ5z9QzdWt+HsahYTPvXInoYMD9Gq754FJL0evlG +nHcTiaaITGF+6GfbyYnxoyCXji9OR1iEMw=='; my $passphrase = "There is no passphrase.", my $now = gmtime; my $timestamp = $now->datetime . ".000000Z"; my $request_method = "GET"; my $request_path = '/products'; my $body = ''; my $message = $timestamp . $request_method . $request_path . $b +ody; my $decoded_secret = decode_base64($secret); my $signature_b64 = encode_base64( hmac_sha256($message, $decoded_secr +et) ); chomp($signature_b64); my $ua = LWP::UserAgent->new; $ua->agent ('Stock/1.0'); my $res = $ua->get( "$uri$request_path", 'CB-ACCESS-SIGN' => $signature_b64, 'CB-ACCESS-TIMESTAMP' => $timestamp, 'CB-ACCESS-KEY' => $api_key, 'CB-ACCESS-PASSPHRASE' => $passphrase, 'Content-Type' => 'application/json' ); if ($res->is_success) { say $res->decoded_content; } else { say "request failed."; say "status:", $res->as_string; }

Note that I've made the following changes:

  1. Fixed the timestamp to meet their version of the ISO 8601 format
  2. Added in the path to the URI requested
  3. Changed the user agent to one not banned by the server
  4. Dumped the entire error page so you can see why it was forbidden (which directly led me to fix number 3)

Replies are listed 'Best First'.
Re^2: Coinbase API
by Your Mother (Archbishop) on Jul 05, 2018 at 08:41 UTC

    I was messing with this too. Couple questions/considerations.

    /products has no signature/request requirements. It responds with full data successfully with a bare GET.

    Their spec says two things about dates. All timestamp are returned in ISO8601 format in UTC with fields ending in postfix _at. Example: "created_at": "2015-07-01T00:55:47Z" but also The CB-ACCESS-TIMESTAMP header MUST be number of seconds since Unix Epoch. When I change your code to try /user instead of /products this is the response–

    {"message":"invalid timestamp"}

      Good spot! I'm not even passingly familiar with this particular API so only skimmed enough of the docs to spot potential problems. I'm sure ownlifeful will know more about what is actually required.

      Backing out my timestamp changes and trying /user as the path I now get

      {"message":"Invalid API Key"}

      which could just be because the key isn't allowed access to that path or the key is incorrect or badly manipulated or ...

      Hopefully this gives ownlifeful something to go on, anyway.

        Nice. That's where I landed too, Invalid...

        It's fun. I like this kind of code and you helped me jump in easily on this one.

        Yes, now I do have something to go on. I can't thank you enough. :)

        You might be getting "Invalid API Key" messages, because I revoked that particular key on Coinbase.

Re^2: Coinbase API
by ownlifeful (Beadle) on Jul 04, 2018 at 22:28 UTC

    Thank you! You sure fixed it. I did look at the full response, but it never occurred to me that particular user-agents would be banned.