dino
May 19, 2020, 12:09am
1
For new users to API, one of the most common questions is how to work out the signature.
The error code and message for invalid signature:
{"code":-1022,"msg":"Signature for this request is not valid."}
It’s hard to replicate this on our end to help out because it requires using an API key/secret key combination.
There are some of the reasons why the signature is invalid:
The secret key is not set
The secret key is not matching to API key
The parameter sending to server has no value.
/api/v3/order?orderId=×tamp=xxxxx&signature=xxxx
can give this error
Don’t have timestamp and signature (in this order) as the last parameters
/sapi/v1/sub-account/status?email=xxx&recvWindow=10000×tamp=xxx&signature=xxx
The signature is signed by different Hash algo, it has to be SHA256
This repository https://github.com/binance-exchange/binance-signature-examples has the hashing method in many languages.
dino
May 19, 2020, 12:27am
2
Q: How do I debug to find the issue?
A: Some users are working with API endpoint by SDK/library, and it adds extra complexity for this issue. Please make sure you can print out the raw HTTP request URL or the post body sending to the API server. That could be different from what you thought.
GET /fapi/v1/income?symbol=BTCUSDT×tamp=1589747537229&signature=57cf6e89721e8fa12b11bd HTTP/1.1
Content-Type: application/json
X-MBX-APIKEY: xxxxxxxxxxxxxxxxx
User-Agent: PostmanRuntime/7.24.1
Accept: */*
Cache-Control: no-cache
Postman-Token: xxxxxxxxxxxxxxx
Host: testnet.binancefuture.com
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
HTTP/1.1 200 OK
Content-Type: application/json
Transfer-Encoding: chunked
Connection: keep-alive
Date: Tue, 18 May 2020 00:19:00 GMT
Server: Bengine
Vary: Accept-Encoding
X-MBX-USED-WEIGHT-1M: 4
x-response-time: 2928ms
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: *
Content-Encoding: gzip
X-Cache: Miss from cloudfront
Via: 1.1 xxxxxxxxxxxxxxxxx.cloudfront.net (CloudFront)
X-Amz-Cf-Pop: xxxxxx
X-Amz-Cf-Id: xxxxxxxxxxxxxxxxxxxxx==
While you can have this request text with headers, it’s can be easier to check:
If the X-MBX-APIKEY
is set correctly
If the parameters are correct.
If the signature is appended.
dino
May 19, 2020, 1:34am
4
Q: How can I be sure that the signature is valid?
A: The API documentation has the details about how to sign the parameters for reference.
It’s recommend to start with a simple endpoint, my favourite is getting the account information.
# https://binance-docs.github.io/apidocs/spot/en/#account-information-user_data
GET /api/v3/account
As it only requires timestamp
, we only need to work out the SHA256 value of the string:
# timestamp should be 13 number of UTC time in milliseconds
# it's a mock timestamp for validation, you should use current time in production.
timestamp=1578963600000
with secret
NhqPtmdSJYdKjVHjA7PZj4Mge3R5YNiP1e3UZjInClVN65XAbvqqM6A7H5fATj0j
the signature should be
d84e6641b1e328e7b418fff030caed655c266299c9355e36ce801ed14631eed4
2 Likes
dino
May 19, 2020, 1:41am
6
Sample Code
Here are the code snippet that hash the query string in different languages. Please be advised that:
timestamp should be your current time in production
The secret key used here is for sample purposes. Should you decide to use this code then please replace with your own secret key.
In Javascript:
const crypto = require('crypto');
const query_string = 'timestamp=1578963600000';
const apiSecret = 'NhqPtmdSJYdKjVHjA7PZj4Mge3R5YNiP1e3UZjInClVN65XAbvqqM6A7H5fATj0j';
const signature = crypto
.createHmac('sha256', apiSecret)
.update(query_string)
.digest('hex')
In Ruby
require 'openssl'
query_string = 'timestamp=1578963600000'
secret = 'NhqPtmdSJYdKjVHjA7PZj4Mge3R5YNiP1e3UZjInClVN65XAbvqqM6A7H5fATj0j'
signature = OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), secret, query_string)
In Python
import hmac
import hashlib
query_string = 'timestamp=1578963600000'
secret = 'NhqPtmdSJYdKjVHjA7PZj4Mge3R5YNiP1e3UZjInClVN65XAbvqqM6A7H5fATj0j'
signature = hmac.new(secret.encode('utf-8'), query_string.encode('utf-8'), hashlib.sha256).hexdigest()
In PHP
$query_string = 'timestamp=1578963600000';
$secret = 'NhqPtmdSJYdKjVHjA7PZj4Mge3R5YNiP1e3UZjInClVN65XAbvqqM6A7H5fATj0j';
$signature = hash_hmac('sha256', $query_string, $secret);
They are collected in this repo, where you can find more languages:
1 Like