<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Calix</title>
    <description>The latest articles on DEV Community by Calix (@calixph).</description>
    <link>https://dev.to/calixph</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4202056%2F9b93a5b6-2a47-4a87-9b24-8ae625913e58.png</url>
      <title>DEV Community: Calix</title>
      <link>https://dev.to/calixph</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/calixph"/>
    <language>en</language>
    <item>
      <title>How far back each exchange's API actually lets you go (11 exchanges compared)</title>
      <dc:creator>Calix</dc:creator>
      <pubDate>Sun, 25 Oct 2026 07:40:00 +0000</pubDate>
      <link>https://dev.to/calixph/how-far-back-each-exchanges-api-actually-lets-you-go-11-exchanges-compared-1nj9</link>
      <guid>https://dev.to/calixph/how-far-back-each-exchanges-api-actually-lets-you-go-11-exchanges-compared-1nj9</guid>
      <description>&lt;p&gt;I build a read-only crypto portfolio tracker, which means I spend a lot of time asking exchange APIs for old trades and finding out how little they will give me. We integrate 11 exchanges, and I keep one manifest of how far back each one will actually serve history. This post is that manifest, with the endpoints behind it.&lt;/p&gt;

&lt;p&gt;The short version: two different limits get confused, and only one of them is a problem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Window caps versus retention walls
&lt;/h2&gt;

&lt;p&gt;A &lt;strong&gt;window cap&lt;/strong&gt; limits how much time a single request may span. HTX's match results accept at most a 48 hour span. Bybit's execution list works in 7 day windows. Gate.io allows 30 days, Bitget 90, Upbit 7. These are annoying, but they are not limits on your history. You loop backwards in chunks and eventually reach the start of the account. If your tool says "only 7 days available" because of a window cap, the tool is lazy, not the exchange.&lt;/p&gt;

&lt;p&gt;A &lt;strong&gt;retention wall&lt;/strong&gt; means the data no longer exists behind the API. Nothing you write can recover it. OKX serves about 90 days of fills. MEXC serves about a month. Bitget about 90 days. HTX about 120. A wall is a fact about the exchange, and it decides how much of your cost basis can be rebuilt from an API key.&lt;/p&gt;

&lt;p&gt;Conflating the two would put a warning on six venues about caps we walk through without trouble, so the manifest deliberately lists only walls. Splitting them is the most useful thing in it.&lt;/p&gt;

&lt;p&gt;One more distinction that bit me: the same venue can have a wall on one surface and none on another. OKX serves its funding ledger (deposits, withdrawals, fiat, rewards) back to February 2021, while its savings interest is a rolling 30 days. A year-old month shows real deposits next to a confident zero of earnings.&lt;/p&gt;

&lt;h2&gt;
  
  
  The table
&lt;/h2&gt;

&lt;p&gt;Numbers come from the manifest in our repo (&lt;code&gt;packages/ui/src/history-limits.ts&lt;/code&gt;), which a test keeps in sync with the adapter registry, so a new venue cannot ship without declaring its limits. "Full" means no retention wall: the API reaches account opening. "About" is on purpose; exchanges do not promise these figures, and I would rather round than imply a contract.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Exchange&lt;/th&gt;
&lt;th&gt;Trade history&lt;/th&gt;
&lt;th&gt;Deposits / withdrawals&lt;/th&gt;
&lt;th&gt;Endpoints and quirks&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Binance&lt;/td&gt;
&lt;td&gt;Full&lt;/td&gt;
&lt;td&gt;Full&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;/api/v3/myTrades&lt;/code&gt; requires a symbol, so there is no account-wide trade feed: you have to know which pairs to ask about. A coin bought and fully sold, with no deposit or withdrawal pointing at it, is named only by the daily account snapshot (&lt;code&gt;/sapi/v1/accountSnapshot&lt;/code&gt;), which reaches about 30 days back. Transfers (&lt;code&gt;/sapi/v1/capital/deposit/hisrec&lt;/code&gt;, &lt;code&gt;withdraw/history&lt;/code&gt;) walk in 90 day windows back to account opening.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OKX&lt;/td&gt;
&lt;td&gt;About 90 days&lt;/td&gt;
&lt;td&gt;Full (funding bills back to Feb 2021)&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;/api/v5/trade/fills-history&lt;/code&gt; serves roughly 3 months. A deeper &lt;code&gt;/api/v5/trade/fills-archive&lt;/code&gt; exists but needs a separately requested download, and returned 404 for the account shape I tested. Savings interest on &lt;code&gt;/api/v5/finance/savings/lending-history&lt;/code&gt; is a rolling 30 days.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;KuCoin&lt;/td&gt;
&lt;td&gt;Full&lt;/td&gt;
&lt;td&gt;Full&lt;/td&gt;
&lt;td&gt;Per-fill data (&lt;code&gt;/api/v1/fills&lt;/code&gt;) is only 7 days, but done orders (&lt;code&gt;/api/v1/orders&lt;/code&gt;, status done) reach account opening with a 7 day range cap per query, so trades are reconstructed from orders. &lt;code&gt;/api/v1/accounts/ledgers&lt;/code&gt; is capped at 1 year with a 24 hour query window.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Gate.io&lt;/td&gt;
&lt;td&gt;Full&lt;/td&gt;
&lt;td&gt;Full&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;/spot/my_trades&lt;/code&gt; and &lt;code&gt;/wallet/deposits&lt;/code&gt; use a 30 day request window, walked back in full.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bybit&lt;/td&gt;
&lt;td&gt;About 2 years&lt;/td&gt;
&lt;td&gt;Full&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;/v5/execution/list&lt;/code&gt; retains roughly two years of executions and is queried in 7 day windows. Older fills come back empty rather than as an error.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Coinbase&lt;/td&gt;
&lt;td&gt;Full&lt;/td&gt;
&lt;td&gt;Full&lt;/td&gt;
&lt;td&gt;Advanced Trade fills (&lt;code&gt;/api/v3/brokerage/orders/historical/fills&lt;/code&gt;) are cursor paginated with no retention floor. Simple-mode buys and sells are not in that feed at all; they live on the legacy v2 &lt;code&gt;/v2/accounts/{id}/buys&lt;/code&gt; and &lt;code&gt;/sells&lt;/code&gt; endpoints, which Coinbase has deprecated but still serves, with the real fiat amount.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Kraken&lt;/td&gt;
&lt;td&gt;Full&lt;/td&gt;
&lt;td&gt;Full&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;/0/private/TradesHistory&lt;/code&gt; is account-wide, and &lt;code&gt;/0/private/Ledgers&lt;/code&gt; carries the movements. Both reach the start.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bitget&lt;/td&gt;
&lt;td&gt;About 90 days&lt;/td&gt;
&lt;td&gt;Full&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;/api/v2/spot/trade/fills&lt;/code&gt; has a 90 day wall. Deposit and withdrawal records (&lt;code&gt;/api/v2/spot/wallet/deposit-records&lt;/code&gt;) walk 90 day windows back to the 2018 launch.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Upbit&lt;/td&gt;
&lt;td&gt;Full&lt;/td&gt;
&lt;td&gt;Full&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;/v1/orders/closed&lt;/code&gt; is queryable 7 days at a time; you walk back about 11 years. Markets are KRW based.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;MEXC&lt;/td&gt;
&lt;td&gt;About a month (31 days)&lt;/td&gt;
&lt;td&gt;About 90 days&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;/api/v3/myTrades&lt;/code&gt; plus 7 day windows inside a hard retention limit. Older data is only available as a manual export from the website.&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;HTX&lt;/td&gt;
&lt;td&gt;About 120 days&lt;/td&gt;
&lt;td&gt;About a year&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;/v1/order/matchresults&lt;/code&gt; caps each query at 48 hours and returns at most 500 rows per page, so a busy window has to be split. Transfers come from &lt;code&gt;/v1/query/deposit-withdraw&lt;/code&gt;.&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Five of the eleven have a trade wall: OKX, Bybit, Bitget, MEXC and HTX. MEXC and HTX also wall transfers. For KuCoin the honest summary is "full history", even though one of its endpoints is walled at 7 days; I document the outcome, not the endpoint.&lt;/p&gt;

