Authorization troubles on Advanced Trading API

@lsoderman, would you be so kind to share your final code?

1 Like

This c# code that will get you connection and a “ticker” feed stream

this is a return data message
{“channel”:“ticker”,“client_id”:“”,“timestamp”:“2022-11-23T15:06:07.403532716Z”,“sequence_num”:0,“events”:[{“type”:“snapshot”,“tickers”:[{“type”:“ticker”,“product_id”:“SHIB-USD”,“price”:“0.0000089”,“volume_24_h”:“1272356720746”,“low_24_h”:“0.00000856”,“high_24_h”:“0.0000091”,“low_52_w”:“0.00000712”,“high_52_w”:“0.000055”,“price_percent_chg_24_h”:“3.24825986078886”}]}]}

the code

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WebSocketSharp;
using System.Security.Cryptography;

namespace Api_CB
{
    public class Program
    {
        public static void Main(string[] args)
        {
            using (var ws = new WebSocket("wss://advanced-trade-ws.coinbase.com"))
            {
                var TimeStamp = UTCtime();
                var Hstring = TimeStamp + "tickerSHIB-USD"; //string to sign
                ws.SslConfiguration.EnabledSslProtocols = System.Security.Authentication.SslProtocols.None;
                //ws.OnMessage += (sender, e) => Console.WriteLine(e.Data);
                ws.OnMessage += Ws_OnMSGReceived;
                subscribe_msg subscribe = new subscribe_msg("subscribe", "ticker", "", "", UTCtime(), CreateToken(Hstring));
                var jsonString = Newtonsoft.Json.JsonConvert.SerializeObject(subscribe);
                ws.Connect();

                ws.Send(jsonString);
                Console.ReadKey(true);
            }

             string UTCtime()
            {
                // Get the offset from current time in UTC time
                DateTimeOffset dto = new DateTimeOffset(DateTime.UtcNow);
                // Get the unix timestamp in seconds
                string unixTime = dto.ToUnixTimeSeconds().ToString();
                return unixTime;
            }

            string CreateToken( string data)
            {
                string key = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxyour secret key " 
                string hash;
                ASCIIEncoding encoder = new ASCIIEncoding();
                Byte[] code = encoder.GetBytes(key);
                using (HMACSHA256 hmac = new HMACSHA256(code))
                {
                    Byte[] hmBytes = hmac.ComputeHash(encoder.GetBytes(data));
                    hash = ToHexString(hmBytes);
                }
                return hash;
            }

            string ToHexString(byte[] array)
            {
                StringBuilder hex = new StringBuilder(array.Length * 2);
                foreach (byte b in array)
                {
                    hex.AppendFormat("{0:x2}", b);
                }
                return hex.ToString();
            }

        }
        // event handler on msg recived
        private static void Ws_OnMSGReceived(object sender, MessageEventArgs e)
        {
            Console.WriteLine(e.Data);
            //throw new NotImplementedException();
        }

        public class subscribe_msg
        {
            public string type { get; set; } 
            public List<string> product_ids { get; set; }
            public string channel { get; set; }
            public string api_key { get; set; }
            public string timestamp { get; set; }
            public string signature { get; set; }

            public subscribe_msg(string Type, string Channel, string Product_ids, string API_key, string Timestamp, string Signature)
            {
                this.type = Type;
                this.channel = Channel;
                this.product_ids = new List<string>() {"SHIB-USD"} ;
                this.api_key = "xxxxxxxxxxxxx"; // API_key here
                this.timestamp = Timestamp;
                this.signature = Signature;
            }
        }
    }
}

2 Likes

@lsoderman, I have the same trouble to do authentication. I always get “Unauthorized” error. Could you kindly share your code here? Thanks

1 Like

Here ya go

import requests
from requests.auth import AuthBase
import hmac
import hashlib
import time

key = 'xxxxxxxxxxxxx'
secret = 'xxxxxxxxxxxxxxxxxxxxxxxxxxx'
path = '/api/v3/brokerage/accounts'
base_url = 'https://coinbase.com'


class CBAuth(AuthBase):

    def __init__(self, secret, key, path):
        # setup any auth-related data here
        self.secret = secret
        self.key = key
        self.url = path

    def __call__(self, request):
        timestamp = str(int(time.time()))
        message = timestamp + request.method + self.url
        signature = hmac.new(self.secret.encode(
            'utf-8'), message.encode('utf-8'), digestmod=hashlib.sha256).digest()

        request.headers.update({
            'CB-ACCESS-SIGN': signature.hex(),
            'CB-ACCESS-TIMESTAMP': timestamp,
            'CB-ACCESS-KEY': self.key,
            'accept': "application/json"
        })
        return request


auth = CBAuth(secret, key, path)
url = base_url + path
response = requests.get(url, auth=auth)
print(response.text)
2 Likes

Hello.
I am getting unauthorized error when trying to get list of accounts.
Here is my code.

