401 - Unauthorized error response of List Orders endpoint

Hello !

My goal is also to recover open orders on Coinbase .

Reading the documentation, I saw that the V3 API is available.
Perfect, I see we can do a GET on /api/v3/brokerage/orders/historical/batch? limit=10 (with the scope wallet:orders:read enabled)

Unfortunately, I get an answer ‘Unauthorized’ code 401.

I specify, that I manage to get successfully the endpoints:

  • api/v3/brokerage/orders/historical/fills (and the others V3 too)

  • All the endpoints of the V2 api

So I think my signature is good, along with my key, timestamp and scope.

I hope I’ve given enough details, could you please give me a lead ? :slightly_smiling_face:

Best,

Olivier

Welcome to the Coinbase Cloud Developer forum, @Olivier! We’re happy to help, but first we’ll need you to provide us with the following information so that we can further assist you with the issue:

  • Can you please provide a code snippet to demonstrate the problem you are encountering including generating a Signature and Timestamp? Please ensure to exclude your API credentials for security reasons.

Please note that we moved your concern to the Advanced Trade API category to ensure that this has been properly addressed. Once you send us the information requested above, we’ll work to quickly address this issue.

We appreciate your patience and understanding. Have a wonderful day!

3 Likes

Hello,

Thank you for your reply.

Below, you’ll find more informations :

I’m using Node.js with library ‘crypto’ and ‘request’ .

const path = '/api/v3/brokerage/orders/historical/batch?limit=10'; 

const optionsRequest = (path, keys, method = 'GET', body = '') => {

  const timestamp = Math.floor(Date.now() / 1000);
  const req = {
    method: method,
    path: path,
    body: body
  };

  const message = timestamp + req.method + req.path + req.body;

  const { apiKey, apiSecret } = keys;
  const signature = crypto.createHmac("sha256", apiSecret).update(message).digest("hex");

  return {
    baseUrl: 'https://api.coinbase.com/',
    url: req.path,
    method: req.method,
    headers: {
      'CB-ACCESS-SIGN': signature,
      'CB-ACCESS-TIMESTAMP': timestamp,
      'CB-ACCESS-KEY': apiKey,
      'CB-VERSION': '2022-02-21 '
    }
  };

}


const getOrders = (path) => {
  return new Promise((resolve, reject) => {

    const options = optionsRequest(path, keys);
    request(options, function (error, response) {
      if (error) {
        console.log('Error: ', error);
        reject(error);
      }
      if (response) {
        console.log('Response: ', response);
        resolve(response);
      }
    })
  })
}


try {
  getOrders(path).then(orders => {
    console.log(orders);
  })
} catch (error) {
  console.log('error:', error);
}

The response :

“statusCode”: 401,
“body”: “Unauthorized\n”,
“headers”: {
“date”: “Wed, 21 Dec 2022 09:45:43 GMT”,
“content-type”: “text/plain; charset=utf-8”,
“content-length”: “13”,
“connection”: “close”,
“trace-id”: “1506336803281853123”,
“x-content-type-options”: “nosniff”,
“cf-cache-status”: “DYNAMIC”,
“set-cookie”: [
“__cf_bm=Y64ilkkfq3gyqPSvgttTLgHbVDOpLT0lqYregHCBcUE-1671615943-0-Aarxsx9Vx5B+REE1kZUPZwFUXM9ubzQNf6fLQFXHXUrzx5gVoPs+hu11RYW2r5BEvUP6TUmXxGTgPTpkdjICxtc=; path=/; expires=Wed, 21-Dec-22 10:15:43 GMT; domain=.coinbase.com; HttpOnly; Secure”
],
“strict-transport-security”: “max-age=31536000; includeSubDomains; preload”,
“server”: “cloudflare”,
“cf-ray”: “77cfafbdcdc0d64e-CDG”
},
“request”: {
“uri”: {
“protocol”: “https:”,
“slashes”: true,
“auth”: null,
“host”: “api.coinbase.com”,
“port”: 443,
“hostname”: “api.coinbase.com”,
“hash”: null,
“search”: “?limit=10”,
“query”: “limit=10”,
“pathname”: “/api/v3/brokerage/orders/historical/batch”,
“path”: “/api/v3/brokerage/orders/historical/batch?limit=10”,
“href”: “https://api.coinbase.com/api/v3/brokerage/orders/historical/batch?limit=10
},
“method”: “GET”,
“headers”: {
“CB-ACCESS-SIGN”: xxxxxxxxxxxxxxxxxxeeb89",
“CB-ACCESS-TIMESTAMP”: 1671615942,
“CB-ACCESS-KEY”: xxxxxxxxxxxxxxxN8m",
“CB-VERSION”: "2022-02-21 "
}
}
}

This is strange for me because i can get all these endpoints below with succes :

