Bitcoin Reconciliation API for Exchanges and Custodians
On 10 September 2026 we reconciled a five-address cold-storage set two independent ways at block 966,451, from address totals and from 1,677 individual transactions, and the two answers matched to the satoshi. That match is the test a reconciliation data layer has to pass, and commercial balance feeds cannot take it: they round to two decimal places and refresh hourly on every plan. We cover the silent-zero trap in historical balance endpoints, why you reconcile at a block height and never a timestamp, and the five questions to ask a Bitcoin data vendor before you sign.
By the BitcoinDatabase team
September 2026 · 8 min read
BTC
Balance trail
informational on-chain data · not financial advice
The short answer
A Bitcoin reconciliation API has to give you two things that most on-chain data products do not: satoshi precision and a fixed block height to reconcile at. Commercial balance feeds round to two decimal places and refresh hourly, which is fine for a chart and useless for tying out a ledger. On 10 September 2026 we reconciled a five-address cold-storage set two independent ways at block 966,451, from address totals and from 1,677 individual transactions, and the two answers matched to the satoshi. That match is the test your data layer has to pass.
If you run finance or treasury ops at an exchange, a custodian, a broker or a fund that holds bitcoin, reconciliation is the job that has to be right every single month. Your internal ledger says a wallet holds a number. The chain says it holds a number. When those disagree, you need to know whether it is a missing deposit, an unrecorded fee, a rounding artifact, or a real problem, and you need to know before the auditor asks.
Most of the pain in that process is not accounting. It is the data layer underneath, and specifically four properties of it that vendors rarely lead with. We measured all four against live endpoints on 10 September 2026, and the numbers below are reproducible.
What does a Bitcoin reconciliation API actually need to do?
Four things. Return a balance at an exact block height, not "now". Return it in satoshis rather than a rounded decimal. Return every transaction that touched an address in a window, with no silent paging cutoffs. And let you compute the same figure two different ways so the two can be compared. The last one is the only real proof you have that your pipeline works, and almost nobody designs for it.
Notice what is missing from that list: labels, risk scores, dashboards, alerts. Those are useful products and they are not what a reconciliation needs. A reconciliation needs arithmetic you can show your work on.
Why can you not reconcile against a commercial exchange balance feed?
Because of precision and freshness, and both are documented rather than hidden. We read the CoinGlass API documentation on 10 September 2026. Its Exchange Balance List and Exchange Assets endpoints both state a cache and update frequency of every one hour for all API plans, Enterprise included, and the documented response carries balances at two decimal places. Paying more does not buy a fresher number or another decimal.
Two decimal places on bitcoin is 0.01 BTC of granularity. At recent prices that is roughly 875 dollars of unresolvable difference per address before your reconciliation even starts, and across a wallet set it compounds. The whole point of a tie-out is that the residual should be zero or explainable, and a feed that cannot represent a zero cannot tell you that you have one.
| Property | Typical balance feed | What a reconciliation needs |
|---|---|---|
| Precision | 2 decimal places | 8 decimal places (satoshi) |
| Freshness | Cached hourly | Per block |
| Cutoff control | Latest value only | Pinned to a block height |
| Transaction detail | Aggregate totals and deltas | Every input and output |
| Independent recompute | Not possible | Required |
How do you reconcile a Bitcoin balance two independent ways?
You compute the same delta from two different sources and check that they agree. Source one is the balance itself: read the address total at the start height and at the end height and subtract. Source two is the flow: pull every transaction that touched the address in that window, sum the value it received, sum the value it spent, and take the difference. If your indexing, your paging and your address matching are all correct, those two numbers are identical. If they are not, you have a bug, and you have it before it reaches a report.
Here is a live example. We track a set of five widely reported exchange cold addresses plus the off-list hot wallet that funds them, and we have now read them nine times since 16 August 2026. On 10 September 2026, at block 966,451, the hot wallet held 13,598.75190037 BTC. On 8 September, at block 966,164, it held 11,353.48334032 BTC. The balance delta is 2,245.26856005 BTC.
Separately, we paged every confirmed transaction that touched that address across blocks 966,165 to 966,451: 1,677 transactions, 68 sequential pages. Summing the outputs paying into the address gave 30,553.21495369 BTC received. Summing the prevouts it spent gave 28,307.94639364 BTC sent. Net: 2,245.26856005 BTC.
The two figures match exactly, to the satoshi. That is a free correctness check on the entire pipeline, and it costs one extra query. Take it every time. The gross number is worth noting too: 58,861.16 BTC moved through that one address in about two days, which is the scale of activity a monthly close has to account for.
Why does the tracked total not move when the wallet clearly does?
Because activity and position are different measurements, and conflating them is the most common reconciliation error we see. Over those same 287 blocks, while 58,861.16 BTC of gross flow passed through the funding wallet, the five tracked cold addresses held 69,460,003,430,648 satoshis, which is byte-for-byte the figure we recorded on 4, 6 and 8 September. Four consecutive readings, identical to the satoshi, across thirteen days.
Sixty thousand bitcoin moved and the reserve figure drew a flat line, and the flat line was completely accurate. Both numbers are correct because they answer different questions. If your ledger tracks position and your ops team watches flow, you will spend a lot of time arguing about which one is broken when neither is. The full series and the method are on our Bitcoin exchange reserves page, and the flow side is covered on the Bitcoin exchange flow API page.
Should you reconcile at a timestamp or a block height?
A block height, always. Timestamps look friendlier to a finance team and they will corrupt your cutoff quietly. Bitcoin block timestamps are not monotonic: a miner may set a timestamp earlier than the previous block within consensus limits. When we measured spent-output lifespans across a single block we found 15 inputs with a negative lifespan, meaning the spending block carried an earlier timestamp than the block that created the coin. If your period-end cutoff is "everything before 23:59:59 UTC on the last day of the month", a handful of transactions will land on the wrong side of it and nothing will warn you.
A block height is unambiguous, verifiable by anyone, and reproducible a year later. Pick the last block confirmed before your cutoff, record its height and hash in the working paper, and reconcile to that. Everyone who checks your work gets the same answer.
What are the traps when fetching a historical Bitcoin balance?
Three, and two of them fail silently, which is worse than failing loudly.
The first is that public explorers mostly do not support a historical balance at all. We tested this directly. Passing a height parameter to a Blockstream Esplora address call returns a byte-identical response to the call without it: the parameter is simply ignored, so you get the current balance while believing you asked for a past one. BlockCypher's before parameter is worse. Asking for an address state before block 300,000 returned a response in which every numeric field was zero. Not an error, not an empty result, just zeros that will flow straight into a spreadsheet and reconcile to nothing.
The second is paging. Address history comes back 25 transactions at a time on the common public APIs. The funding wallet in our example carries 2,324,375 transactions in total; a two-day slice of it took 68 sequential requests. A naive loop that walks an entire busy address from the tip will take hours and will usually be abandoned halfway, leaving a partial window that looks complete.
The third is the mempool. When we took the reading on 10 September the hot wallet had four unconfirmed transactions pending, netting about 18.92 BTC outbound. Depending on which field of the API response you read, those are either included or not. Decide once whether your reconciliation is confirmed-only, write it down, and make sure the code matches the policy. Confirmed-only is the right default for anything an auditor will look at.
What should you ask a Bitcoin data vendor before you buy?
Five questions, in this order. Can I request a balance at a specific block height, and will you return an error rather than a stale or zeroed value if you cannot? What precision do you return, in satoshis or decimals? Can I retrieve the complete transaction history of a high-volume address without paging limits that make it impractical? Do you expose the UTXO set with a spent flag, or only balances? And can I reproduce any figure you publish from the rows you hand me?
That last question is the one that separates a data source from a dashboard. If the vendor cannot show its work, you cannot show yours, and reconciliation is entirely a business of showing your work. Our Bitcoin UTXO data page covers the response fields, and the point-in-time mechanics are worked through in our guide to checking a Bitcoin address balance on a specific date. If you are weighing a commercial balance feed against the raw chain, we measured one of the better known ones on our CoinGlass alternative page, including its tiers and its documented precision.
Where the fiat leg fits
One practical note, because the crypto side is only half of a reconciliation. The USD leg still arrives from a banking partner or a payment processor, usually as a statement rather than a feed, and a controller can lose as much time keying that in as on the chain side. Pulling those documents into a spreadsheet first, by converting the PDF statements into clean CSV rows, is what makes the two sides line up in the same workbook instead of on two different screens.
Once both legs are in the same format, the on-chain side stops being the hard part. BitcoinDatabase exposes blocks, transactions, inputs, outputs and the UTXO set at satoshi precision over REST, with address history back to 2009, and over SQL on the indexed chain, which grows with every new block, pinned to whatever block height in that range you name. Start with the address balance history API, or query the chain directly from the API documentation.
Measurements in this article were taken on 10 September 2026 at block 966,451 against live public endpoints, and cross-checked against two independent explorers. Vendor documentation and pricing change; re-run the checks before relying on them. This is informational on-chain data and engineering guidance, not accounting, audit, tax, legal or investment advice.
Query the Bitcoin blockchain yourself
Pull balances, UTXOs, transactions, on-chain metrics and fund flows from the Bitcoin blockchain by REST API, SQL and dashboards. Address history since 2009, new blocks within seconds, no node to run.