If you are having 401: Invalid Signature API Issues - Read this for a potential Simple Fix (NodeJS)

Hey All,

I am posting this as just a small bit of goodwill for the community. Particularly if you use Axios…

You signature is probably NOT invalid, confirm this by:

  1. Doing a GET request on /accounts in the way that it would make sense to you

If you are getting a response then don’t worry about your hashing etc… etc… thats not your issue

Next debugging step:

  1. Ensure you have your headers like this:

    ‘CB-ACCESS-SIGN’: signature,
    ‘CB-ACCESS-KEY’: api_key,
    ‘CB-ACCESS-TIMESTAMP’: cb_access_timestamp,
    ‘CB-ACCESS-PASSPHRASE’: passphrase,
    ‘content-type’: ‘application/json; charset=UTF-8’,
    ‘User-Agent’: ‘request’,

The last being the potentially most important because I’m guessing you need to override whatever your request library is sending as the user agent.

If it doesn’t work then the last thing that finally got it to work for me:

  1. Ensure that the request body is being sent in the right way. I use axios so for me my axios config looks like:

const axiosConfig = {
method: ‘POST’,
url: ‘https://api.pro.coinbase.com/orders’,
headers,
data: buyParams,
};

** It specifically works when I did NOT use the object shorthand for buyParams **

You must have data: buyParams, or payload: buyParams or whatever ensures that the post data is nested correctly. This is actually a fairly common issue that comes with using axios (other APIs have this issue) but maybe others give much better error notifications.

So finally to the Coinbase API team… the error message Invalid Signature is completely misleading — Please, please if at least to do a small Hotfix and just update where you are sending this error message if possible.

Notice how many devs are here scrambling and guessing.

This took me 11 hours of working time to fix. It breaks various libraries as well and so much time wasted. I was about to switch to Kraken but I decided to rest and return just because so much of my codebase had been written around your APIs.

The switch from Pro → Exchange is documented SO SO SO SO poorly. I get maybe this isnt a big part of your business but for a multi billion dollar company, just throw a couple million at the problem.

Hell pay me 100k and I will take a month and rewrite your documentation from a developer standpoint. Much less than you are probably paying your current Tech Writers…

I don’t mean to be rude but look at the forums… people are CONFUSED.

5 Likes

Encantada de leer esto amigos alguien puede enseñarme a crear una billetera o dirección de monedero USDT trc20 de retiro .:innocent::eyes::smile_cat::smile_cat::smile_cat::smile_cat:

HI @greisflor, thank you for joining the conversation. Since this is already a different topic, we’ve created a new thread specifically for your inquiry. Please refer to this thread: How to create a wallet address for USDT trc20

2 Likes

im going to put this here since the original advice is already out of date on this thread. I agree with the poster, the docs are terrible. The below worked for me using the advanced api (nodejs):


        let payload = {
            "order_configuration": {
                "market_market_ioc": {
                    "quote_size": "0.001"
                }
            },
            "side": "BUY",
            "product_id": "ETH-USDC",
            "clientOrderId": uuid.v4()
        }


        const timestamp = Math.floor(Date.now() / 1000).toString();
        const message = timestamp + "POST" + "/api/v3/brokerage/orders" + JSON.stringify(payload);
        const signature = crypto.createHmac("sha256", apiSecret).update(message).digest("hex");

        const headers = {
            'Accept': 'application/json',
            'Content-Type': 'application/json',
            "Authorization": `Bearer ${apiKey}`,
            "CB-ACCESS-TIMESTAMP": timestamp,
            "CB-ACCESS-SIGN": signature,
        };

        //const response = await axios.post('https://api.coinbase.com/api/v3/brokerage/orders', body, { headers });


        const response = await fetch('https://api.coinbase.com/api/v3/brokerage/orders', {
            method: 'POST',
            mode: 'cors',
            body: payload,
            headers,
          });
          const data = await response.json();

Here is the code in C#, I can’t believe I spent the Sunday trying to figure out what is missing from the terrible documentation. This works for the Pro Api, we’ll see about the Advanced. Code that is commented may be needed for post requests (that was a GET). Thanks to the good person who started this thread.

        request.AddHeader("Content-Type", "application/json; charset=UTF-8");
        request.AddHeader("CB-ACCESS-KEY", APIkey);
        request.AddHeader("CB-ACCESS-PASSPHRASE", passphrase);
        request.AddHeader("CB-ACCESS-TIMESTAMP", timestamp);

// request.AddHeader(“User-Agent”, “request”);
// request.AddHeader(“Accept”, “application/json”);
// request.AddHeader(“Authorization”, “Bearer” + APIkey);

        // CB-ACCESS-SIGN
        string signature = timestamp + method + requestPath + body;
        var dataBytes = Encoding.UTF8.GetBytes(signature);
        using( var hmac = new HMACSHA256(Convert.FromBase64String(APIsecret)) )
        {
            var sig = hmac.ComputeHash(dataBytes);
            signature = Convert.ToBase64String(sig);
        }
        request.AddHeader("CB-ACCESS-SIGN", signature);