One Call, Five Answers: How Many Candles Each Exchange API Actually Returns
Every trading-data script eventually grows the same loop: request candles, remember the last timestamp, ask for the next page. The loop breaks the first time it touches a second exchange, because "how many candles come back in one call" is not one number. On the morning of 2026-10-20 (02:00–02:10 UTC) I asked five exchange APIs the same question with the same kind of request — hourly candles on BTC — and got five different answers. One venue's documentation and its own endpoint even disagree by exactly one candle.
Quick disclosures: AI-assisted content: this article was researched and drafted with AI assistance, and every number below was re-checked against the official endpoints and documentation cited at the end. #ad — affiliate disclosure: this post carries no affiliate or referral links today; if future posts in this series do, they will be labelled right where they appear. This article is not financial advice — it is a documentation study of API behaviour.
The five answers, up front
| Venue | Docs say | Wire says | Docs' default size |
|---|---|---|---|
| Binance | Max 1000, default 500 | 1000 bars (asked 1500); 500 by default | 500 |
| Bybit | [1, 1000], default 200 | 1000 bars (asked 1001); 200 by default | 200 |
| OKX | Max 300, default 100 | 300 bars (asked 500); 100 by default | 100 |
| Kraken | "Maximum 720 candles per call" | 721 rows, no limit parameter exists | — |
| KuCoin | no text documentation found | 100 bars | — |
Four different caps (100 / 300 / 720 / 1000) and three different defaults (100 / 200 / 500) for the same everyday request. Same asset, same interval, same minute, five rulebooks.
What I actually ran
All five calls are public, key-free, and repeatable:
-
Binance
GET /api/v3/klineson BTCUSDT, interval 1h,limit=1500→ exactly 1,000 rows. Same call with nolimit→ 500 rows. -
Bybit
GET /v5/market/kline(category spot, BTCUSDT, interval 60),limit=1001→ exactly 1,000 rows. Nolimit→ 200 rows. -
OKX
GET /api/v5/market/candleson BTC-USDT, bar 1H,limit=500→ exactly 300 rows. Nolimit→ 100 rows. -
Kraken
GET /0/public/OHLCon XBTUSD, interval 60 → 721 rows. The endpoint has no limit parameter at all. -
KuCoin
GET /api/v1/market/candles(BTC-USDT, type 1hour) → 100 rows.
Over caps are not errors — Binance and Bybit did not complain about limit=1500 or limit=1001. They silently returned their maximum. A client that asks for 5,000 and trusts the request will quietly believe it fetched 5,000.
The documentation layer, quoted
A number on the wire is nice; a number the venue actually commits to is better. Same morning, official text surfaces:
- Binance spot REST spec, klines section: "limit | INT | NO | Default: 500; Maximum: 1000."
- Bybit kline page: "Limit for data size per page. [1, 1000]. Default: 200."
- OKX REST docs, candles section: "Number of results per request. The maximum is 300. The default is 100."
- Kraken historical-data guide: "Maximum 720 candles per call."
- KuCoin: the docs site is a JavaScript application; I found no text-rendered page stating the candle depth. Reported as observed — the 100-row figure above is measurement, not a quote.
So four of five venues have their number in writing, and the live wire agrees with every written number. Almost.
The one-candle disagreement
Kraken's guide says 720. The endpoint returned 721 rows.
The arithmetic makes the disagreement visible: the first row opens at 2026-09-20 02:00 UTC and the last row is stamped 2026-10-20 02:00 UTC — exactly 2,592,000 seconds apart, which is precisely 720 hour-wide slots. Seven hundred twenty-one rows spanning seven hundred twenty slots. The most plausible reading is that the final row is the bar still forming at request time (I called shortly after 02:00 UTC, and a closed candle's close price is simply the last traded price on most venues, so a live bar looks identical to a finished one in the response). Kraken's own pagination hint — the last field in the response — pointed at 01:00, i.e. the second-to-last row, as the resume marker, which quietly treats the final row as not-yet-final.
Kraken's documentation does not adjudicate this, so I will not either. The point for builders: a documented cap and the row count are two different measurements, and one candle of drift per page is exactly the kind of off-by-one that turns into a silent gap — or a duplicated bar — after two hundred pages.
A quiet cross-check worth copying
Binance and Bybit disagree on defaults (500 vs 200), but both cap at 1000 — and on the same minute of capture, both handed me a window whose oldest bar was 2026-09-08 11:00 UTC. Two independent venues, one thousand hours back from the same moment, agreeing to the hour. When you build a cross-venue pipeline, checks like this — where two sources should agree and do — cost nothing and catch whole classes of silent truncation.
What a portable fetcher must carry
- A per-venue page-size constant. Read each venue's own limit line; never port one venue's constant to another. 100-to-1000 across five mainstream venues.
-
Never omit
limit. The three documented defaults differ 5× (100/200/500), and KuCoin offers no documented default at all. - Row order is also per-venue. In my same-minute captures, Binance returned oldest bar first (row 0 was the oldest), while Bybit returned newest first (the oldest sat at the end of the array). Same pair, same interval, opposite arrays.
- Decide what to do with live bars. Kraken hands you the forming candle; whether your backtest wants it is a policy decision, not a default.
- Treat over-cap requests as truncation signals. Asking for 1500 and receiving 1000 is correct behaviour — but only if your code compares asked versus received instead of trusting the request.
None of this is exotic. It is five ordinary rulebooks, each written by one venue, each silently binding the moment your script touches that venue.
Numbers move — verify official sources
Every figure here is a snapshot from 2026-10-20 02:00–02:10 UTC, and any venue can change its limits without announcing it. Re-run the calls yourself: api.binance.com GET /api/v3/klines; api.bybit.com GET /v5/market/kline; okx.com GET /api/v5/market/candles; api.kraken.com GET /0/public/OHLC; api.kucoin.com GET /api/v1/market/candles. For the written rules: the klines section of Binance's spot REST spec on GitHub, the kline page on bybit-exchange.github.io/docs/v5, the candles section of okx.com/docs-v5, and the historical-data guide on docs.kraken.com. Verify official sources before you hard-code any number into your own code.
Not financial advice. This post reports on API documentation and observed endpoint behaviour only; it recommends no exchange, no strategy, and no trade.
AI-assisted content disclosure: researched and drafted with AI assistance on 2026-10-20 against the cited official sources. #ad: no affiliate or referral links are present in this post.
Top comments (0)