candleSnapshot | Hyperliquid Info API
curl --request POST \
--url https://hypercore.goldrushdata.com/info \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"type": "<string>",
"req": {
"coin": "<string>",
"interval": "<string>",
"startTime": 123,
"endTime": 123
}
}
'import requests
url = "https://hypercore.goldrushdata.com/info"
payload = {
"type": "<string>",
"req": {
"coin": "<string>",
"interval": "<string>",
"startTime": 123,
"endTime": 123
}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
type: '<string>',
req: {coin: '<string>', interval: '<string>', startTime: 123, endTime: 123}
})
};
fetch('https://hypercore.goldrushdata.com/info', 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://hypercore.goldrushdata.com/info",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'type' => '<string>',
'req' => [
'coin' => '<string>',
'interval' => '<string>',
'startTime' => 123,
'endTime' => 123
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://hypercore.goldrushdata.com/info"
payload := strings.NewReader("{\n \"type\": \"<string>\",\n \"req\": {\n \"coin\": \"<string>\",\n \"interval\": \"<string>\",\n \"startTime\": 123,\n \"endTime\": 123\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://hypercore.goldrushdata.com/info")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"type\": \"<string>\",\n \"req\": {\n \"coin\": \"<string>\",\n \"interval\": \"<string>\",\n \"startTime\": 123,\n \"endTime\": 123\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://hypercore.goldrushdata.com/info")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"type\": \"<string>\",\n \"req\": {\n \"coin\": \"<string>\",\n \"interval\": \"<string>\",\n \"startTime\": 123,\n \"endTime\": 123\n }\n}"
response = http.request(request)
puts response.read_body{
"t": 123,
"T": 123,
"s": "<string>",
"i": "<string>",
"o": "<string>",
"c": "<string>",
"h": "<string>",
"l": "<string>",
"v": "<string>",
"n": 123
}Info API
candleSnapshot | Hyperliquid Info API
Hyperliquid candleSnapshot: fetch historical OHLCV candles for a coin and interval over a time window for charting and backtesting.
POST
/
info
candleSnapshot | Hyperliquid Info API
curl --request POST \
--url https://hypercore.goldrushdata.com/info \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"type": "<string>",
"req": {
"coin": "<string>",
"interval": "<string>",
"startTime": 123,
"endTime": 123
}
}
'import requests
url = "https://hypercore.goldrushdata.com/info"
payload = {
"type": "<string>",
"req": {
"coin": "<string>",
"interval": "<string>",
"startTime": 123,
"endTime": 123
}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
type: '<string>',
req: {coin: '<string>', interval: '<string>', startTime: 123, endTime: 123}
})
};
fetch('https://hypercore.goldrushdata.com/info', 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://hypercore.goldrushdata.com/info",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'type' => '<string>',
'req' => [
'coin' => '<string>',
'interval' => '<string>',
'startTime' => 123,
'endTime' => 123
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://hypercore.goldrushdata.com/info"
payload := strings.NewReader("{\n \"type\": \"<string>\",\n \"req\": {\n \"coin\": \"<string>\",\n \"interval\": \"<string>\",\n \"startTime\": 123,\n \"endTime\": 123\n }\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://hypercore.goldrushdata.com/info")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"type\": \"<string>\",\n \"req\": {\n \"coin\": \"<string>\",\n \"interval\": \"<string>\",\n \"startTime\": 123,\n \"endTime\": 123\n }\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://hypercore.goldrushdata.com/info")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"type\": \"<string>\",\n \"req\": {\n \"coin\": \"<string>\",\n \"interval\": \"<string>\",\n \"startTime\": 123,\n \"endTime\": 123\n }\n}"
response = http.request(request)
puts response.read_body{
"t": 123,
"T": 123,
"s": "<string>",
"i": "<string>",
"o": "<string>",
"c": "<string>",
"h": "<string>",
"l": "<string>",
"v": "<string>",
"n": 123
}Credit Cost
1 per call
Processing
Realtime
type: "candleSnapshot" is used to fetch historical OHLCV candles for a coin and interval over a time window for charting and backtesting.
Estimate your monthly cost for this API using the Pricing Calculator.
- Wire-equal to
POST api.hyperliquid.xyz/infowith{"type": "candleSnapshot", "req": {...}}. Note the nestedreqobject. - Each response contains at most 5,000 candles (per-response cap, not a retention limit); page by advancing
startTimefor longer ranges. - GoldRush serves candles from a dedicated HyperCore historical store, so candles older than the upstream window can extend back to GoldRush’s full HyperCore coverage.
[startTime, endTime] window. Each candle carries the open/close timestamps, the coin, the interval, open/high/low/close prices, base volume, and trade count. Use it for chart backfills, indicator computation, and backtests.
This is a global, non-user-keyed type. NOT LIMITED TO THE MOST RECENT 5,000 CANDLES. GoldRush serves it from a dedicated HyperCore historical store so candles older than the upstream window remain available; page through time by advancing startTime.
Endpoint
POST https://hypercore.goldrushdata.com/info
Authorization: Bearer <GOLDRUSH_API_KEY>
Content-Type: application/json
Request
The request parameters are nested inside areq object.
string
default:"candleSnapshot"
required
Always
"candleSnapshot".object
required
The candle query parameters.
Show properties
Show properties
string
required
The asset symbol, e.g.
"BTC". HIP-3 markets use the deployer-prefixed form.string
required
Candle interval. One of
"1m", "3m", "5m", "15m", "30m", "1h", "2h", "4h", "8h", "12h", "1d", "3d", "1w", "1M".int
required
Unix timestamp in milliseconds. Inclusive lower bound for the window.
int
Unix timestamp in milliseconds. Inclusive upper bound. Defaults to current server time when omitted.
Example
curl -X POST https://hypercore.goldrushdata.com/info \
-H "Authorization: Bearer $GOLDRUSH_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "candleSnapshot",
"req": {
"coin": "BTC",
"interval": "1h",
"startTime": 1735689600000,
"endTime": 1735776000000
}
}'
const response = await fetch("https://hypercore.goldrushdata.com/info", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.GOLDRUSH_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
type: "candleSnapshot",
req: {
coin: "BTC",
interval: "1h",
startTime: 1735689600000,
endTime: 1735776000000,
},
}),
});
const candles = await response.json();
import os, requests
response = requests.post(
"https://hypercore.goldrushdata.com/info",
headers={"Authorization": f"Bearer {os.environ['GOLDRUSH_API_KEY']}"},
json={
"type": "candleSnapshot",
"req": {
"coin": "BTC",
"interval": "1h",
"startTime": 1735689600000,
"endTime": 1735776000000,
},
},
)
candles = response.json()
Response
An array of candle objects, oldest first.[
{
"t": 1735689600000,
"T": 1735693199999,
"s": "BTC",
"i": "1h",
"o": "62739.0",
"c": "62960.0",
"h": "63118.0",
"l": "62711.0",
"v": "921.9829",
"n": 16396
}
]
Field descriptions
The price and volume fields (
o, c, h, l, v) are returned as decimal strings, preserving upstream precision. Do not parse them as floats.int
Candle open time, Unix milliseconds.
int
Candle close time, Unix milliseconds.
string
Coin symbol.
string
Candle interval - echoes the request
interval.string
Open price.
string
Close price.
string
High price.
string
Low price.
string
Base-asset volume over the candle.
int
Number of trades in the candle.
Paginating a large backfill
Each response returns at most 5,000 candles - a per-response cap, not a limit on how far back history goes. To backfill a range wider than 5,000 candles, page forward through time: start at your window’sstartTime, then set the next request’s startTime to the last candle’s close time (T) plus one millisecond. Repeat until a response returns fewer than 5,000 candles.
Because T is the inclusive close of a candle and the next candle opens at T + 1, advancing to T + 1 lands exactly on the following candle - no overlap to de-duplicate and no gaps.
async function backfillCandles(
coin: string,
interval: string,
startTime: number,
endTime: number,
) {
const all: any[] = [];
let cursor = startTime;
while (cursor < endTime) {
const res = await fetch("https://hypercore.goldrushdata.com/info", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.GOLDRUSH_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
type: "candleSnapshot",
req: { coin, interval, startTime: cursor, endTime },
}),
});
const page = await res.json();
if (page.length === 0) break;
all.push(...page);
// Advance to one millisecond past the last candle's close time.
cursor = page[page.length - 1].T + 1;
// A short page means we've reached the end of the range.
if (page.length < 5000) break;
}
return all;
}
import os, requests
def backfill_candles(coin, interval, start_time, end_time):
all_candles = []
cursor = start_time
while cursor < end_time:
res = requests.post(
"https://hypercore.goldrushdata.com/info",
headers={"Authorization": f"Bearer {os.environ['GOLDRUSH_API_KEY']}"},
json={
"type": "candleSnapshot",
"req": {
"coin": coin,
"interval": interval,
"startTime": cursor,
"endTime": end_time,
},
},
)
page = res.json()
if not page:
break
all_candles.extend(page)
# Advance to one millisecond past the last candle's close time.
cursor = page[-1]["T"] + 1
# A short page means we've reached the end of the range.
if len(page) < 5000:
break
return all_candles
Pick the coarsest
interval that satisfies your use case - larger intervals cover more calendar time per 5,000-candle page, so a multi-year 1d backfill is a single request while the same range at 1m pages many times.Related endpoints
l2BookDiffSnapshot
fetch a full-depth L2 order book snapshot for one coin, with height, epoch, and seq to bootstrap the l2BookDiff2 stream.
allMids
fetch the current mid price for every actively traded asset in a single call.
fundingHistory
fetch a coin’s historical funding rates and premiums over a time window for funding analytics and basis strategies.
l2Book
fetch an aggregated Level-2 order book snapshot for a single coin - bids and asks as price, size, and order-count levels.