The current funding rate and the next funding time, one row each time either changes.
/api/v1/data/raw/funding_rate
exchange_timestamptimestampWhen the venue says the event happened (UTC, µs). Exact, except modelled on Hyperliquid, whose feed carries no exchange time: there the file has an exchange_timestamp_kind column ("modelled") right after it.local_timestamptimestampWhen the event reached our capture machine (UTC, µs).funding_ratefloat64Funding rate for the current period, as the venue publishes itnext_funding_timestamptimestamp, nullableWhen the current funding period settles (UTC, µs)| Venue | Symbols | From |
|---|---|---|
| Binance | 985 | Jan 2020 |
| OKX | 697 | Sep 2019 |
| Hyperliquid | 525 | Feb 2025 |
One file per calendar month before 2026-08-01, one per day from then on, in the aperiodic-raw-derivatives bucket. Example key:
v1/funding_rate/exchange=binance-futures/symbol=perpetual-BTC-USDT:USDT/year=2025/month=06/data.parquet
The shared DEMO-KEY gets the 2025-06 file of each venue's BTC perpetual. No account needed.
# Install the Aperiodic CLI into ~/.local/bin
mkdir -p "$HOME/.local/bin"
curl -fsSL https://raw.githubusercontent.com/aperiodic-io/cli/main/install.sh | INSTALL_DIR="$HOME/.local/bin" bash
export PATH="$HOME/.local/bin:$PATH"
# Download the 2025-06 funding_rate file into ./raw — no API key needed
aperiodic raw funding_rate --preview \
--exchange binance-futures \
--symbol perpetual-BTC-USDT:USDT \
--output-dir ./raw && echo "Saved to $PWD/raw"pip install "aperiodic[polars]"from datetime import date
import aperiodic as ap
# Into one DataFrame (monthly files are trimmed to your range)
df = ap.get_raw(api_key="YOUR_KEY", dataset="funding_rate",
exchange="binance-futures", symbol="perpetual-BTC-USDT:USDT",
start_date=date(2025, 6, 1), end_date=date(2025, 6, 30))
print(df.head())
# Or stream the files to disk, skipping ones you already have
ap.download_raw(api_key="YOUR_KEY", dataset="funding_rate",
exchange="binance-futures", symbol="perpetual-BTC-USDT:USDT",
start_date=date(2025, 1, 1), end_date=date(2025, 12, 31),
output_dir="raw")Read the folder back one dataset at a time, with a glob:
# DuckDB, from the folder that holds ./raw
duckdb -c "SELECT * FROM read_parquet('raw/funding_rate/**/data.parquet')
WHERE exchange_timestamp >= '2025-06-01' LIMIT 10"from datetime import datetime, timezone
import polars as pl
df = (
pl.scan_parquet("raw/funding_rate/**/data.parquet")
.filter(pl.col("exchange_timestamp") >= datetime(2025, 6, 1, tzinfo=timezone.utc))
.collect()
)
print(df.head())exchange_timestamp is the venue's own time. local_timestamp is when the event reached our capture machine.exchange_timestamp is modelled; those files say so in an exchange_timestamp_kind column.