Coinbase Pro API Authentication

thank you @larry.kubin . I have been focusing on the coinbase pro and really like the python code generator for the api reference docs. IT"S AWESOME! One thing that I am having trouble with is getting the “cb access sign”. I think I am getting closer as the error I get now is “Invalid API Key” but I haven’t been able to do any authenticated queries. Some things that might make it easier to onboard people to use CoinBase API would be to provide the code needed to generate the “cb access sign” in python. (I think cbpro and cbpro libraries used to do it but those libraries don’t work on python 3.6 and up). I saw they had node code in their documentation at Authorization and Authentication (coinbase.com) . I also looked up the “cb access sign” online in reddit and stack overflow. I think it is a big barrier from people creating projects on the coinbase API for now. Lastly, I see that there are requirements before when people can ask questions on the forum (read a bunch of blogs, etc.) How long do you think that my take as I have a bunch of questions regarding Coinbase API, documentation that I think others might have too. Thanks again!

@SubStandard, thanks for the question. I will give this a test and get you a response as soon as possible. You mentioned in the other thread you were primarily using Python - is that correct? I’ll see if I can give you an example that uses Python + requests.

1 Like

So I have two questions about documentation. I found this link Coinbase Exchange | API Reference which has example code in python for signing a message (doesn’t work without some changes-I’ll attach those next) but different than the links provided from Authorization and Authentication (coinbase.com). My fisrt question is 1) is there a difference in API for Coinbase Pro and Coinbase and which docs should I be going off of?
2) Will my sandboxed APIkeys, API secrets, passphrase work in the API Reference Get all accounts for a profile (coinbase.com) or do I need to be using my actually portfolio account Keys,Secret, pass phrase to use the online query features? I haven’t been able to authenticate a or CB-Access-Sign so I am trying to figure out which one to use. Thanks!

Here is the code from the API Reference link above with minor changes "

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

Before implementation, set environmental variables with the names API_KEY and API_SECRET

API_KEY = ‘API_KEY’
API_SECRET = ‘API_SECRET’

Create custom authentication for Coinbase API

class CoinbaseWalletAuth(AuthBase):
def init(self, api_key, secret_key):
self.api_key = api_key
self.secret_key = bytes(secret_key, ‘UTF-8’) ####(I added bytes and UTF-8 as the hmac.new would not accept strings)

def __call__(self, request):
    timestamp = str(int(time.time()))
    message = timestamp + request.method + request.path_url + (request.body or '')
    message = bytes(message, 'UTF-8')  ##(I also added "bytes and UTF-8 here as well)
    signature = hmac.new(self.secret_key, message, hashlib.sha256).hexdigest()

    request.headers.update({
        'CB-ACCESS-SIGN': signature,
        'CB-ACCESS-TIMESTAMP': timestamp,
        'CB-ACCESS-KEY': self.api_key,
    })
    return request

api_url = ‘https://api.coinbase.com/v2/
auth = CoinbaseWalletAuth(API_KEY, API_SECRET)

Get current user

r = requests.get(api_url + ‘user’, auth=auth)
print (r.json())

