How to Check a Bitcoin Address Balance on a Specific Date
The blockchain stores no balances, only unspent outputs, and explorers report the present tense. We tested four public endpoints on one address: two ignored a height parameter, one returned zeroes, one is gone. What actually works, the arithmetic behind a point-in-time balance, and the five errors that quietly corrupt one.
By the BitcoinDatabase team
August 2026 · 9 min read
Hit Run to query the fully-indexed Bitcoin blockchain.
BTC
30-day trend
informational on-chain data · not financial advice
The short answer
To check a Bitcoin address balance on a specific date, convert that date to a block height and sum every output the address received in blocks up to that height, minus every output it had already spent. Block explorers will not do this for you: they report current balances only, and adding a height parameter to their API request changes nothing. The practical routes are computing it yourself from the transaction list, replaying the chain on your own node, or querying an indexed copy of the blockchain that stores every movement with its confirming block.
This question comes up in three places, always with money attached to the answer. A tax preparer needs to know what a wallet held on December 31. An auditor is testing a reserve claim made on a particular morning. A fund is rebuilding a year of holdings for a report and cannot find a single tool that will simply state the balance on a date.
All three discover the same thing within about ten minutes: the blockchain does not store balances at all, and the tools built on top of it are designed almost entirely around the present tense.
Why a block explorer only shows you the current balance
A Bitcoin balance is not a field. Nowhere in the chain is there a record saying an address holds 12.4 BTC. What exists is a set of unspent transaction outputs, and a balance is what you get when you add up the ones that currently point at an address. Bitcoin Core keeps exactly one copy of that set, the current one, because that is all consensus requires.
So explorers report the present. To show how completely, we ran the same address against three public endpoints on 4 August 2026. The address is the genesis address, 1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa, chosen because it is the most-inspected address in Bitcoin and anyone can repeat these requests.
| Public endpoint | What it returned | Point in time? |
|---|---|---|
| mempool.space /api/address | Current aggregates only: funded 5,732,830,722 sats, spent 0, 64,897 transactions | No. Response identical with and without a height parameter |
| blockstream.info /api/address | Byte-identical to the above, same Esplora shape | No. Height parameter silently ignored |
| BlockCypher /addrs/{addr}/balance | Current totals: 10,733,865,456 sats received, 64,913 transactions | No. With before=300000 and before=800000 every field came back 0 |
| blockchain.info /charts/balance | A 302 redirect, no data | Gone. Still the top answer in old forum threads |
Two details in that table are worth pausing on. The first is that BlockCypher's before parameter is meant for paging through an address's transactions, not for restating its balance, so returning zeroes is not strictly a bug. It is still a trap, because the request looks like it worked. A script that reads final_balance from that response records a balance of zero for an address that held tens of BTC at both heights, and nothing in the response says otherwise. Silent zeroes are more dangerous than errors.
The second is the last row. Search this problem and you will land in forum threads pointing at a blockchain.info balance chart URL that took an address and drew its balance over time. That was the right answer once. It now returns a redirect rather than data, which is why the question keeps getting asked and never quite stays answered.
How do I find a Bitcoin address balance on a specific date?
Start by converting the date into a block height, because a date is ambiguous and a height is not. Blocks arrive roughly every ten minutes, and "December 31" means different boundaries in New York than in Singapore. Pick the last block confirmed before midnight in whichever time zone your reporting uses, write that height down, and use it as the definition. Anyone checking your work later needs that number, not your date.
From there you have four routes.
| Method | Effort | Scales to | Best for |
|---|---|---|---|
| Explorer transaction list plus manual math | Minutes per address, by hand | One quiet address | A single personal wallet with a dozen transactions |
| Script over an explorer API | An afternoon, plus rate limits | Tens of addresses | A one-off analysis you will not repeat |
| Your own node with a transaction index | Days of sync, then build the replay yourself | Whatever you engineer | Teams that need full custody of the data |
| Indexed chain by API or SQL | One request | Whole address lists at once | Tax, audit, reserves, anything repeated |
The first two are fine for one address and collapse quickly. The third is real work: a node stores the raw blocks but keeps only the current UTXO set, so having one does not hand you historical balances. You still write the replay logic and the storage behind it. The fourth is the same computation performed once, ahead of time, for every address in the chain, which is what a Bitcoin address balance history API is.
How do I get a Bitcoin balance at a specific block height?
The arithmetic is short enough to state in one sentence: take every output paid to the address in blocks at or below your target height, subtract every one of those outputs that had already been spent by that same height, and the remainder is the balance. Everything hard about this is bookkeeping, not math.
Doing it from an explorer means pulling the address's full transaction list, filtering to transactions confirmed at or below the height, and tracking each output through to its spend. Busy addresses turn that into a paging exercise across thousands of transactions, and you have to watch the spend side carefully. An output received in 2013 and spent in 2019 counts toward a balance measured in 2015 and not toward one measured in 2020. Missing that is the single most common error in hand-rolled balance history, and it always overstates the older figure.
On an indexed dataset the same job is a filter, because every input and output is already stored with the block that confirmed it. In SQL against the indexed chain it is one statement: sum the outputs to the address where the confirming height is at or below your target, minus the inputs spending them under the same condition. The public BigQuery Bitcoin dataset can express this too, with the caveat that you are billed for the terabytes each run scans, and a full-history scan is not a cheap query to iterate on.
Why do two explorers report different balances for the same address?
Because a balance is an indexer's output, not a protocol field, and indexers make different choices. Our own requests on 4 August 2026 show it plainly. For the genesis address, the Esplora-based endpoints reported 5,732,830,722 sats funded across 64,897 transactions. BlockCypher reported 10,733,865,456 sats received across 64,913. Same address, same afternoon, a gap of roughly 50.01 BTC and 16 transactions.
Most of that gap has a well-documented cause. The genesis block's 50 BTC coinbase reward is never added to the UTXO set by Bitcoin Core, which special-cases that block during validation, so the coins are permanently unspendable and invisible to anything reading Core's index. Explorers built on that index leave the 50 BTC out. Others add it back because a user looking at the genesis address expects to see it. Neither is wrong, and both are defensible, but they answer slightly different questions.
The lesson generalizes past this one quirk. If two providers can differ on the most examined address in Bitcoin, they can differ on yours, and a historical balance is only comparable to another historical balance when both were produced under a stated convention. Record which source you used, which height you pinned, and how unconfirmed activity was handled. That is the same period-end discipline that applies when you tie the bank and payment-processor side of the books together, and it exists for the same reason: two systems will disagree, and the write-up is what makes the disagreement resolvable.
What is the difference between transaction history and balance history?
Transaction history is the list of movements in and out of an address. Balance history is the running total those movements produce over time. Explorers give you the first. Accounting, tax and audit work needs the second, and turning one into the other is where the effort goes.
The distinction matters more than it sounds. A single point-in-time balance answers "what did this hold on December 31" but supports nothing. A balance timeline, one row per day or per movement with the transaction that caused each change, is what lets a reviewer see the year, spot the transfers, and agree with the ending figure. When someone asks for a historical balance, they usually want the line and not the dot, even if they asked for the dot. The same applies across a set: pinning a whole address list to one height is how reserve snapshots and treasury year-ends get produced, and it is the natural extension of checking a list of addresses in one pass.
Five things that quietly corrupt a historical balance
Change addresses. Most wallets send change to a fresh address you never wrote down. Reconstruct a wallet's history from the addresses you know about and you will find balances vanishing at the exact moment a spend occurred. If the wallet is HD, work from the extended public key rather than an address list.
The xpub gap limit. Scanners stop after roughly 20 consecutive unused derived addresses. Funds sitting past a gap are simply not seen, and the omission is silent. Widen the limit when a wallet has been used irregularly.
Reorgs near your boundary. A balance pinned to a height one or two blocks deep is not final. For reporting, choose a height with meaningful confirmations behind it and note the choice.
Unconfirmed activity. Current-balance tools often blend mempool transactions into the number. A historical balance should be confirmed-only, since anything unconfirmed at your boundary either landed in a later block or never landed at all.
The USD conversion. A holding of 3.2 BTC on a past date has no single dollar value until you choose a price source and a time of day. Whatever you pick, pin it to the same block boundary as the balance and say so in the file, because the conversion is where two otherwise identical reports diverge. That is also why cost basis work keeps the price on the same timeline as the movements.
What auditors and tax preparers actually ask for
In practice the request is rarely a single number. It is a set of addresses, a period, and a demand that the result be reproducible by someone who does not trust you. That means three things travel together: the balance, the block height it was measured at, and the movements inside the period that connect the opening figure to the closing one.
Give an auditor an address and a height and they can rerun the query themselves. Give them a screenshot of a balance and they have your word, which is worth nothing in a workpaper. This is the whole reason to pin balances to heights instead of dates, and it is why full-history chain data and a plain address lookup with first-seen and last-activity dates tend to be requested together: one establishes the number, the other establishes the story around it.
Can a block explorer show historical balances?
Almost none can, and the ones that once did have mostly retired the feature. The transaction list is public, so the raw material is there, but the balance on a past date is a computation the explorer is not performing and its API has no parameter to request. If you need that figure once, do the arithmetic by hand. If you need it for a portfolio, a period, or an audit file, read it from a chain that is already indexed by confirming block, where a balance at height 500,000 costs exactly what a balance at the tip costs.
This is informational on-chain data, not tax, accounting, financial or legal advice. Confirm any figure that will appear in a filing with the professional signing it.
Query the Bitcoin blockchain yourself
Pull balances, UTXOs, transactions, on-chain metrics and fund flows from the fully indexed Bitcoin blockchain by REST API, SQL and dashboards. Indexed since 2009, new blocks within seconds, no node to run.