You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Bitget Restful API POST请求签名错误问题求助

Bitget期货API POST请求签名错误排查求助

参考Stack Overflow相关文章后,已成功实现Bitget期货Rest API的GET请求,但按官方文档配置POST请求签名时,始终收到error sign signature错误。

官方签名规则

  • 当queryString为空时,签名内容为:timestamp + method.toUpperCase() + requestPath + body
  • 当queryString不为空时,签名内容为:timestamp + method.toUpperCase() + requestPath + "?" + queryString + body

我的代码

def parse_params_to_str(params):
    url = '?'
    for key, value in params.items():
        url = url + str(key) + '=' + str(value) + '&'

    return url[0:-1]


def get_signature(message):
    mac = hmac.new(bytes(api_sec, encoding='utf8'), bytes(
        message, encoding='utf-8'), digestmod='sha256')
    d = mac.digest()
    return base64.b64encode(d)


def get(request_path, body, query, method):
    std_time = time.time() * 1000
    new_time = int(std_time)
    if str(body) == '{}' or str(body) == 'None':
        converted_body = ''
    else:
        converted_body = json.dumps(body)

    message = str(new_time) + method + request_path + \
        parse_params_to_str(query) + converted_body
    print(message)

    headers = {"ACCESS-KEY": api_key,
               "ACCESS-SIGN": get_signature(message),
               "ACCESS-TIMESTAMP": str(new_time),
               "ACCESS-PASSPHRASE": api_passphrase,
               "Content-Type": "application/json",
               "Locale": "en-US"
               }
    if method == "GET":
        request_resp = requests.get(
            (api_url + request_path), headers=headers, params=query)
    return request_resp


def post(request_path, body,  method):
    std_time = time.time() * 1000
    new_time = int(std_time)

    if str(body) == '{}' or str(body) == 'None':
        converted_body = ''
    else:
        converted_body = json.dumps(body)

    
    message = str(new_time) +method + request_path + converted_body
    print(message)

    
    headers = {"ACCESS-KEY": api_key,
               "ACCESS-SIGN": get_signature(message),
               "ACCESS-TIMESTAMP": str(new_time),
               "ACCESS-PASSPHRASE": api_passphrase,
               "Content-Type": "application/json",
               "Locale": "en-US"
               }
    if method == "POST":
        request_resp = requests.post(
            (api_url + request_path), headers=headers, params=body)
    return request_resp


query = {
    "symbol": symbol,
    "marginCoin": "USDT"
}

order_resp = get("/api/mix/v1/account/account", None, query, "GET")

print(order_resp.json())

para= {"symbol": "BTCUSDT_UMCBL",
        "marginCoin": "USDT",
        "openPrice": "23189.5", 
        "leverage": "20", 
        "openAmount": "5000"}
test = post("/api/mix/v1/account/open-count", para, "POST")
print(test.json())

问题原因及解决方法

  1. Method未转大写
    官方要求签名时必须使用大写的请求方法(如POST),但当前代码中拼接签名字符串时直接使用了原method变量,未转大写。
    修复:将签名字符串中的method替换为method.upper(),GET和POST方法都需要修改。

  2. POST请求参数传递方式错误
    代码中POST请求使用params=body将参数放在URL中,但Bitget的POST接口要求参数放在请求体(JSON格式)中,这会导致签名计算的body内容与实际发送的不一致。
    修复:将requests.post中的params=body改为json=body。

  3. JSON序列化格式不一致
    默认json.dumps(body)会生成带空格的JSON字符串(如{"key": "value"}),而Bitget服务器可能要求紧凑格式(无空格),导致签名不匹配。
    修复:修改JSON序列化代码为converted_body = json.dumps(body, separators=(',', ':')),确保生成无空格的JSON字符串。

  4. 代码冗余与扩展性问题
    GET和POST方法的签名逻辑重复,容易出现遗漏。建议将签名计算逻辑抽为公共函数,统一处理query参数和body的拼接。
    优化示例:

    def generate_signature(timestamp, method, request_path, query=None, body=None):
        method_upper = method.upper()
        query_str = parse_params_to_str(query) if query and query != {} else ""
        if query_str:
            query_str = f"?{query_str}"
        
        converted_body = json.dumps(body, separators=(',', ':')) if body and body != {} else ""
        
        message = f"{timestamp}{method_upper}{request_path}{query_str}{converted_body}"
        return get_signature(message)
    

修复后的关键代码示例

修改后的post函数:

def post(request_path, body, method):
    std_time = time.time() * 1000
    new_time = int(std_time)

    if str(body) == '{}' or str(body) == 'None':
        converted_body = ''
    else:
        converted_body = json.dumps(body, separators=(',', ':'))

    # 方法转大写
    message = str(new_time) + method.upper() + request_path + converted_body
    print(message)

    headers = {"ACCESS-KEY": api_key,
               "ACCESS-SIGN": get_signature(message),
               "ACCESS-TIMESTAMP": str(new_time),
               "ACCESS-PASSPHRASE": api_passphrase,
               "Content-Type": "application/json",
               "Locale": "en-US"
               }
    if method == "POST":
        # 使用json参数传递请求体
        request_resp = requests.post(
            (api_url + request_path), headers=headers, json=body)
    return request_resp

内容的提问来源于stack exchange,提问作者trista

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 19:15:14