&lt;p&gt;A note on sourcing. The OKX figures were verified against a real account in September 2026, and the KuCoin ones were re-checked against KuCoin's own docs in August 2026. The rest are the limits recorded in each adapter from earlier probing, and I did not re-probe all of them for this post. Re-probe before you build on any of it. Exchanges change these quietly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why this matters at year end
&lt;/h2&gt;

&lt;p&gt;This is the part that made me write the post. Walls are measured from today, not from the start of the year. If you read the API in the last week of October 2026, the reach is roughly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;OKX and Bitget, 90 days: back to late July&lt;/li&gt;
&lt;li&gt;HTX, 120 days: back to late June&lt;/li&gt;
&lt;li&gt;MEXC, about a month: back to late September&lt;/li&gt;
&lt;li&gt;Bybit, about 2 years: back to late October 2024&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By 31 December the same walls reach back only to about 2 October (OKX, Bitget), 2 September (HTX) and 30 November (MEXC). Anything you traded earlier in 2026 on those venues will be gone from the API by then. It is not hidden, it is deleted from the API's point of view. Bybit's two year wall means 2024 trades are the ones leaving now.&lt;/p&gt;

&lt;p&gt;The consequence is not abstract. On one real OKX account, 90 days of fills against an account funded since March 2024 left about 27 months of buys unrecorded. It surfaced as "you hold 87 LINK the ledger has never seen". A tool built on such an API will quietly compute a cost basis that is wrong forever, and the symptom does not tell you whose fault it is.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to do about it now
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Export CSVs from each exchange's web UI before the wall moves.&lt;/strong&gt; Trade history and deposit/withdrawal history, the longest range each site allows. For MEXC, this is the only route to anything older than the API serves. Do the venues with the shortest walls first: MEXC, then OKX, Bitget, HTX.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Do it per account and per product.&lt;/strong&gt; Spot, funding, earn and derivatives are separate ledgers. OKX derivatives bills, for instance, are 7 days live and 3 months archived.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Store the files somewhere you control.&lt;/strong&gt; An export is the only copy you will ever have of the data the API has already dropped.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;If you build against these APIs, record the first sync date.&lt;/strong&gt; A history that starts at your first successful sync is a different claim from a history that starts at account opening, and your users will want to know which one they have.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Do not let a lazy walk truncate you.&lt;/strong&gt; Never stop a backward window walk after N empty windows. Real accounts have long gaps, and you will silently lose everything older.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;None of this is tax advice. It is just arithmetic about which dates are still reachable.&lt;/p&gt;

&lt;p&gt;If you only want to see how an allocation would have held up, rather than rebuild old trades, the free in-browser stress test needs none of this history: &lt;a href="https://whereitgoes.money/stress-test?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=history-limits" rel="noopener noreferrer"&gt;whereitgoes.money/stress-test&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The per-exchange breakdown I maintain for users is on &lt;a href="https://whereitgoes.money/exchanges?utm_source=devto&amp;amp;utm_medium=article&amp;amp;utm_campaign=history-limits" rel="noopener noreferrer"&gt;whereitgoes.money/exchanges&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I build WhereItGoes; this article was drafted with AI assistance and checked against the code.&lt;/p&gt;

</description>
      <category>crypto</category>
      <category>api</category>
      <category>fintech</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