timestamp = str(int(time.time()))
method=“GET”
url_path=“/api/v3/brokerage/accounts”
body=“”
message = timestamp + method + url_path + body;
#hmac_key = base64.b64decode(API_SECRET);
#signature = hmac.new(hmac_key, message.encode(‘utf-8’), digestmod=hashlib.sha256)
#signature_b64 = base64.b64encode(signature.digest());
signature = hmac.new(API_SECRET.encode(‘utf-8’), message.encode(‘utf-8’), digestmod=hashlib.sha256).digest()
print(signature.hex())
url = “https://coinbase.com/api/v3/brokerage/accounts/
headers = {
“accept”: “application/json”,
“CB-ACCESS-KEY”: ACCESS_KEY,
“CB-ACCESS-SIGN”: signature.hex(),
“CB-ACCESS-TIMESTAMP”: timestamp
}

response = requests.get(url, headers=headers)
print(response)
print(response.text)

Anyone help me

Hello!
You have an extra / after accounts in the url, meaning the signature doesn’t match. It sees it as a different path. This should work for you:

timestamp = str(int(time.time()))
method = "GET"
url_path = "/api/v3/brokerage/accounts"
url = "https://coinbase.com/api/v3/brokerage/accounts"
body = ""
message = timestamp + method + url_path + body

signature = hmac.new(API_SECRET.encode(
    'utf-8'), message.encode('utf-8'), digestmod=hashlib.sha256).digest()
print(signature.hex())
headers = {
    "accept": "application/json",
    "CB-ACCESS-KEY": ACCESS_KEY,
    "CB-ACCESS-SIGN": signature.hex(),
    "CB-ACCESS-TIMESTAMP": timestamp
}

response = requests.get(url, headers=headers)
print(response)
print(response.text)

1 Like

Thanks for your reply.
I have already tried that but getting same error.

In that case, do you have the right permissions set for your key? Or did you perhaps assign them to the wrong variables? I just copy/pasted that code right after successfully testing it, so I’m sure it works.

There’s also the fact that the API is still in beta so it could be a problem there, or could be a problem with your account. Have you been able to call other endpoints successfully?

This is my API key screenshots.
I have selected all permissions.
But I can’t sure that I done correct.

All API calling get unauthorized error.

That looks right to me.
Just to be sure, when you set the variables in the code above, you have ACCESS_KEY = 'L3dr....', right? (or use env vars or whatever) If that doesn’t work, maybe try deleting that key and making a new one.

ACCESS_KEY variable is set correctly.
I don’t use env vars.
When for recreating api key, it takes 48 hours to get it working.
I don’t think that is the key problem.
I have tried with working key in v2.
But still getting unauthorized error.
Seems like the code problem. Header or something else.

Idk, I really don’t think it’s the code. The code works. My key worked instantly, so I really feel like it has to be the key, the permissions, or the variables. Unless your account is new? Then maybe it takes longer?

Unless your computer’s internal clock is off? I know sometimes having multiple OSs installed will mess with your system time. If your timestamp is off from Coinbase’s by 30 seconds (I think?) it will deny the request. Having the “wrong” system time could definitely mess that up.

I got the same error with the same code. Same frustrate here. When you figure out it, please share your fix.

Running into a new problem. Authentication is working on things such as products, and accounts. But trying to place an order I get a fail on authorization (401 error).

Using the same method for creating the signature, using the /api/v3/brokerage/orders endpoint.

I can’t figure out why this is acting differently.

Here’s the snippets of code. Note, the api_key and api_secret are kept in a settings file and so are identical anytime I use them.

Auth code:

api_key = Settings.api_key
api_secret = Settings.api_secret

class CBAuth(AuthBase):

    def __init__(self, api_secret,api_key, api_url):
        # setup any auth-related data here
        self.api_secret = api_secret
        self.api_key = api_key
        self.api_url = api_url
        print(api_secret, api_key, api_url)


    def __call__(self, request):
        timestamp = str(int(time.time()))
        message = timestamp + request.method + self.api_url
        signature =  hmac.new(api_secret.encode('utf-8'), message.encode('utf-8'), digestmod=hashlib.sha256).digest()

        request.headers.update({
            'CB-ACCESS-SIGN': signature.hex(),
            'CB-ACCESS-TIMESTAMP': timestamp,
            'CB-ACCESS-KEY': api_key,
            'accept': "application/json"

        })
        print(message)
        print(request.headers)
        return request

Relevant code to placing order:

    auth = KCAuth.CBAuth(api_secret, api_key, orderep)
    print(api_secret, api_key, orderep)

    print(api_url)
    print(orderep)
    print(api_url + orderep)
    r = requests.post(api_url + orderep, json=payload, auth=auth)#   .json()
    print(r)

api_url is ‘https://api.coinbase.com
orderep is “/api/v3/brokerage/orders”

The various print statements are for debugging. The response when I send this is

Response [401]

The auth is working for other functions, but not this.

The exchange/pro api has an endpoint for this exact reason btw. It’s public, so you could try hitting it for the timestamp before signing.
https://api.exchange.coinbase.com/time
It would rule that out at least.

@ZK_AW and @TrueCoder, you are both using python, yes? Can you also do javascript/node.js? I can send a working javascript function to test and rule out the code environment entirely.

1 Like

Do you have all permissions enabled on the API or just some? Some of them are confusing, like to place an order you need the wallet:buys/sells:create permission, not the wallet:orders:create permission which makes syntactical sense.

I have all endpoints enabled. And the auth works fine with the other endpoint (accounts and products), so I doubt it’s a timestamp issue. I actually forced it to update my product database immediately prior to testing just to make sure I was able to authenticate

I only know Python at this point. But I could whip up a quick test to verify coinbase vs. my timestamp