"Unauthorized" trying to place a buy order in advanced trade API

Hey I’m trying to create an order in Python and no matter what I do I have not got anything other than an Unauthorized response. I’m 100% sure my key and secret are authorized.

import time
import http.client
import json
import uuid
import hashlib
import hmac
import base64
import os

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_ioc”: {
“quote_size”: ‘5’,
}
}
})

message = timestamp + request_method + request_path + str(payload or ‘’)
signature = hmac.new(api_secret.encode(‘utf-8’), message.encode(‘utf-8’), digestmod=hashlib.sha256).digest()
signature_b64 = base64.b64encode(signature).decode()

headers = {
‘Content-Type’: ‘application/json’,
‘CB-ACCESS-KEY’: api_key,
‘CB-ACCESS-SIGN’: signature_b64,
‘CB-ACCESS-TIMESTAMP’: timestamp,
}

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

It would make my day if someone told me I’m stupid and missing something obvious cause I just have no idea what to do

You don’t need to base64 encode signature.

Okay now it’s showing a 400 response. Still not sure what’s wrong with the headers

Do you have required permissions set for api key? Otherwise I have no idea…

Yep. Even tried creating a new key and all. I’m just at a complete loss here

Can you paste your code again using the preformatted text thing? Makes it easier to read and uses a font that won’t change things like quote marks in such a way as to cause errors when we try to copy/paste your code. Thanks!
Screenshot 2023-03-23 at 2.38.53 PM

import time
import http.client
import json
import uuid
import hashlib
import hmac
import base64
import os

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_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()
signature_b64 = base64.b64encode(signature).decode()

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

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

Yes of course

Thanks! There’s 2 things I found.

1 - You need to send the signature hex

'CB-ACCESS-SIGN': signature, <-- you had this
'CB-ACCESS-SIGN': signature.hex(), <-- you need this

2 - Kinda weird but you need to send the order configuration as market_market_ioc, not market_ioc. Not sure why they need it doubled like that, but it should work.

Here’s the full code if you want to just copy paste the whole thing. Same as what you had but with those two things fixed.

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"))