List Accounts endpoint bug

For the List Accounts endpoint, when I don’t pass any params I get a good response. When I pass either of the two optional params, limit or cursor, I get Unauthorized. Is this a bug?

auth.py

import time, hmac, hashlib

class Auth:
    def __init__(self):
        self.API_KEY = ''
        self.SECRET = ''
    
    def __call__(self, message):
        timestamp = str(int(time.time()))
        signature = hmac.new(self.SECRET.encode('utf-8'), (timestamp + message).encode('utf-8'), digestmod=hashlib.sha256).hexdigest()
        headers = {
            'CB-ACCESS-KEY': self.API_KEY,
            'CB-ACCESS-TIMESTAMP': timestamp,
            'CB-ACCESS-SIGN': signature,
            'Content-Type': 'application/json'
        }
        return headers, signature, self.API_KEY, timestamp

main.py

import json, http.client
import numpy as np
from auth import Auth

def send_request(method, path, payload):
    auth = Auth()
    headers = auth(method + path + payload)[0]
    conn = http.client.HTTPSConnection('api.coinbase.com')
    conn.request(method, path, payload, headers)
    res = conn.getresponse()
    data = res.read()
    return data

def list_accounts():
    method = 'GET'
    path = '/api/v3/brokerage/accounts'

    #path = '/api/v3/brokerage/accounts?limit=250'

    #cursor = '***'
    #path = '/api/v3/brokerage/accounts?cursor=' + cursor
    
    payload = ''
    data = send_request(method, path, payload)
    print(data)

list_accounts()

Probably an issue with the signature. Are you signing the string with the parameters included? If you are, you shouldn’t be. Only sign with the params when they go in the body/data of the message.

I’m not certain on what your code is doing based on the commented out sections, but it looks you are setting path = '/api/v3/brokerage/accounts?limit=250' before you sign. You need to sign it as path = '/api/v3/brokerage/accounts', then add the params before you make the call.

Hope that helps!

1 Like

Ya that was exactly the problem. Thanks for the help @jmicko

Solution for me

def send_request(method, path, payload, params=''):
    auth = Auth()
    headers = auth(method + path + payload)[0]
    conn = http.client.HTTPSConnection('api.coinbase.com')
    conn.request(method, path + params, payload, headers)
    data = json.loads(conn.getresponse().read())
    return data

def list_accounts(currency=None):
    method = 'GET'
    path = '/api/v3/brokerage/accounts'
    payload = ''
    data = send_request(method, path, payload, params='?limit=250')
    if currency == None:
        print(data)
        uuid=None
        balance=None
    elif currency != None:
        for i in data["accounts"]:
            if i["currency"] == currency:
                uuid = i["uuid"]
                balance = i["available_balance"]["value"]
    return uuid, balance

uuid, balance = list_accounts('BTC')
1 Like

doesn’t look like you were using the cursor param at all though ? I am trying to use it and its never prcoessed as I always get back the same first page of data ?

Author had different problem. Don’t post unrelated problems in old topics!