Hourly market panel (open interest, mark, oracle, funding, volume)
curl --request GET \
--url https://api.ironflow.sh/v1/markets/hourly \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.ironflow.sh/v1/markets/hourly"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.ironflow.sh/v1/markets/hourly', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.ironflow.sh/v1/markets/hourly",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.ironflow.sh/v1/markets/hourly"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.ironflow.sh/v1/markets/hourly")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.ironflow.sh/v1/markets/hourly")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"data": [
{
"timestamp": 1794528000000,
"market": "BTC-PERP",
"market_id": 0,
"market_class": "perp",
"dex": "",
"open": 71448,
"high": 71507,
"low": 70624,
"close": 71109,
"volume": 3463.12,
"volume_usd": 246018390.33,
"taker_buy_usd": 94154048.84,
"taker_sell_usd": 151864341.49,
"liquidation_usd": 19530228.46,
"trades": 27256,
"open_interest": 39517.2047,
"open_interest_usd": 2811119583.86,
"mark_price": 71136.6,
"oracle_price": 71162,
"funding_rate": 0.0000125
}
],
"pagination": {
"next_cursor": "MTcxODQwMDAwMDAwMC00Mg==",
"has_more": true
},
"complete_until": 1794657600000,
"notice": "<string>"
}{
"error": {
"code": "BAD_REQUEST",
"message": "market is required (e.g. BTC-PERP)"
}
}{
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded. Retry after 60 seconds.",
"upgrade": {
"plan": "explorer",
"price_usdc": 49,
"days": 30,
"unlocks": "<string>",
"limit": "rate",
"lifts": "60 requests a minute now, 100 on Explorer",
"url": "<string>",
"how": "<string>",
"buy_url": "<string>",
"pay_per_call": {}
},
"get_key": {
"method": "POST",
"url": "https://api.ironflow.sh/v1/keys",
"body": {
"email": "[email protected]"
},
"page": "<string>"
},
"dataset": {
"name": "Hyperliquid Liquidations",
"url": "https://huggingface.co/datasets/ironflow/hyperliquid-liquidations?utm_source=api",
"holds": "every liquidation",
"from": "2025-05-25",
"through": "2026-10-31"
},
"ironbox": {
"why": "No rate limits inside an Ironbox: your agent runs next to Hyperliquid with the data on the box.",
"create": "POST https://api.ironflow.sh/v1/ironbox",
"url": "https://ironflow.sh/ironbox?utm_source=api"
},
"stream": "GET https://api.ironflow.sh/v1/liquidations/stream (1 credit a minute)",
"allowed_from": 1794394800000,
"did_you_mean": [
"xyz:GOLD-PERP",
"PAXG-PERP"
]
}
}{
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded. Retry after 60 seconds.",
"upgrade": {
"plan": "explorer",
"price_usdc": 49,
"days": 30,
"unlocks": "<string>",
"limit": "rate",
"lifts": "60 requests a minute now, 100 on Explorer",
"url": "<string>",
"how": "<string>",
"buy_url": "<string>",
"pay_per_call": {}
},
"get_key": {
"method": "POST",
"url": "https://api.ironflow.sh/v1/keys",
"body": {
"email": "[email protected]"
},
"page": "<string>"
},
"dataset": {
"name": "Hyperliquid Liquidations",
"url": "https://huggingface.co/datasets/ironflow/hyperliquid-liquidations?utm_source=api",
"holds": "every liquidation",
"from": "2025-05-25",
"through": "2026-10-31"
},
"ironbox": {
"why": "No rate limits inside an Ironbox: your agent runs next to Hyperliquid with the data on the box.",
"create": "POST https://api.ironflow.sh/v1/ironbox",
"url": "https://ironflow.sh/ironbox?utm_source=api"
},
"stream": "GET https://api.ironflow.sh/v1/liquidations/stream (1 credit a minute)",
"allowed_from": 1794394800000,
"did_you_mean": [
"xyz:GOLD-PERP",
"PAXG-PERP"
]
}
}{
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded. Retry after 60 seconds."
}
}{
"error": {
"code": "INTERNAL_ERROR",
"message": "An unexpected error occurred"
}
}{
"error": {
"code": "QUERY_TIMEOUT",
"message": "query took too long — narrow your time range, add a market filter, or reduce the limit"
}
}Market Data
Hyperliquid hourly market panel: open interest, funding, volume
GET /v1/markets/hourly returns one row per Hyperliquid market and hour: open interest, mark, oracle, funding, OHLC, volume, taker flow and liquidations.
GET
/
v1
/
markets
/
hourly
Hourly market panel (open interest, mark, oracle, funding, volume)
curl --request GET \
--url https://api.ironflow.sh/v1/markets/hourly \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.ironflow.sh/v1/markets/hourly"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.ironflow.sh/v1/markets/hourly', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.ironflow.sh/v1/markets/hourly",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.ironflow.sh/v1/markets/hourly"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.ironflow.sh/v1/markets/hourly")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.ironflow.sh/v1/markets/hourly")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"data": [
{
"timestamp": 1794528000000,
"market": "BTC-PERP",
"market_id": 0,
"market_class": "perp",
"dex": "",
"open": 71448,
"high": 71507,
"low": 70624,
"close": 71109,
"volume": 3463.12,
"volume_usd": 246018390.33,
"taker_buy_usd": 94154048.84,
"taker_sell_usd": 151864341.49,
"liquidation_usd": 19530228.46,
"trades": 27256,
"open_interest": 39517.2047,
"open_interest_usd": 2811119583.86,
"mark_price": 71136.6,
"oracle_price": 71162,
"funding_rate": 0.0000125
}
],
"pagination": {
"next_cursor": "MTcxODQwMDAwMDAwMC00Mg==",
"has_more": true
},
"complete_until": 1794657600000,
"notice": "<string>"
}{
"error": {
"code": "BAD_REQUEST",
"message": "market is required (e.g. BTC-PERP)"
}
}{
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded. Retry after 60 seconds.",
"upgrade": {
"plan": "explorer",
"price_usdc": 49,
"days": 30,
"unlocks": "<string>",
"limit": "rate",
"lifts": "60 requests a minute now, 100 on Explorer",
"url": "<string>",
"how": "<string>",
"buy_url": "<string>",
"pay_per_call": {}
},
"get_key": {
"method": "POST",
"url": "https://api.ironflow.sh/v1/keys",
"body": {
"email": "[email protected]"
},
"page": "<string>"
},
"dataset": {
"name": "Hyperliquid Liquidations",
"url": "https://huggingface.co/datasets/ironflow/hyperliquid-liquidations?utm_source=api",
"holds": "every liquidation",
"from": "2025-05-25",
"through": "2026-10-31"
},
"ironbox": {
"why": "No rate limits inside an Ironbox: your agent runs next to Hyperliquid with the data on the box.",
"create": "POST https://api.ironflow.sh/v1/ironbox",
"url": "https://ironflow.sh/ironbox?utm_source=api"
},
"stream": "GET https://api.ironflow.sh/v1/liquidations/stream (1 credit a minute)",
"allowed_from": 1794394800000,
"did_you_mean": [
"xyz:GOLD-PERP",
"PAXG-PERP"
]
}
}{
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded. Retry after 60 seconds.",
"upgrade": {
"plan": "explorer",
"price_usdc": 49,
"days": 30,
"unlocks": "<string>",
"limit": "rate",
"lifts": "60 requests a minute now, 100 on Explorer",
"url": "<string>",
"how": "<string>",
"buy_url": "<string>",
"pay_per_call": {}
},
"get_key": {
"method": "POST",
"url": "https://api.ironflow.sh/v1/keys",
"body": {
"email": "[email protected]"
},
"page": "<string>"
},
"dataset": {
"name": "Hyperliquid Liquidations",
"url": "https://huggingface.co/datasets/ironflow/hyperliquid-liquidations?utm_source=api",
"holds": "every liquidation",
"from": "2025-05-25",
"through": "2026-10-31"
},
"ironbox": {
"why": "No rate limits inside an Ironbox: your agent runs next to Hyperliquid with the data on the box.",
"create": "POST https://api.ironflow.sh/v1/ironbox",
"url": "https://ironflow.sh/ironbox?utm_source=api"
},
"stream": "GET https://api.ironflow.sh/v1/liquidations/stream (1 credit a minute)",
"allowed_from": 1794394800000,
"did_you_mean": [
"xyz:GOLD-PERP",
"PAXG-PERP"
]
}
}{
"error": {
"code": "RATE_LIMIT_EXCEEDED",
"message": "Rate limit exceeded. Retry after 60 seconds."
}
}{
"error": {
"code": "INTERNAL_ERROR",
"message": "An unexpected error occurred"
}
}{
"error": {
"code": "QUERY_TIMEOUT",
"message": "query took too long — narrow your time range, add a market filter, or reduce the limit"
}
}One row per market and UTC hour, ready to use: open interest, mark and oracle price at the end of the hour, the funding rate charged for the hour, open, high, low and close, volume in coins and USD, taker buy and sell USD, liquidation USD and trade count. In SQL the same rows are
History by plan:
A
hl.market_hourly.
# BTC, last 7 days, one row per hour
curl "https://api.ironflow.sh/v1/markets/hourly?market=BTC-PERP&from=-7d" \
-H "Authorization: Bearer $IRONFLOW_KEY"
# Every market for one day, page by page
curl "https://api.ironflow.sh/v1/markets/hourly?from=2026-11-13&to=2026-11-14&limit=1000" \
-H "Authorization: Bearer $IRONFLOW_KEY"
| Plan | History |
|---|---|
| No key | 24 hours |
| Free key, or one call paid with x402 | 14 days |
| Explorer | 90 days |
| Builder | 1 year |
| Enterprise | Everything since May 2025 |
from before your history is moved up, with a notice. A range that ends before it answers HISTORY_OUT_OF_RANGE with allowed_from, the earliest from that works.
Paging: without market you get every market, at most one day of hours per page. Pass pagination.next_cursor as cursor while has_more is true; a page can hold fewer than limit rows and still have more after it.
Values:
funding_rateis the rate charged for the hour, settled when the hour ends. Where the settlement is missing, it is the last rate seen during the hour.open_interestis in the base asset;open_interest_usdis it timesmark_price.- Null means no value:
opentoclosein an hour without trades; open interest, mark, oracle and funding on spot and outcome markets. - Only complete hours are served.
complete_untilis the end of the newest one; an hour appears a few minutes after it ends.
Authorizations
Ironflow API key, format if_xxxx. Free keys at https://ironflow.sh/key. Optional on read endpoints.
Query Parameters
Response
One page of market hours.