/v1/hist/crypto/:symbol/barsgzip requiredCrypto bars
Paginated OHLCV bars for a USD-quoted crypto asset, from 1-minute through monthly. 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.
- Auth
X-API-Keyheader- Format
- JSON, gzip-encoded
- Rate limits
- Per-key, see limits
Example
curl -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"{ "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" }}Parameters
symbolrequiredstring · path- Concatenated USD-quoted form, uppercase, written with no slash: BTCUSD and ETHUSD, not BTC/USD. A slashed form does not resolve to this endpoint. Browse the crypto symbol pages for the exact string to use.
startrequiredstring · 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) only. Epoch milliseconds (e.g. 1746144000000) are not accepted and return 400 invalid_parameter.
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, 1d, 1w, 1mo. Default 1m. Same enum across every /hist/* bars endpoint, so a single client schema works across asset classes.
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.
Response fields
data[]array- OHLCV bars, oldest first, one per interval bucket.
data[].tint64 (epoch ms)- Bar open time, Unix epoch milliseconds, UTC. The bar covers [t, t + interval).
data[].ofloat- Open price.
data[].hfloat- High price.
data[].lfloat- Low price.
data[].cfloat- Close price.
data[].vfloat- Base-asset volume traded in the bucket (e.g. 12.345 BTC). Fractional volumes preserved.
meta.symbolstring- Echoed symbol.
meta.intervalstring- Echoed bar size.
meta.as_ofstring- When the response was produced. RFC 3339, UTC.
meta.next_cursorstring- Opaque pagination token. Present only when more data exists within the requested window; absent at the tail.
Reference
- 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 (unknown symbol).
- 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.
- 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.
- 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
- 404
not_foundSymbol not found.
{ "error": "not_found", "message": "Symbol not found."} - 400
invalid_parameterMalformed start, end, limit, or cursor.
{ "error": "invalid_parameter", "message": "start must be YYYY-MM-DD or RFC3339."} - 400
interval_unsupported_for_marketInterval outside the canonical 1m | 5m | 15m | 30m | 1h | 1d | 1w | 1mo enum.
{ "error": "interval_unsupported_for_market", "message": "interval must be one of: 1m, 5m, 15m, 30m, 1h, 1d, 1w, 1mo."} - 422
data_unavailableStart 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"} - 406
gzip_requiredHeavy endpoint called without Accept-Encoding: gzip.
{ "error": "gzip_required" } - 502
upstream_errorOur aggregation pipeline returned an error response.
{ "error": "upstream_error" } - 502
malformed_upstreamOur aggregation pipeline returned an unparseable payload.
{ "error": "malformed_upstream" } - 503
upstream_rate_limitedOur aggregation pipeline hit its rate limit. Try again shortly.
{ "error": "upstream_rate_limited" } - 503
historical_unavailableCrypto historical data is not configured on this deployment.
{ "error": "historical_unavailable" }