{u’data’: {u’username’: None, u’resource’: u’user’, u’name’: u’User’…

Running the above code gets me:
{‘errors’: [{‘id’: ‘authentication_error’, ‘message’: ‘invalid api key’}]}

So I am assuming my access-signed worked but I’m not counting on it since I still got an error.

Hi @SubStandard . I think what’s happening here is there is some confusion between our various trading API’s (Exchange, Pro, Prime). We have recently merged much of this documentation together, so I think the distinctions are not very clear.

So I grabbed the snippet for authentication and turned it into a more complete example that fetches my orders. In this example, I have already placed an order for a dollar worth of DOGE. Here’s what I did to fetch my orders.

Note: I am getting the API Key, Passphrase, and Secret from Coinbase Pro (pro.coinbase.com) under /profile/api. The screen looks like this:

Also I made a change to the Buffer() since I was getting a deprecation warning in my version of Node.

Source Code

var crypto = require('crypto');
const https = require('https');

// current unix timestamp in seconds (note Date.now() returns milliseconds)
var cb_access_timestamp = Date.now() / 1000;

// obtained API key, secret, and passphrase from https://pro.coinbase.com/profile/api
var cb_access_passphrase = '';
var cb_api_key = '';
var secret = '';
var path = '/orders?status=done'; // fetching my completed orders
var body = ''; // body is empty in this case
var method = 'GET';

// create the prehash string by concatenating required parts
var message = cb_access_timestamp + method + path + body;

// decode the base64 secret
// NOTE: added .from() to address DeprecationWarning: Buffer() is deprecated
var key = Buffer.from(secret, 'base64');

// create a sha256 hmac with the secret
var hmac = crypto.createHmac('sha256', key);

// sign the require message with the hmac, and finally base64 encode the result
var cb_access_sign = hmac.update(message).digest('base64');

const options = {
  hostname: 'api.exchange.coinbase.com',
  port: 443,
  path: path,
  method: method,
  headers: {
    'Content-Type': 'application/json',
    'Content-Length': 0,
    'User-Agent': 'my-app',
    'CB-ACCESS-KEY': cb_api_key,
    'CB-ACCESS-PASSPHRASE': cb_access_passphrase,
    'CB-ACCESS-SIGN': cb_access_sign,
    'CB-ACCESS-TIMESTAMP': cb_access_timestamp
  }
}

const req = https.request(options, res => {
  console.log(`statusCode: ${res.statusCode}`)

  res.on('data', d => {
    process.stdout.write(d)
  })
})

req.on('error', error => {
  console.error(error)
})

req.end()

Response

[
    {
        "id": "[changed]",
        "product_id": "DOGE-USD",
        "profile_id": "[changed]",
        "side": "buy",
        "funds": "0.9950200000000000",
        "specified_funds": "1.0000000000000000",
        "type": "market",
        "post_only": false,
        "created_at": "2022-01-19T03:22:31.441458Z",
        "done_at": "2022-01-19T03:22:31.441458Z",
        "done_reason": "filled",
        "fill_fees": "0.0049206000000000",
        "filled_size": "5.90000000",
        "executed_value": "0.9841200000000000",
        "status": "done",
        "settled": true
    }
]

I will create a Python example, test it, and post here. Will also get it added to the docs. Thanks for your questions and patience.

3 Likes

You @larry.kubin are awesome! Thank you for taking a look into this.

1 Like

Hello, and this may be a silly question, but I would like to have something clarified for me. I have built a simple Coinbase PRO API interface in Python , and that has endpoints that would go to base URL : api.pro.coinbase and Documentation for it was //docs.pro.coinbase.com

Now that redirects me to here - which is seems to be similar API, but the base URL for the custody/Pro that has Base URL of api.exchange.coinbase.

is this replacing the original “pro” APIs, and those will be deprecated at some point, or will the original code keep working, and do i need to start building new scripts to go to this new URL going forward.
thanks!

Hi, the sample works perfect for GET methods with no body but for POST methods with body it is throwing ‘invalid signature’ error

I am adding body like below:
var body = JSON.stringify({
price: ‘1.0’,
size: ‘1.0’,
side: ‘buy’,
product_id: ‘BTC-USD’
});
I don’t understand where I am doing wrong.

I just signed up to this forum and there is NO button to create a new thread. I am forced to hijack this thread and ask how I am supposed to create new threads/topics? Do I need to request special permission to post a new topic or is the UI truly that horrendous that I can’t find a button to do so?

Thanks!

2 Likes

It takes some time as your user account starts off with no permissions, but after reading the blog posts and becoming a basic user, you can write threads. I too had the same problem. In the badges it tells you what is needed to become a basic user.
Take it easy

1 Like

Thanks for clearing this up, @SubStandard! There are not that many threads on this forum, so I am not sure how long I need to look at them before I am granted permissions to create my own threads.

My issue is that I seem to be unable to get a sandbox account created via https://public.sandbox.pro.coinbase.com/ because it redirects me to https://www.coinbase.com/setup/identity which is ostensibly is not a Sandbox account (based on the URL). I am missing something?

Note that I already have a Coinbase Pro account and I do not want regular Coinbase account. So, what’s the right way to get Sandbox account created?

Thanks!

The link you provided https://public.sandbox.pro.coinbase.com/ is the one I used. I did have to sign in with Coinbase Logins information (which if you have a coinbase Pro account it should be the same login information) after logging in the User interface looks like your coinbase pro interface but it says Sandbox in the URL. Obtaining the API Key, Secret and Pass Phrase by clicking on your name in the upper right and selecting API. Now if only I could figure out this CB-signature stuff in python I could play with pretend currencies in the SandBox…

1 Like

Hi Larry
I would like to get the Python example as well. I am trying to make API call in Coinbase Exchange but getting issues making the signature. It would be great if we could get a sample code in Python to generate the signature.
Thanks

@achuckoury , I went ahead and translated the JavaScript sample I provided above to Python. I have tested and this works for me.

import time
import base64
import hmac
import hashlib
import requests

# current unix timestamp (seconds)
cb_access_timestamp = str(time.time())

# obtained API key, secret, and passphrase from https://pro.coinbase.com/profile/api
cb_access_passphrase = ''
cb_api_key = ''
secret = ''
path = '/orders?status=done' # fetching my completed orders
body = '' # body is empty in this case
method = 'GET'
message = '{}{}{}{}'.format(cb_access_timestamp, method, path, body)
url = 'https://api.exchange.coinbase.com{}'.format(path)

hmac_key = base64.b64decode(secret)
digest = hmac.new(hmac_key, message.encode('utf-8'), digestmod=hashlib.sha256).digest()
signature = base64.b64encode(digest).decode('utf-8')

headers = {
    'Content-Type': 'application/json',
    'CB-ACCESS-KEY': cb_api_key,
    'CB-ACCESS-PASSPHRASE': cb_access_passphrase,
    'CB-ACCESS-SIGN': signature,
    'CB-ACCESS-TIMESTAMP': cb_access_timestamp
}

r = requests.get(url, headers=headers)
print(r.json())

Cheers!

2 Likes

@larry.kubin Thank you so much for the python signature code. I can talk with the API now!!!

2 Likes

So I deleted that last post because of a stupid error on my part with a swapped variable in my signature function. I’ve got full function on the pro api now. However I’m not sure if I’m ready to start making actual trades. I am ready to sandbox my algorithm. But when I change my credentials over to the sandbox api keys and urls I get this mess


Any ideas as to the source of this connection exception?

Jesus help me I did it again. Forgot a / in my url. I should sleep more

1 Like

Thanks Larry. The Python code is working.

1 Like

please could you document an example … not as code but as result. something alike

signing: <1643877611GET/accounts>
secret(encoded) :<Be0gsYS52jo0NG2EwU7JCE/jXSozFlKusQ4qYitXkdIhaOGburNFfjYBO/mIZfymMreLm81AZLKnHEZcH6mXow==>
signature: <5MRIa5n4rIupKQD/O/uhbP/QcQO4RTdnQdib5KhH8vQ>

thank you

Hi @SwissGeorge - Welcome to our Forum! Unfortunately, we cannot provide hashed examples of signatures on this forum. Hoping the sample code here will suffice. Thanks!

Hello,

I am currently working in the Coinbase Pro API sandbox. When trying to complete my orders, i get the error that the product_id is not valid. However, this does not apply for the product_id “BTC-EUR”. All others dont work. Is the Sandbox version limited to only Bitcoin and are all other currencies blocked?
Thank you!