# Funding rate history API: open interest, liquidation data

URL: https://fincodelabs.com/en/blog/funding-rate-history-api · Publisher: Fincode (Fincode Yazılım ve Teknoloji A.Ş.), Istanbul, Turkey · Category: Exchange APIs · Published: 2026-11-06 · Updated: 2026-11-06

Funding rate history API by venue, tested 5 Nov 2026: rows, page limits and traps, Binance's one-month open interest limit, why liquidation feeds undercount.

**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](https://fincodelabs.com/en/blog/perpetual-futures-funding-rate), and payment arithmetic in the [funding rate calculator](https://fincodelabs.com/en/tools/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.

**BTC perpetual funding history, called 5 November 2026 (alphabetical)**

| 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](https://www.okx.com/historical-data) 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.

**Behavior seen 5 November 2026**

| 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.

**Where the interval comes from**

| 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.

**Open interest endpoints, called 5 November 2026 (alphabetical)**

| 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](https://data.binance.vision/) lists daily USD-M `metrics` files from 1 September 2020 (288 rows a day recently, with `sum_open_interest`) under non-commercial terms. Hyperliquid's [asset context files](https://hyperliquid.gitbook.io/hyperliquid-docs/historical-data) are requester-pays and may have gaps.
- **Check units and sides.** OKX gives contracts, coin and USD. Bybit documents `openInterest` as both sides and `singleOpenInterest`, 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.

**Public liquidation sources, documents read 5 November 2026 (alphabetical)**

| 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`.

**15-minute capture, 5 November 2026, 21:13 to 21:28 UTC (scopes differ: not a venue comparison)**

| 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](https://fincodelabs.com/en/blog/binance-websocket-api) 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).

```python
"""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](https://www.okx.com/help/okx-api-agreement) (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](https://data.binance.vision/terms-of-use.html) (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](https://fincodelabs.com/en/blog/crypto-price-api). For integration work in general, see Fincode's [exchange API integration](https://fincodelabs.com/en/services/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)](https://developers.binance.com/en/docs/catalog/core-trading-derivatives-trading-usd-s-m-futures/api/rest-api/market-data)
- [Binance USD-M Futures: WebSocket market streams (liquidation order streams, URL paths)](https://developers.binance.com/en/docs/catalog/core-trading-derivatives-trading-usd-s-m-futures/api/ws-streams/market)
- [Binance USD-M Futures: Change log (rateType, liquidation stream wording, legacy URL date, allForceOrders)](https://developers.binance.com/en/docs/products/derivatives-trading-usds-futures/change-log)
- [Bybit V5 API: Get Funding Rate History](https://bybit-exchange.github.io/docs/v5/market/history-fund-rate)
- [Bybit V5 API: Get Open Interest](https://bybit-exchange.github.io/docs/v5/market/open-interest)
- [Bybit V5 API: All Liquidation stream](https://bybit-exchange.github.io/docs/v5/websocket/public/all-liquidation)
- [Bybit V5 API: Changelog (singleOpenInterest 11 June 2026, All Liquidation 20 February 2025)](https://bybit-exchange.github.io/docs/changelog/v5)
- [OKX API v5 documentation (funding rate history, open interest history, liquidation orders channel, historical market data)](https://www.okx.com/docs-v5/en/)
- [OKX API Agreement, Section 9.4 Market Data (updated 28 July 2026)](https://www.okx.com/help/okx-api-agreement)
- [Deribit API: public/get_funding_rate_history](https://docs.deribit.com/api-reference/market-data/public-get_funding_rate_history)
- [Deribit API: public/get_last_trades_by_instrument (liquidation field)](https://docs.deribit.com/api-reference/market-data/public-get_last_trades_by_instrument)
- [Hyperliquid Docs: Info endpoint, perpetuals (fundingHistory, metaAndAssetCtxs)](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/info-endpoint/perpetuals)
- [Hyperliquid Docs: Rate limits and user limits](https://hyperliquid.gitbook.io/hyperliquid-docs/for-developers/api/rate-limits-and-user-limits)
- [Resmî Gazete: SPK Communiqué III-35/B.2, Article 14, 13 March 2025 (Turkish)](https://www.resmigazete.gov.tr/eskiler/2025/03/20250313-6.htm)
- [Capital Markets Law No. 6362, consolidated text, Article 99/A (Turkish)](https://www.mevzuat.gov.tr/mevzuatmetin/1.5.6362.pdf)

> 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](https://fincodelabs.com/en/editorial-policy).

---

Published by Fincode (Fincode Yazılım ve Teknoloji A.Ş.), a software company in Istanbul, Turkey: https://fincodelabs.com/en/blog/funding-rate-history-api

Cite as: Fincode, "Funding rate history API: open interest, liquidation data", updated November 6, 2026, https://fincodelabs.com/en/blog/funding-rate-history-api
