Unofficial client for selected endpoints of the public and the undocumented private Binance REST API. Implemented in Kotlin, usable from any JVM language including Java.
You can access most of your Binance data via the
official REST APIs
(also available for the JVM).On their website, you can
also download some of your data as .xlsx
or .csv
files.
However, neither of these methods allows you to access all your data that is essential for using a third-party tool to calculate portfolio performance or taxes. E.g., see the limitations listed by CoinTracking.
The JVM client is incomplete and has bugs.
Furthermore, downloading export files from the website is very tedious, because you have to navigate through the confusing site structure to access multiple cumbersome menus which finally allow you to download multiple export files one by one.
The Binance website is a
single-page application that uses a REST API
different to the official public REST API. The endpoint URLs contain the substring private
or friendly
.
Using a browser's developer tools, they could be reverse-engineered to create this project,
an incomplete implementation of this private API. The used programming language is
Kotlin, a relatively new, very readable and clean language that can run on the JVM (
Java Virtual Machine) platform. Therefore, it can be used from Kotlin, Java and other JVM languages.
I am currently implementing a client for some public endpoints as well.
In addition to the basic implementation of the REST APIs, this project also offers some extras that make it much easier to use it:
- Most API endpoints limit the time range of a query to a three months range.
BinanceApiFacade
transparently splits a a query with a large time range into multiple queries. - Most API endpoints limit the number of items (e.g.
Trade
) in a result.BinanceApiFacade
transparently takes care of paging. - Extension functions allow you to derive computed properties from result items that are not explicitly contained.
- You can create reports that are based on your current held asset quantities
(
AssetQuantitiesReport
) and based on history (AssetQuantitiesReport
).
val curlAddressPosix = "..." // See below
val client = BinancePrivateApiRestClientFactory.newInstance(curlAddressPosix).newRestClient()
val facade = BinanceApiFacade(client)
val startTime =
LocalDate.of(2020, 1, 1)
.atStartOfDay(ZoneOffset.UTC)
.toInstant()
.truncatedTo(ChronoUnit.MILLIS)
// Get all trades since startTime from spot, cross margin and isolated margin accounts:
val trades = facade.getTradeHistory(startTime)
Since there is no API key for the private API, we need to use the same mechanism for authentication as the Binance website, which is cookies. You need to obtain them in the following way:
- In your web browser, open the developer tools (see instructions)
- In the browser address bar, navigate to the Binance website and log in.
- In the developer tools area, open the tab called "network" (or similar).
- Right-click an item (a network request) with host
www.binance.com
and select "Copy as cURL (POSIX)" (or similar).
Note that the string you have just copied has all the confidential information that is needed to perform most actions in your Binance account until the session expires, including trading. Therefore, you must treat it with about the same care as a password or the official public API's key and secret! You can easily verify that my code does nothing malicious or risky with your data. Also, given my GitHub account, it is easy to find out my identity. But be careful in case of a fork of this project!
Please use this client responsibly and do not flood the Binance server with requests! You will have to deal with errors if you do it anyway. By default, the client waits one second after each request. You can configure the wait period if you want to.
Regarding timestamps of result items (e.g. IsolatedMarginBorrowing.timestamp
) and startTime
/endTime
of
queries, the Binance private REST API is very inconsistent, unfortunately.
BinanceApiFacade
handles most of these issues transparently for you, but you should still be aware
of them, especially if you want to understand the source code.
Issue | Consequence |
---|---|
A result item's timestamp is originally known by many names in the REST API:
timestamp , time , operateTime etc.
|
This client names all these parameters timestamp ,
handling translation from the original name in JSON transparantly.
|
For some endpoints, startTime and endTime of the query seem to have
no relation to the timestamp of a result item.
It seems that the Binance server uses an internal timestamp for its queries which is not exported
via the REST API.
|
Do not be confused if
timestamp < startTime or endTime < timestamp .
|
endTime is inclusive for some queries and exclusive for others. |
|
For different queries and the resulting items, startTime , endTime
and timestamp have different resolution.
Usually, the resulution is one millisecond, but sometimes it is one second.
|
|
- Since this project is unofficial, you must take great care before using it to support financial decisions! I have taken great care because this project is crucial for my own finances, but you still use it at your own risk.
- Since the underlying private REST API is unofficial, it could be changed without notice,
rendering this client broken.
However, this is very unlikely, since the endpoints are apparently versioned,
e.g.
https://www.binance.com/gateway-api/v3/private/...
. - Since there is no documentation, there could be bugs due to misunderstanding of the private REST API.
- Since there is no documentation, it has been possible to use enum types for some properties only. Whenever the
set of possible values has been unknown,
String
had to be used. - The API has only been implemented incompletely.
This is not due to technical restrictions, but due to restrictions of my personal requirements and time.
Areas that are covered well (but not necessarily completely) include:
- Payments (aka "buy crypto")
- Distribution
- Spot account
- Isolated margin account (cross margin account is partially supported)
- Flexible savings
- Locked staking
- I have observed intermittent bugs on the official Binance website occasionally. I cannot tell whether these stem from bugs in their web client or in their private REST API. This means when using this project, you could observe bugs that are not within my realm of responsibility at all.
- Most decimal numbers are returned by the Binance API as JSON strings which can be converted to
BigDecimal
s. However, rebates (a.k.a. returned fees or discounts) are returned as JSON numbers, which are prone to be inexact. The report or the current quantities should be consistent with the report history. However, for my account, for BNB, they differ by a very small amount. I think this is due to the use of numbers.
If you want to help with these issues, feel free to contact me or create a pull request.
Tests expects to find the file config.properties
in the working directory. You can
use config.properties.template
as a template and rename it. It expects the following properties:
curlAddressPosix
apiKey
,secret
These are the same values that you would use for the official REST API. They are needed because for some extras, the official Java client is utilized internally.accountStartYear
,accountStartMonth
The year and month of your first transactions in your Binance account.