sifting/io
GET/hist/crypto/:symbol/barsgzip required

Crypto bars

Paginated OHLCV bars for a USD-quoted crypto asset, from 1-minute through 1-hour. Each bar carries t (Unix epoch milliseconds, UTC, marking the bucket's open time), o/h/l/c as float prices, and v as the base-asset volume (e.g. 12.345 BTC). v is a float, so fractional volumes are preserved. Note that on /hist/stocks v is whole shares and on /hist/forex v is always 0; the wire shape is shared, the semantics differ per asset class. All time inputs are UTC.

Parameters

Parameter
symbolrequiredstring · path
Concatenated USD-quoted form, uppercase. Currently supported (15 pairs): BTCUSD, ETHUSD, SOLUSD, BNBUSD, XRPUSD, ADAUSD, DOGEUSD, AVAXUSD, LINKUSD, DOTUSD, MATICUSD, LTCUSD, BCHUSD, UNIUSD, ATOMUSD. Anything outside this set returns 404.
startstring · query
Inclusive lower bound on bar time. Required on the first page; cursor overrides on subsequent pages. Accepts YYYY-MM-DD (midnight UTC) or full RFC3339 (2024-01-01T00:00:00Z).
endstring · query
Inclusive upper bound on bar time. Same shape as start. Defaults to now.
intervalstring · query
Bar size. One of: 1m, 5m, 15m, 30m, 1h. Default 1m. Same enum as /hist/stocks and /hist/forex.
limitinteger · query
Bars per page. Default 1000, max 5000. Higher than stocks/forex (2000) to support multi-year backtests in fewer round trips.
cursorstring · query
Pagination token. Opaque. Pass back the value of meta.next_cursor from the previous response verbatim. When present, overrides start. Subsequent pages need no other parameters; the cursor encodes the next start.
Accept-Encodingrequiredstring · header
Must include gzip; otherwise the endpoint returns 406 gzip_required. A 5000-bar page is ~350 KB uncompressed, ~50 KB gzipped.

Example

request · shell
# Recent BTC, 1h bars, single pagecurl -H "X-API-Key: $KEY" -H "Accept-Encoding: gzip" --compressed \  "https://api.sifting.io/v1/hist/crypto/BTCUSD/bars?start=2026-05-01&interval=1h" # Deep history (handled automatically by the pipeline)curl -H "X-API-Key: $KEY" -H "Accept-Encoding: gzip" --compressed \  "https://api.sifting.io/v1/hist/crypto/BTCUSD/bars?start=2014-01-01&end=2014-06-01&interval=1h&limit=5000"
200OKapplication/json (gzip)
{  "data": [    {      "t": 1704067200000,      "o": 42283.58,      "h": 42410.0,      "l": 42250.1,      "c": 42390.5,      "v": 12.345    }  ],  "meta": {    "symbol": "BTCUSD",    "interval": "1h",    "as_of": "2026-05-21T14:23:11Z",    "next_cursor": "MTcwNDA3MDgwMQ"  }}
Loading runner…
First load only

Reference

Result shapes by symbol state
Known symbol, bars in range
200 OK with a populated data array.
Known symbol, empty window
200 OK with data: [].
Window predates all coverage
422 data_unavailable, body carries `earliest` so clients can retry.
Unknown symbol
404 not_found (symbol outside the supported set).
Per-bar fields
t
Bar open time, Unix epoch milliseconds, UTC.
o, h, l, c
Open, high, low, close.
v
Base-asset volume as a float (e.g. 12.345 BTC). Fractional volumes preserved.
meta.next_cursor
Present only when more data exists within the requested window; absent at the tail.
Coverage today
Approximate earliest dates
BTC 2013-09, LTC 2014-01, XRP 2014-07, ETH 2015-08, ADA 2017-10. Most newer L1s start somewhere between 2019 and 2021. The data_unavailable error body carries the exact earliest date for the requested symbol.
Performance
Recent windows
A 5000-bar request typically completes in 1–2 seconds.
Deep history
A 5000-bar request that reaches into deep-history windows typically completes in ~7 seconds. Slower by design, the alternative was no deep history.
Caching
Settled windows (≥7 days old) are cached for 30 days; recent windows for 5 minutes. Repeat queries within those windows return instantly.
Pagination pattern
First call
?start=2024-01-01&interval=1h&limit=5000
Next call
If meta.next_cursor is present, call again with ?cursor=<token>. No other parameters needed.
Tail
Repeat until meta.next_cursor is absent.

Error responses

  • 404not_found

    Symbol outside the supported set.

    {  "error": "not_found",  "message": "Symbol not found."}
  • 400invalid_parameter

    Malformed start, end, limit, or cursor.

    {  "error": "invalid_parameter",  "message": "start must be YYYY-MM-DD or RFC3339."}
  • 400interval_unsupported_for_market

    Interval outside the canonical 1m | 5m | 15m | 30m | 1h enum.

    {  "error": "interval_unsupported_for_market",  "message": "interval must be one of: 1m, 5m, 15m, 30m, 1h."}
  • 422data_unavailable

    Start predates every source in our aggregation pipeline for this symbol (e.g. BTC bars from 2010). Body carries `earliest`. Retry with start ≥ that date.

    {  "error": "data_unavailable",  "message": "no source in our aggregation pipeline has data for the requested window",  "earliest": "2013-09-13",  "symbol": "BTCUSD"}
  • 406gzip_required

    Heavy endpoint called without Accept-Encoding: gzip.

    { "error": "gzip_required" }
  • 502upstream_error

    Our aggregation pipeline returned an error response.

    { "error": "upstream_error" }
  • 502malformed_upstream

    Our aggregation pipeline returned an unparseable payload.

    { "error": "malformed_upstream" }
  • 503upstream_rate_limited

    Our aggregation pipeline hit its rate limit. Try again shortly.

    { "error": "upstream_rate_limited" }
  • 503historical_unavailable

    Crypto historical data is not configured on this deployment.

    { "error": "historical_unavailable" }

More in Historical OHLCV

See all