Search code examples
unix-timestampbinance

Binance TIMESTAMP ERROR (Timestamp for this request is outside of the recvWindow. M 1)


I'm using binance broker api, when executing my code.

I got this error : data: { code: -1021, msg: 'Timestamp for this request is outside of the recvWindow.' }

Then I have used binance server timestamp and get another error : data: { code: -1022, msg: 'Signature for this request is not valid.' }

----- My sample code -------

'use strict'

//Modules
const crypto = require('crypto');
const axios = require('axios');
const moment = require('moment');
const keys = require('./config/keys');


//Keys
const apiKey = keys.keys.apiKey;

async function api_call(config){
  var response  = {}
  try {
    response = await axios(config);
    response =  {
      error: false,
      data : response.data
    }
  } catch (error) {
    response =  { 
      error: true,
      data : error
    }
  }
  return response;
}


async function get_binance_server_time(recvWindow=50000){
  var timestamp = moment().unix();
  var serverTime = 0;

  var config = {
    method: 'get',
    url: `https://api.binance.com/api/v3/time`,
    headers: { 
      'Content-Type': 'application/json', 
      'X-MBX-APIKEY': apiKey 
    }
  };  
  var response = await api_call(config);

  if(response.error){
    response.data = {
      serverTime : serverTime
    }
  }
  serverTime = response.data.serverTime

  console.log(timestamp);
  console.log(response.data.serverTime);

  if (timestamp < (serverTime + 1000) && (serverTime - timestamp) <= recvWindow) {
    console.log("process");
  } else {
    console.log("Rejected");
  }
  return serverTime;
}


async function get_broker_account_information( _signature = null){

  // Make the api call here
  var serverTime  = await get_binance_server_time();
  var _timestamp = serverTime;

  const query_string = `timestamp=${_timestamp}`;
  const recvWindow = 50000
  const signature = crypto.createHmac('sha256', apiKey).update(query_string).digest('hex')

  var config = {
    method: 'get',
    url: `https://api.binance.com/sapi/v1/broker/info?timestamp=${_timestamp}&signature=${signature}&recvWindow=${recvWindow}`,
    headers: { 
      'Content-Type': 'application/json', 
      'X-MBX-APIKEY': apiKey 
    }
  };  
  
  var response = await api_call(config)
  console.log(response.data);
  return response;
}




// create_sub_account()
get_broker_account_information()
// get_binance_server_time()


Solution

  • Binance requires Unix timestamp in Milliseconds. So you should change

    var timestamp = moment().unix();
    

    to

    var timestamp = moment().unix()*1000;
    

    Some time sync issues can be resolved by using an offset of about 15 seconds:

    const offset = 15000;
    var timestamp = moment().unix()*1000 - offset;  // works flawlessly in my case
    

    Also try using

    const recvWindow = 60000  // maximum allowed
    

    Important: Your signature has to be generated from secret key, not api key. You need both, api key in header, secret key in signature calculation.

    To gerenate a valid signature, all query parameters must be in the queryString, which you use to generate the signature.

    Make a parameters object and convert it to a queryString:

    var params = {
        'timestamp': _timeStamp,
        'recvWindow: 60000,
        // other query parameters
    };
    
    var queryString = Object.keys(params).map(key => key + '=' + params[key]).join('&');
    

    Then generate signature:

    const signature = crypto.createHmac('sha256', apiSecret).update(queryString).digest('hex')