Create Limit Sell Order returns <Response [401]> Unauthorized

When I try to Create a Limit Order I get <Response [401]> Unauthorized.
I can Create Other Endpoints such as accounts and they work using the
same Keys and Credentials.

The Code can be found here.

I need to be able to Place and Cancel Orders on Coinbase Advanced Trade before they Sunset Coinbase PRO. Any Help will be appreciated.

1 Like

Hi @Justin

Could you please confirm if you have enabled the necessary permissions while creating your API keys?

Yes,
I have the following but not limited to:
wallet:buys:create
wallet:sells:create
wallet:buys:read
wallet:sells:read
wallet:orders:create
wallet:orders:read
wallet:trades:create
wallet:trades:read

Hi @Justin

Thank you for the confirmation! We were able to identify few things.

We suggest correcting the formatting,

‘CB-ACCESS-SIGN’: signature, ← you had this but ‘CB-ACCESS-SIGN’: signature.hex(), ← you need this

Also, please check the example code below:


api_key = os.environ.get('COINBASE_KEY')
api_secret = os.environ.get('COINBASE_SECRET')

timestamp = str(int(time.time()))
request_method = 'POST'
request_path = '/api/v3/brokerage/orders'

order_uuid = str(uuid.uuid4())
conn = http.client.HTTPSConnection("api.coinbase.com")

payload = json.dumps({
            'client_order_id': order_uuid,
            "product_id": "ETH-USD",
            "side": "BUY",
            "order_configuration": {
                "market_market_ioc": {
                "quote_size": '5.00',
                }
            }
            })

message = timestamp + request_method + request_path + payload
signature = hmac.new(api_secret.encode('utf-8'), message.encode('utf-8'), digestmod=hashlib.sha256).digest()

headers = {
'Content-Type': 'application/json',
'CB-ACCESS-KEY': api_key,
'CB-ACCESS-SIGN': signature.hex(),
'CB-ACCESS-TIMESTAMP': timestamp,
}

conn.request(request_method, request_path, payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))

We hope this helps. If you’re still having trouble after implementing this fix, please let us know.

2 Likes

@Caleb Thank you for your response

The hex conversion is handled by using the .hexdigest() at then end.

The following two sets of code below will have the same result.

signature = hmac.new(api_secret.encode(), message.encode(), hashlib.sha256).hexdigest()
print(signature)
ed5f01059a4d1edd64a92f0f2a3f41d442f5c443090494fc1ba5ae23801a2d81

signature = hmac.new(api_secret.encode(), message.encode(), hashlib.sha256).digest()
print(signature.hex())
ed5f01059a4d1edd64a92f0f2a3f41d442f5c443090494fc1ba5ae23801a2d81

I am still unable to Create an Order using either approach.

Thank you for the Working Code you provided. However it will only work in Python 3.1+
I have a lot of Code written for a CryptoBot using the Coinbase Pro API that uses
Python 27 so I am always looking for Python code that is compatible for both 2.7 & 3.0+
and the requests module is compatible to both.

1 Like

@Caleb

Ok letting you Know :slight_smile: Have a Great Day!

@Caleb

Do you have any updates on this 401 Unauthorized issue?

Hi @Justin

We’ve referred this to our internal teams and yet to get an update. We will get back to you soon after we get an update. Please stay in touch and have a good day ahead.

1 Like

Hi @Justin

Thank you for your patience. Having to dive deep on your code further, we have identified the following:

The POST request did not happen to work because the body parameter was not included in the signature.

  • body is the request body string – it is omitted if there is no request body (typically for GET requests)

What you have in the code is this: message= timestamp + method + endpoint

But what is required as per the document is this: Create a signature string by concatenating the values of these query parameters: timestamp + method + requestPath + body

Please add the body parameter in the signature for the code to work. We hope this helps. Please let us know if you have any further questions.

@Caleb

Thank you for your response.

The missing body in the generation of my signature was indeed the problem. In case some
others have ran across the same issue, I have posted my working code below that uses the requests module. The Python code is compatible with both Python 2.7 and Python 3.0+.

image

import os
import json
import time
import hmac
import uuid
import hashlib
import requests

api_key = os.environ.get('COINBASE_KEY')
api_secret = os.environ.get('COINBASE_SECRET')
 
timestamp = str(int(time.time()))
endpoint = '/api/v3/brokerage/orders'
method = 'POST'

payload = {
    "side": "SELL",
    "order_configuration": {
        "limit_limit_gtc": {
        "base_size": "3.5",
        "limit_price": "0.55",
        "post_only": False
        },
    },
    
    "product_id": "ADA-USD",
    "client_order_id": str(uuid.uuid1())
}

body = json.dumps(payload)

data = (timestamp + method + endpoint.split('?')[0] + body).encode()

signature = hmac.new(api_secret.encode(), data, hashlib.sha256).hexdigest()

headers = {
    'accept': 'application/json',
    'CB-ACCESS-KEY': api_key,
    'CB-ACCESS-SIGN': signature,
    'CB-ACCESS-TIMESTAMP':  timestamp
}

api_url = 'https://api.coinbase.com'
url = api_url + endpoint

response = requests.post(url, body, headers=headers)
print(response.status_code) # 200
print(response.json()) # Output
print(response)

@Caleb May you and your team have an Awesome Day!
Justin

1 Like