Python-binance: binance.exceptions.BinanceAPIException: APIError(code=-1022): Signature for this request is not valid.

Created on 9 Sep 2017  路  40Comments  路  Source: sammchardy/python-binance

always...

Most helpful comment

I managed to resolve my problem. It seems that the last two query params need to be timestamp and signature, in this order.

All 40 comments

@includeleec can you give an example of how you're using the API.

from binance.client import Client

class Monitor:
    def __init__(self):
        self.bac = Client(KEY,SERCRET)
    def my_balance(self):
        print(self.bac.get_account(recvWindow=RECV_WINDOW))


m = Monitor()
m.my_balance()

sometimes ok,sometimes throw error.

@includeleec can you check the value you're using for recvWindow, the API docs indicate it should be an int for the number of milliseconds the request is valid for.

If I send a string of say "4000" then I also get the Signature invalid error back from the Binance API.

RECV_WINDOW=6000000,
this setting i copy from binance example

#!/usr/bin/env python

api_key = 'key_here'
api_secret = 'secret_here'

from binance.client import Client
client = Client(api_key, api_secret)

time_res = client.get_server_time()

RECV_WINDOW=6000000

class Monitor:
    def __init__(self):
        self.bac = Client(api_key,api_secret)
    def my_balance(self):
        print(self.bac.get_account(recvWindow=RECV_WINDOW))


m = Monitor()
m.my_balance()

It's working for me, did you set up your API key correctly?

Hi,

same issue with invalid invalid signature.

Thanks

@laurent101 please provide examples to add to the discussion.

There are a range of things that can cause this, some that I'm aware of are listed in the FAQ here https://github.com/sammchardy/python-binance#user-content-faq

I ran the code as posted above by @jmynes and ended up with an invalid signature error message. Both my key and secret (both strings) are correct.

I found the issue which is related to the API version issue I posted. I had added and changed the version of the REST API from 'v1' to 'v3' which is the update on the Binance website. As @sammchardy correctly pointed out this requires an amended signature. Sorry for the inconvenience caused.

Im encountering the same issue on v1 as @includeleec even when I add "recvWindow=6000000" to the parameters.
the signature is sometimes valid and sometimes not valid.

same issue. seems to fail randomly

Had this issue, however appending recvWindow=5000 to the request seems to fix it for me.

Very strange especially since the API docs state that

An additional parameter, recvWindow, may be sent to specific the number of milliseconds after timestamp the request is valid for. If recvWindow is not sent, it defaults to 5000 millisecond.

and yet the signature is invalid unless I provide a recvWindow ...

EDIT:
Seems like get_account doesn't work even with recvWindow=5000

For anyone still running into this issue, I've been referencing sammchardy's extremely helpful code here as a template for my own project, and I was continually running into this error as well. Here is an example standalone code snippet that I was finally able to get working:

api_key = ''
api_secret = ''

request_url = 'https://api.binance.com/api/v3/openOrders?'

timestamp = int(time.time() * 1000)
symbol = 'BNBBTC'

querystring = urlencode({'symbol' : symbol, 'timestamp' : timestamp})

signature = hmac.new(api_secret.encode('utf-8'), querystring.encode('utf-8'), hashlib.sha256).hexdigest()

request_url += querystring + '&signature=' + signature

r = requests.get(request_url, headers={"X-MBX-APIKEY": api_key})

Has anyone found a fix for this yet? I am running into it when calling .getAccount(). I've tried setting RECV_WINDOW manually without success.

I'm also running into this intermittently when initiating various sales.

I've updated some dependencies in v0.5.10 including certifi which has resolved this issue for me for the moment. Let me know if it helps.

I just updated everything today but am also still receiving this error when calling the withdraw method. All the signed GET withdraw api functions seem to work fine though (deposithistory, withdrawhistory, depositaddress). I've tried increasing the recvWindow up to 6000000 ms but with no success.

getting this error when placing orders, has anyone been able to find a solution?
tried @shammy12's solution but got a similar error >> " {'code': -1022, 'msg': 'Signature for this request is not valid.'}"

@meko0019 Can you give an example function call that produces that error? I'm hitting it all over the place, but one common roadblock I'm seeming to hit is when _selling ADA_. ADA is only buyable/sellable in whole increments; I'm wondering if the API is expecting a decimal for the purposes of the signature...

(FWIW I have updated and am still seeing this pretty commonly as well)

EDIT: I could not reproduce the bug by making that change (int -> float). Is there some way for an extra parameter to be included in the API response/signature by accident?

I have released v0.5.13 which ensures orders are correct when generating signature and sending to server. This seems to resolve issues in my tests.

Let me know if it's still occurring.

@5outh all of the order functions including test_order were producing that error. A new API key seems to have solved it for me.

Very interesting, I'll have to try that. I was still seeing issues (with a 2-week old key) yesterday, but they seem less frequent. That may be because I'm placing fewer orders though...

Will ping back if changing the API key doesn't fix things. Thanks for your work on this project!

getting the same message with PHP / CURL