// const path = ‘/api/v3/brokerage/transaction_summary’; // OK
// const path = ‘/api/v3/brokerage/products’; // OK
// const path = ‘/api/v3/brokerage/orders/historical/fills’; // OK
// const path = ‘/v2/accounts’; OK

Here, an example of the success response for ‘/api/v3/brokerage/transaction_summary’

{
“statusCode”: 200,
“body”: “{"total_volume":4.313846111297607,"total_fees":0.017255384474992752,"fee_tier":{"pricing_tier":"","usd_from":"0","usd_to":"10000","taker_fee_rate":"0.006","maker_fee_rate":"0.004"},"margin_rate":null,"goods_and_services_tax":null,"advanced_trade_only_volume":4.313846111297607,"advanced_trade_only_fees":0.017255384474992752,"coinbase_pro_volume":0,"coinbase_pro_fees":0}”,
“headers”: {
“date”: “Wed, 21 Dec 2022 09:51:04 GMT”,
“content-type”: “application/json; charset=utf-8”,
“content-length”: “371”,
“connection”: “close”,
“access-control-allow-headers”: “Content-Type, Accept, Second-Factor-Proof-Token, Client-Id, Access-Token, X-Cb-Project-Name, X-Cb-Is-Logged-In, X-Cb-Platform, X-Cb-Session-Uuid, X-Cb-Pagekey, X-Cb-Ujs, Fingerprint-Tokens, X-Cb-Device-Id, X-Cb-Version-Name”,
“access-control-allow-methods”: “GET,POST,DELETE,PUT”,
“access-control-allow-private-network”: “true”,
“access-control-expose-headers”: “”,
“access-control-max-age”: “7200”,
“cache-control”: “no-store”,
“set-cookie”: [
“cb_dm=e6c6bd81-21a1-4c39-a387-04244dd06f25; Path=/; Domain=coinbase.com; Expires=Tue, 21 Dec 2032 09:51:04 GMT; HttpOnly; Secure”,
“__cf_bm=OKp9GO2V3a2lWHRCByeNEvhKwTrzTdV2QEwEuFhcghU-1671616264-0-AVs1Mi07urHQvrWILeGzMd+z7v7+JDw7Uxn/Ae3jVy+pWwED4wKWCGwwACQow54PNsKO/jh3zr+fNSj+QmGa3uM=; path=/; expires=Wed, 21-Dec-22 10:21:04 GMT; domain=.coinbase.com; HttpOnly; Secure”
],
“strict-transport-security”: “max-age=31536000; includeSubDomains; preload”,
“trace-id”: “3484410697854362371, 3484410697854362371”,
“vary”: “Origin”,
“x-content-type-options”: “nosniff”,
“x-dns-prefetch-control”: “off”,
“x-download-options”: “noopen”,
“x-frame-options”: “SAMEORIGIN”,
“x-xss-protection”: “1; mode=block”,
“cf-cache-status”: “DYNAMIC”,
“server”: “cloudflare”,
“cf-ray”: “77cfb7928a7bd506-CDG”
},
“request”: {
“uri”: {
“protocol”: “https:”,
“slashes”: true,
“auth”: null,
“host”: “api.coinbase.com”,
“port”: 443,
“hostname”: “api.coinbase.com”,
“hash”: null,
“search”: null,
“query”: null,
“pathname”: “/api/v3/brokerage/transaction_summary”,
“path”: “/api/v3/brokerage/transaction_summary”,
“href”: “https://api.coinbase.com/api/v3/brokerage/transaction_summary
},
“method”: “GET”,
“headers”: {
“CB-ACCESS-SIGN”: “680xxxxxxxxxxxxxxxxxxca156”,
“CB-ACCESS-TIMESTAMP”: 1671616262,
“CB-ACCESS-KEY”: “nxxxxxxxxxxxxN8m”,
“CB-VERSION”: "2022-02-21 "
}
}
}

Sorry, there is a lot of code now, i hope i will help for all.

It’s strange because a majority of endpoints are working, so it’s not easy to understand.

Hello @Olivier! Upon investigating the code snippet you have provided us, we noticed that you have included the query parameters in your path. According to the documentation, the path (requestPath) is the full path (minus the base URL and query parameters). We would also like to reference this post made by a community member regarding signing with params. We recommend for you to try it out and reply back to us if the issue still persists. Thank you!

3 Likes

Hello @Faker ,

Thank you, you are right, now it’s OK !!!

I’m confused because it’s clearly noticed in the documentation :expressionless:

Best,

Olivier

1 Like

Hello @Olivier! Thank you for confirming! We are glad that we were able to help you regarding your concern. Please don’t hesitate to reach back to us if you have any other concerns. Once again, welcome to the Forum!

3 Likes