OKEx APi – Problem with POST method "Invalid Sign" Error

Question:

I am not able to send POST request to OKEx API. However, with GET method, everything is ok – I can check my account balance. As soon I send POST request I’ve received that error
{'msg': 'Invalid Sign', 'code': '50113'}

class OkexBot:
    def __init__(self, APIKEY: str, APISECRET: str, PASS: str):
        self.apikey = APIKEY
        self.apisecret = APISECRET
        self.password = PASS
        self.baseURL = 'https://okex.com'

    @staticmethod
    def get_time():
        return dt.datetime.utcnow().isoformat()[:-3] + 'Z'

    @staticmethod
    def signature(timestamp, method, request_path, body, secret_key):
        if str(body) == '{}' or str(body) == 'None':
            body = ''
        else:
            body = json.dumps(body)
        message = str(timestamp) + str.upper(method) + request_path + str(body)
        mac = hmac.new(bytes(secret_key, encoding='utf8'), bytes(message, encoding='utf-8'), digestmod='sha256')
        output = mac.digest()
        return base64.b64encode(output)

    def get_header(self, request='GET', endpoint='', body: dict = dict()):
        cur_time = self.get_time()
        header = dict()
        header['CONTENT-TYPE'] = 'application/json'
        header['OK-ACCESS-KEY'] = APIKEY
        header['OK-ACCESS-SIGN'] = self.signature(cur_time, request, endpoint, body, APISECRET)
        header['OK-ACCESS-TIMESTAMP'] = str(cur_time)
        header['OK-ACCESS-PASSPHRASE'] = PASS
        return header

    def place_market_order(self, pair, side, amount, tdMode='cash'):
        endpoint = '/api/v5/trade/order'
        url = self.baseURL + endpoint
        request = 'POST'
        body = {
            "instId": pair,
            "tdMode": tdMode,
            "side": side,
            "ordType": "market",
            "sz": str(amount)
        }

        body = json.dumps(body)
        header = self.get_header(endpoint=endpoint, request=request, body=body)
        response = requests.post(url=url, headers=header, data=body)
        return response

I looked into this topic

but nothing was helpful.

Asked By: Kacper

||

Answers:

This code is vaid.

class OkexBot:
    def __init__(self, APIKEY: str, APISECRET: str, PASS: str):
        self.apikey = APIKEY
        self.apisecret = APISECRET
        self.password = PASS
        self.baseURL = 'https://www.okex.com'

    @staticmethod
    def get_time():
        return dt.datetime.utcnow().isoformat()[:-3] + 'Z'

    @staticmethod
    def signature(timestamp, method, request_path, body, secret_key):
        message = timestamp + method + request_path + body
        mac = hmac.new(bytes(secret_key, encoding='utf8'), bytes(message, encoding='utf-8'), digestmod='sha256')
        output = mac.digest()
        return base64.b64encode(output)

    def get_header(self, request='GET', endpoint='', body=''):
        cur_time = self.get_time()
        header = dict()
        header['CONTENT-TYPE'] = "application/json"
        header['OK-ACCESS-KEY'] = APIKEY
        header['OK-ACCESS-SIGN'] = self.signature(cur_time, request, endpoint, body, APISECRET)
        header['OK-ACCESS-TIMESTAMP'] = cur_time
        header['OK-ACCESS-PASSPHRASE'] = PASS
        return header

    def place_market_order(self, pair, side, amount, tdMode='cash'):
        endpoint = '/api/v5/trade/order'
        url = self.baseURL + '/api/v5/trade/order'
        request = 'POST'
        body = {
            "instId": pair,
            "tdMode": tdMode,
            "side": side,
            "ordType": "market",
            "sz": str(Decimal(str(amount)))
        }
        body = json.dumps(body)
        header = self.get_header(request, endpoint, str(body))
        print(header)
        response = requests.post(url, headers=header, data=body)
        return response


Answered By: Kacper
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.