10

I have set up a read-only API key on Binance to access account information like currency balances but I can't see the JSON data. The string query I put into the URL returns the following error:

{"code":-2014,"msg":"API-key format invalid."}

The URL I am using is this: https://api.binance.com/api/v3/account?X-MBX-APIKEY=**key**&signature=**s-key**

The documentation for Binance API can be found here: https://www.binance.com/restapipub.html. What am I doing wrong ?

HFBrowning
  • 2,196
  • 3
  • 23
  • 42
Crunk_Cat
  • 101
  • 1
  • 1
  • 4
  • I want to connect to Binance as well. It's not immediately clear how to do this from the documentation, but moreover, I can't even create an API key. When I go to the screen to create an API key, clicking on the button to create the key does nothing. – Christian Findlay Dec 30 '17 at 22:46
  • https://developers.binance.com/docs/binance-api/spot/index/ – carloswm85 Dec 12 '21 at 03:02

9 Answers9

4

Binance's websocket API kinda tricky to use. Also there is no way to use a secret key.

Common usage

  1. Send HTTP POST request with your secret API key as a X-MBX-APIKEY header to https://api.binance.com/api/v1/userDataStream
  2. You will get listen key which should be used for websocket connection. It will be available 1 hour.

    {"listenKey": "your listen key here"}

  3. Use it when connecting to Binance's websocket

wss://stream.binance.com:9443/ws/{your listen key here}

Python example

import ssl
from websocket import create_connection

import requests

KEY = 'your-secret-key'
url = 'https://api.binance.com/api/v1/userDataStream'
listen_key = requests.post(url, headers={'X-MBX-APIKEY': KEY})['listenKey']
connection = create_connection('wss://stream.binance.com:9443/ws/{}'.format(KEY), 
                               sslopt={'cert_reqs': ssl.CERT_NONE})
toert
  • 49
  • 3
  • 1
    This is correct, except that you have to send the API key and not the API secret in the X-MBX-APIKEY header, no signature is required. – Ultranuke Apr 24 '21 at 21:23
2

You put it in the header. Following is tested working PHP example borrowed from jaggedsoft binance PHP library, it's a signed request that will return the account status.

$api_key = "cool_key";
$secret = "awesome_secret";

$opt = [
  "http" => [
    "method" => "GET",
    "header" => "User-Agent: Mozilla/4.0 (compatible; PHP Binance API)\r\nX-MBX-APIKEY: {$api_key}\r\n"
  ]
];
$context = stream_context_create($opt);
$params['timestamp'] = number_format(microtime(true)*1000,0,'.','');
$query = http_build_query($params, '', '&');
$signature = hash_hmac('sha256', $query, $secret);
$endpoint = "https://api.binance.com/wapi/v3/accountStatus.html?{$query}&signature={$signature}";

$res = json_decode(file_get_contents($endpoint, false, $context), true);
carloswm85
  • 1,396
  • 13
  • 23
Robert Sinclair
  • 4,550
  • 2
  • 44
  • 46
2
def get_listen_key_by_REST(binance_api_key):
    url = 'https://api.binance.com/api/v1/userDataStream'
    response = requests.post(url, headers={'X-MBX-APIKEY': binance_api_key})  # ['listenKey']
    json = response.json()
    return json['listenKey']


print(get_listen_key_by_REST(binance_api_key))


def get_all_orders(symbol, binance_api_key, binance_secret_key):
    """Get all account orders; active, canceled, or filled.
    Args:   symbol: Symbol name, e.g. `BTCUSDT`.
    Returns:
    """

    from datetime import datetime, timezone, timedelta
    now = datetime.now(timezone.utc)
    epoch = datetime(1970, 1, 1, tzinfo=timezone.utc)  # use POSIX epoch
    posix_timestamp_micros = (now - epoch) // timedelta(microseconds=1)
    posix_timestamp_millis = posix_timestamp_micros // 1000  # or `/ 1e3` for float

    import hmac, hashlib
    queryString = "symbol=" + symbol + "&timestamp=" + str(
        posix_timestamp_millis)
    signature = hmac.new(binance_secret_key.encode(), queryString.encode(), hashlib.sha256).hexdigest()
    url = "https://api.binance.com/api/v3/allOrders"
    url = url + f"?{queryString}&signature={signature}"
    response = requests.get(url, headers={'X-MBX-APIKEY': binance_api_key})
    return response.json()
1

X-MBX-APIKEY should be set as a field in the HTTP header, and not as a HTTP parameter. See this page for more information on HTTP header fields. However, I tried the same with Excel and could not get it running until now.

Another open question is how to use the secret key.

Matthias Sommer
  • 1,070
  • 13
  • 28
1

This worked for me:

base_url="https://api.binance.com"
account_info="/api/v3/account"

url="${base_url}${account_info}"

apikey="your_apikey"
secret="your_secret"

queryString="timestamp=$(date +%s)" #$(python3 binance_time.py) must sync
requestBody=""

signature="$(echo -n "${queryString}${requestBody}" | openssl dgst -sha256 -hmac $secret)"
signature="$(echo $signature | cut -f2 -d" ")"

req=$(curl -H "X-MBX-APIKEY: $apikey" -X GET "$url?$queryString&signature=$signature")
echo $req
Matt
  • 774
  • 1
  • 10
  • 28
Alksentrs
  • 21
  • 1
0

You should set the API key in the request header, not as a parameter in the request url. Please provide more information on your request procedure (language, etc.).

Sjors Hijgenaar
  • 1,232
  • 1
  • 16
  • 30
0

If you are based in USA - make sure to switch your base url to https://api.binance.us

bustedware
  • 194
  • 1
  • 3
  • 18
0
        _httpClient.DefaultRequestHeaders.Add("X-MBX-APIKEY", "apikey");
        _httpClient.DefaultRequestHeaders.Add("SecretKey", "secretkey");
  • Remember that Stack Overflow isn't just intended to solve the immediate problem, but also to help future readers find solutions to similar problems, which requires understanding the underlying code. This is especially important for members of our community who are beginners, and not familiar with the syntax. Given that, **can you [edit] your answer to include an explanation of what you're doing** and why you believe it is the best approach? – Jeremy Caney Nov 10 '22 at 00:14
  • @JeremyCaney I will edit my asnwer later –  Nov 10 '22 at 15:24
-2

curl -H "X-MBX-APIKEY:your_api_key" -X POST https://api.binance.com/api/v1/userDataStream