Short answer: Funding rate history needs no API key at the venues here: on 5 November 2026 Binance returned 7,841 BTCUSDT rows back to 10 September 2019, while OKX's API reached only about three months. Open interest is patchier: Binance's history endpoint keeps only the latest month. Liquidation feeds are the weakest: Binance pushes at most one order per symbol per second and OKX says its channel is not the total, so a sum from them undercounts.
Everything here comes from official documents and public calls on 5 November 2026 (UTC), using BTC perpetuals. Row counts are shown, not market values.
This is data engineering, not a trading method: no arbitrage and no reading of these numbers. What funding is belongs in the perpetual futures guide, and payment arithmetic in the funding rate calculator. Leverage can lose the whole margin. In Turkey, crypto assets listed on platforms under the Capital Markets Board (SPK) cannot be traded with leverage (Communiqué III-35/B.2, Article 14), and this page is not aimed at Turkish residents: Article 99/A of Capital Markets Law No. 6362 treats activity by foreign crypto-asset platforms directed at Turkish residents as unauthorized. Elsewhere, rules depend on your jurisdiction and each platform's terms. Naming a venue is not a recommendation.
Funding rate API by venue: limits and measured history
Page sizes, order and reach differ by venue.
| Venue and request | Per page | Order | Measured reach |
|---|---|---|---|
Binance USD-M GET /fapi/v1/fundingRate | 1,000, default 100 | Oldest first | 7,841 rows from 10 September 2019 in 8 pages |
Bybit GET /v5/market/funding/history | 200 | Newest first | 7,249 rows from 25 March 2020 in 37 pages |
Deribit public/get_funding_rate_history | No limit parameter; start and end required | Oldest first | Test host only: 72 hourly rows for 3 days, but only the latest 744 (31 days) for 90. Production reset the connection, so depth is unverified |
Hyperliquid POST /info, fundingHistory | 500 | Oldest first | 30,004 rows from 12 May 2023 in 61 pages |
OKX GET /api/v5/public/funding-rate-history | 400 | Newest first | 283 rows, 94 days; the page says up to three months |
OKX keeps older funding in monthly files: its historical data page (opens in a new tab) says from March 2022, though market-data-history with module=3 listed a September 2021 file, then files from mid-January 2022. Months follow UTC+8, per its documents, so the March 2022 file starts at 16:00 UTC on 28 February. Binance's fundingRate and fundingInfo share 500 requests per 5 minutes per IP. Hyperliquid allows 1,200 weight a minute, and a full fundingHistory page costs 45 (20 plus one per 20 items); at 2.5 seconds per page, 61 pages took 176 seconds with no HTTP 429.
Funding rate history traps found in testing
Most return HTTP 200 or a normal page, so a collector stores wrong data instead of failing.
| Venue | What happens | Fix |
|---|---|---|
| Binance | startTime=0 is ignored and returns the latest 500 rows, even with limit=1000 | Start from 1 or a real time |
| Binance | limit=1001 or limit=0 returns HTTP 200 with a status: ERROR object | Check the body type, not only the status |
| Binance | Without times, the page promises the latest 200 rows; calls returned 100 by default and 500 with limit=1000 | Send times and page explicitly |
| Binance | fundingTime sat up to 47 ms past the hour on 3,405 of 7,841 rows | Floor to the hour before any join |
| Binance | markPrice is an empty string on 4,536 rows, up to 31 October 2023 | Treat it as nullable |
| Binance | rateType, added 23 July 2026, can be Special: an extra rate from stock dividends | Add it to the row key |
| Bybit | startTime alone gives retCode 10001 with HTTP 200 | Walk back with endTime |
| Hyperliquid | Times drift up to 24 minutes past the hour; after flooring, 84 non-hourly steps (81 of 8 hours, 3 of 2 hours), the last on 15 August 2024 | Floor, then run a gap check |
| OKX | Documents call fundingRate predicted and realizedRate actual; all 283 rows matched | Store realizedRate |
Normalize funding intervals before comparing venues
Rates compare only per common period, and a symbol's interval can change.
| Venue | Source |
|---|---|
| Binance | fundingInfo.fundingIntervalHours, current value only: 820 rows (466 at 4 hours, 350 at 8, 4 at 1), covering all 565 trading perpetuals, though its page describes only adjusted symbols |
| Bybit | fundingInterval in minutes on instruments-info (480 for BTCUSDT) |
| Deribit | Hourly rows that carry both interest_1h and interest_8h |
| OKX | Difference between fundingTime and nextFundingTime, per its documents |
For history, derive the interval from consecutive timestamps. Binance's GTCUSDT moved from 8 to 1 hour on 12 October 2026 and to 4 hours two days later, so one per-symbol setting mislabels older rows.
Hypothetical example. A rate of 0.01% per 8 hours and a rate of 0.005% per 4 hours are both 0.00125% per hour. Store the rate as published plus step_h, and divide only when you compare.
Open interest API: what each venue keeps
Current open interest is easy to get; Binance's public history stops at one month.
| Venue | Request | Measured limits |
|---|---|---|
| Binance | GET /futures/data/openInterestHist, periods 5m to 1d | Latest month: a start 30 days back worked, 31 days back gave HTTP 400, code -1130. The page says at most 500 rows; 1,000 also worked and 2,000 failed |
| Bybit | GET /v5/market/open-interest, 5min to 1d | 200 rows a page with a cursor; daily rows from 5 August 2020 |
| Hyperliquid | metaAndAssetCtxs | Current values only |
| OKX | GET /api/v5/rubik/stat/contracts/open-interest-history | Latest 1,440 entries at 100 a page: 5 days at 5m, 60 days at 1H, back to February 2024 at 1Dutc |
- Collect it yourself for longer history; a gap cannot be refilled once it leaves the window.
- Bulk files exist. Binance Vision (opens in a new tab) lists daily USD-M
metricsfiles from 1 September 2020 (288 rows a day recently, withsum_open_interest) under non-commercial terms. Hyperliquid's asset context files (opens in a new tab) are requester-pays and may have gaps. - Check units and sides. OKX gives contracts, coin and USD. Bybit documents
openInterestas both sides andsingleOpenInterest, added 11 June 2026, as one; on all 2,284 daily rows back to August 2020 one side was half, rounded up to 0.001. Binance's and OKX's pages do not say which they report.
Liquidation data API: why totals undercount
No venue here offers a complete public liquidation history, and two say in writing that their feed is partial.
| Venue | Source | What the page says or the call showed |
|---|---|---|
| Binance | <symbol>@forceOrder and all-market forceOrder@arr (the name starts with an exclamation mark) | One order per symbol per 1,000 ms. GET /fapi/v1/allForceOrders stopped on 27 April 2021 and returned 404 |
| Bybit | allLiquidation.{symbol}, 500 ms | Says it pushes all liquidations; subscribe per symbol |
| Deribit | Public trades, optional liquidation field | M, T or MT marks the liquidated side |
| Hyperliquid | No market-wide subscription found | Liquidations appear only in per-user events |
| OKX | liquidation-orders channel | "This data doesn't represent the total number of liquidations on OKX." An undocumented REST path also answered; treat it as unsupported |
Binance's documents conflict. The stream page says the latest order in each 1,000 ms is pushed; a change log entry of 10 April 2026 says the largest. Either way the rest are not sent. In the capture below, no symbol had two events under 1,000 ms apart by event time E (595 pairs), though 19 pairs were closer by order time T.
| Connection and scope | Events |
|---|---|
Binance /market/ws/, all symbols, USD-M and COIN-M merged | 804, across 209 symbols |
Binance unrouted /ws/, all symbols | 0, though it stayed connected |
| Bybit, 12 subscribed symbols | 193 |
| OKX, all swaps | 298, across 75 instruments |
Binance's change log set 23 April 2026 to decommission legacy URLs, so older code can connect and collect nothing; see the Binance WebSocket guide for routing. Normalize meaning too: Binance's S is the order side, so SELL closes a long (the page says only "Side"), while Bybit's Buy means a long was liquidated. Binance reports an average price, Bybit a bankruptcy price. Label any total as observed events, never as market-wide liquidations.
A tested collector for funding, open interest and liquidations
This script stores all three datasets in SQLite using the fixes above. It ran on 5 November 2026 (Python 3.11, requests 2.31, websockets 13.1).
"""Public endpoints only, no API keys."""
import asyncio, json, sqlite3, time
import requests, websockets
SYMBOL, SECONDS, HOUR = "BTCUSDT", 120, 3_600_000 # example symbol
db = sqlite3.connect("derivs.db") # symbol in every key: no overwrites
db.executescript("""
CREATE TABLE IF NOT EXISTS funding (venue, symbol, hour_ms, kind, rate, step_h, PRIMARY KEY (venue, symbol, hour_ms, kind));
CREATE TABLE IF NOT EXISTS open_interest (venue, symbol, ts_ms, oi, PRIMARY KEY (venue, symbol, ts_ms));
CREATE TABLE IF NOT EXISTS liquidation (venue, symbol, ts_ms, position, qty, price);
""")
def get(url, **params):
r = requests.get(url, params=params, timeout=15)
r.raise_for_status()
body = r.json()
if isinstance(body, dict) and (body.get("status") == "ERROR" or body.get("retCode")):
raise RuntimeError(body)
return body
def save_funding(venue, rows):
prev = {}
for ms, rate, kind in sorted(rows, key=lambda r: int(r[0])):
hour = int(ms) // HOUR * HOUR
step = (hour - prev[kind]) / HOUR if kind in prev else None
db.execute("INSERT OR REPLACE INTO funding VALUES (?,?,?,?,?,?)", (venue, SYMBOL, hour, kind, rate, step))
prev[kind] = hour
def binance_funding(start=1):
rows = []
while True:
page = get("https://fapi.binance.com/fapi/v1/fundingRate", symbol=SYMBOL, startTime=start, limit=1000)
rows += [(r["fundingTime"], r["fundingRate"], r.get("rateType", "")) for r in page]
if len(page) < 1000:
return save_funding("binance", rows)
start = page[-1]["fundingTime"] + 1
def bybit_funding(): # newest first: walk back with endTime
rows, end = [], int(time.time() * 1000)
while True:
page = get("https://api.bybit.com/v5/market/funding/history", category="linear",
symbol=SYMBOL, limit=200, endTime=end)["result"]["list"]
rows += [(r["fundingRateTimestamp"], r["fundingRate"], "") for r in page]
if len(page) < 200:
return save_funding("bybit", rows)
end = int(page[-1]["fundingRateTimestamp"]) - 1
def open_interest(): # run on a schedule to build history
rows = [("binance", SYMBOL, r["timestamp"], r["sumOpenInterest"]) for r in
get("https://fapi.binance.com/futures/data/openInterestHist", symbol=SYMBOL, period="1h", limit=500)]
rows += [("bybit", SYMBOL, int(r["timestamp"]), r["singleOpenInterest"]) for r in
get("https://api.bybit.com/v5/market/open-interest", category="linear", symbol=SYMBOL,
intervalTime="1h", limit=200)["result"]["list"]]
db.executemany("INSERT OR REPLACE INTO open_interest VALUES (?,?,?,?)", rows)
async def binance_liq():
stream = chr(33) + "forceOrder@arr" # the name starts with an exclamation mark
async with websockets.connect("wss://fstream.binance.com/market/ws/" + stream) as ws:
while True:
o = json.loads(await ws.recv()).get("o") # skip non-events
if o: # SELL closes a long
db.execute("INSERT INTO liquidation VALUES ('binance',?,?,?,?,?)",
(o["s"], o["T"], "long" if o["S"] == "SELL" else "short", o["z"], o["ap"]))
async def liquidations():
try:
await asyncio.wait_for(binance_liq(), SECONDS)
except asyncio.TimeoutError:
pass
except Exception as e: # keep the events already received
print("stream stopped:", repr(e))
binance_funding(); bybit_funding(); open_interest()
db.commit() # REST rows survive a stream failure
asyncio.run(liquidations())
db.commit()
for table in ("funding", "open_interest", "liquidation"):
print(table, db.execute(f"SELECT venue, count(*) FROM {table} GROUP BY venue").fetchall())Output (liquidation counts vary by run and cover all symbols):
funding [('binance', 7841), ('bybit', 7249)]
open_interest [('binance', 500), ('bybit', 200)]
liquidation [('binance', 11)]Add reconnects and gap alerts before leaving it running.
Data terms for derivatives data
Public does not mean free to reuse: read the terms before this data reaches a product or another person.
- OKX. The API Agreement (opens in a new tab) (updated 28 July 2026) counts funding rates and open interest as market data, and Section 9.4 limits it to personal, non-commercial trading and account management: no publishing or display to others without written consent, public endpoints included, and automated collection only at personal-trading scale.
- Binance Vision. Dataset Terms (opens in a new tab) (updated 26 August 2026): CC BY-NC-SA 4.0, and commercial use needs a separate written license.
- Not verified. Binance's and Hyperliquid's general terms did not load as text on 5 November 2026, Bybit's and Deribit's were not checked, and Hyperliquid's historical data page states no license. Ask in writing before commercial use.
More is in the crypto price API guide. For integration work in general, see Fincode's exchange API integration page; naming these venues here does not mean Fincode integrates them or has built on them.
Frequently asked questions
How far back does Binance funding rate history go?
For BTCUSDT, to 10 September 2019: 7,841 rows on 5 November 2026. Send startTime=1; 0 returned only the latest 500 rows.
Why does Binance open interest history return an error for older dates?
openInterestHist keeps only the latest month: a start 31 days back returned HTTP 400, code -1130. Collect history as you go, or use archive files under their terms.
Is there a Binance liquidation data API?
Market-wide, only the WebSocket streams, at most one order per symbol per second. GET /fapi/v1/allForceOrders stopped in 2021; forceOrders needs a key and covers only your account.
Can I compare funding rates across exchanges directly?
Not until they share a period: divide each rate by its interval in hours, taking the interval from timestamps, because it can change.
Sources
- Binance USD-M Futures: Market data REST API (funding rate history, funding info, open interest statistics) (opens in a new tab)
- Binance USD-M Futures: WebSocket market streams (liquidation order streams, URL paths) (opens in a new tab)
- Binance USD-M Futures: Change log (rateType, liquidation stream wording, legacy URL date, allForceOrders) (opens in a new tab)
- Bybit V5 API: Get Funding Rate History (opens in a new tab)
- Bybit V5 API: Get Open Interest (opens in a new tab)
- Bybit V5 API: All Liquidation stream (opens in a new tab)
- Bybit V5 API: Changelog (singleOpenInterest 11 June 2026, All Liquidation 20 February 2025) (opens in a new tab)
- OKX API v5 documentation (funding rate history, open interest history, liquidation orders channel, historical market data) (opens in a new tab)
- OKX API Agreement, Section 9.4 Market Data (updated 28 July 2026) (opens in a new tab)
- Deribit API: public/get_funding_rate_history (opens in a new tab)
- Deribit API: public/get_last_trades_by_instrument (liquidation field) (opens in a new tab)
- Hyperliquid Docs: Info endpoint, perpetuals (fundingHistory, metaAndAssetCtxs) (opens in a new tab)
- Hyperliquid Docs: Rate limits and user limits (opens in a new tab)
- Resmî Gazete: SPK Communiqué III-35/B.2, Article 14, 13 March 2025 (Turkish) (opens in a new tab)
- Capital Markets Law No. 6362, consolidated text, Article 99/A (Turkish) (opens in a new tab)
This guide is general information about software and markets, not investment, legal or tax advice. Automated trading can lose money, past or backtested performance does not guarantee future results, and the rules that apply depend on your jurisdiction and your exchange's terms. Sources, checks and corrections: see the editorial policy.