$ch = curl_init();
$timestamp = round(microtime(true) * 1000);
$secret = 'bmrLfulh***************************KladNAcI4qLg';
$querystring = urlencode("'timestamp' : ".$timestamp."}");
$signature = hash_hmac('SHA256', $secret, $querystring);

curl_setopt($ch, CURLOPT_URL, "https://api.binance.com/api/v3/order?symbol=LTCBTC&side=BUY&type=LIMIT&timeInForce=GTC&quantity=1&price=0.1&recvWindow=50000&timestamp=".$timestamp."&signature=".$signature."");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);

$headers = array();
$headers[] = "X-Mbx-Apikey: EAXHTI2ZyuWqVdV**********ptYUnl2XYM9f";
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$result = curl_exec($ch);
print_r($result);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close ($ch);

Updated to v0.5.13, made a new api key, received a "Name is empty" exception so I withdrew manually then tried it again and it seems to be working perfectly now. Thanks for the update and I really appreciate your awesome work on this project!

Going to close this now, v0.5.13.

Adding a note about regenerating API key and secret to FAQs

Can someone explain what the "recv_window" does?

my version is 0.5.17, but i still met this problem.
Thanks @sammchardy

@LiYijin kindly note now it's at version 0.6. Cheers

@5outh all of the order functions including test_order were producing that error. A new API key seems to have solved it for me.

I re-installed from git
sudo pip install git+git://github.com/sammchardy/python-binance.git

and still received the error. then generated a new api key and reran. this resolved the problem.

In my case only the /api/v3/order API endpoint returns this error. Other signed APIs, like /api/v3/account, work fine.

(please note that I'm not using this library, but this discussion seems to be directed at binance rather than this library anyway)

My problem was fixed upon using math.ceil() on the quantity

I had this problem a lot, then I updated to 0.6.2 and generated a new API key. Havent' had the problem since! :-)

I managed to resolve my problem. It seems that the last two query params need to be timestamp and signature, in this order.

Hey There, i did find a solution for me with PHP and wated to share it to you, i was also getting this error amm the time and the following PHP Code did work then:

                  ```

//--API Call
$nonce=time();
//--
$uri='https://api.binance.com/api/v3/account?recvWindow=10000000000000000&timestamp='.$nonce;
$strsign='recvWindow=10000000000000000&timestamp='.$nonce;
//--
$sign=hash_hmac('SHA256',$strsign,$apisecret);
$uri=$uri.'&signature='.$sign;
$ch = curl_init($uri);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('X-MBX-APIKEY:'.$apikey));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_URL, $uri);
$execResult = curl_exec($ch);
$Balances = json_decode($execResult, true);
var_dump($Balances);
```

Sorry if this is the wrong place to post my findings, but I struggled a lot with a similar issue on 'Signature for this request is not valid.'. Perhaps this can be added to the FAQ https://github.com/sammchardy/python-binance#user-content-faq.

Take care of having the correct parameters when you call a function:

client.order_market_buy(symbol='BTCUSDT',quantity=('0.001264',1234),timestamp=client.get_server_time())
=> ERROR 'Signature for this request is not valid.'

client.order_market_buy(symbol='BTCUSDT',quantity=('0.001264'),timestamp=client.get_server_time())
=> NO ERROR

client.order_market_buy(symbol='BTCUSDT',quantity='0.001264',1234,timestamp=client.get_server_time())
=> NO ERROR

Off course the parameter quantity=('0.001264',1234) is wrong (had a bug in my code) but the message could be more clear (e.g. wrong amount).

If it helps anyone, passing None values to create_order will also cause this since the None parameter is used in the query_string used for calculating the signature but not in the query string sent to the server.

e.g. don't use create_order(price = None,.....)

If someone still needs it, I created an example python script that returns your balances.
It includes a valid signature.
https://github.com/thirstygerry/binance-python

I managed to resolve my problem. It seems that the last two query params need to be timestamp and signature, in this order.
pleas help me am geting the same problem
timestamp = int(time.time() * 1000)
params = {

       #'recvWindow': 5000,59999 6000000
       'recvWindow': 6000,
       'timestamp': timestamp
    }

I managed to resolve my problem. It seems that the last two query params need to be timestamp and signature, in this order.
pleas help me am geting the same problem
timestamp = int(time.time() * 1000)
params = {

       #'recvWindow': 5000,59999 6000000
       'recvWindow': 6000,
       'timestamp': timestamp
    }

i dont know if anybody still have this problem with wrong nonce in the Request, but i can tell you all the right solution is easy, you just need to send instead of timestemp the timestemp in miliseconds and not in seconds, here is a example:

$nonce=round(microtime(true) * 1000); //time();
$recwindow=5000;
//-- $url='symbol='.$symbol.'&side=SELL&type=MARKET&quantity='.$VolumeCoin.'&recvWindow='.$recwindow.'&timestamp='.$nonce;
//--
$sign=hash_hmac('SHA256',$url,$apisecret);
$url=$url.'&signature='.$sign;
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('X-MBX-APIKEY:'.$apikey));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_URL, "https://api.binance.com/api/v3/order");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS,$url);
$execResult = curl_exec($ch);
$Auftrag = json_decode($execResult, true);

Was this page helpful?
0 / 5 - 0 ratings