BitcoinDatabase.com
All posts
Guides

Reading a Bitcoin Address: Balance, UTXOs and Transaction Flows from First Principles

Bitcoin address lookup from first principles: how a balance is really the sum of unspent outputs, how to read UTXOs, inputs and outputs, and how to trace transaction flows with a REST API or SQL.

By the BitcoinDatabase team

June 2026 · 9 min read

Bitcoin address lookup: what a balance really is

A Bitcoin address lookup looks like the simplest thing in the world: type an address, see a balance. Underneath, though, Bitcoin has no concept of an account balance at all. An address does not "hold" a number the way a bank account does. Its balance is something you compute, the sum of the unspent outputs that are locked to it. Once that clicks, the rest of address analysis, UTXOs, inputs, outputs and transaction flows, becomes much easier to read. This is an informational walkthrough of how that data fits together; it is not financial advice.

From address to balance

An address is, in essence, a short encoding of a locking condition, the script that says how a coin may be spent. There are several formats you will encounter: legacy addresses beginning with 1, pay-to-script-hash addresses beginning with 3, and native SegWit (bech32) addresses beginning with bc1. They are different ways to express "whoever can satisfy this script may spend these coins."

To find a balance, you gather every output ever sent to that address, then keep only the ones that have not yet been spent. Sum their amounts and you have the balance. A REST call hides this work behind a single field.

GET https://api.bitcoindatabase.com/v1/address/bc1q...xyz

{
  "address": "bc1q...xyz",
  "balance_btc": 3.92140000,
  "received_btc": 41.10000000,
  "sent_btc": 37.17860000,
  "utxo_count": 4,
  "tx_count": 96
}

Notice that balance equals received minus sent. In SQL the same idea is a sum over unspent outputs:

SELECT sum(value_btc) AS balance_btc
FROM outputs
WHERE address = 'bc1q...xyz'
  AND spent = false;

UTXOs: the coins themselves

Each unspent output, a UTXO, is a discrete coin with an amount, locked to an address. An address with a balance of 3.9214 BTC and four UTXOs is holding four separate coins that happen to add up to that figure. This matters when you build anything that spends: a wallet cannot send "part of a UTXO." It must consume whole outputs as inputs and return any difference to itself as a change output.

GET https://api.bitcoindatabase.com/v1/address/bc1q...xyz/utxos

[
  { "txid": "9f2c...", "vout": 0, "value_btc": 2.50000000 },
  { "txid": "a4b1...", "vout": 1, "value_btc": 1.00000000 },
  { "txid": "c7d8...", "vout": 0, "value_btc": 0.42140000 }
]

Inputs and outputs: reading a transaction

A Bitcoin transaction is a list of inputs and a list of outputs. Each input references a previous output being spent (by its txid and output index, the vout). Each output creates a new coin locked to an address. The total value of inputs always meets or exceeds the total value of outputs; the small difference is the fee paid to the miner who includes the transaction.

So when you "send" coins, you are really destroying some UTXOs and minting new ones. Following the chain of which outputs feed which inputs is exactly how you trace value across the ledger.

Tracing transaction flows

Because every output records where its value came from and where it went, you can walk the flow of funds forward or backward. Forward: take an output and find the transaction that later spent it. Backward: take an input and find the output it consumed. Stitch these together and you have a flow graph. Analysts use this for entity clustering, exchange-flow studies, and following large movements, always remembering that addresses are pseudonymous identifiers, not identities.

-- where did the coins in this transaction's outputs go next?
SELECT o.address AS from_addr, i.spending_txid, o2.address AS to_addr, o2.value_btc
FROM outputs o
JOIN inputs i  ON i.prev_txid = o.txid AND i.prev_vout = o.vout
JOIN outputs o2 ON o2.txid = i.spending_txid
WHERE o.txid = '9f2c...';

Confirmations and what "settled" means

An address balance is only as final as the transactions behind it. A payment with zero confirmations is still in the mempool and could be replaced or dropped. One confirmation means it landed in a block; each additional block on top makes a chain reorganization, and therefore a reversal, exponentially less likely. When you read a balance, also read the confirmation depth of its recent transactions before treating funds as spendable.

Get started

BitcoinDatabase indexes every address, output and input so a lookup that would otherwise require your own node and address index is a single REST call or SQL query. Open the Query Console, paste any address, and watch the balance, UTXOs and recent transactions resolve in real time, then drop the same /v1/address endpoint into your own app when you are ready.

Query Console
btc
try:

Hit Run to query the fully-indexed Bitcoin blockchain.

BTC

30-day trend

informational on-chain data · not financial advice

REST API · SQL · dashboards, one indexed dataset. Querying the indexed Bitcoin blockchain ...

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.

Query the whole Bitcoin blockchain

BitcoinDatabase indexes the public Bitcoin blockchain block by block and returns balances, UTXOs, transactions, on-chain metrics and fund flows by REST API, SQL and dashboards, with no node to run.

REST + SQL + dashboards · indexed since 2009 · new blocks within seconds

Informational on-chain data only · not financial, investment or legal advice · AML features are compliance tooling to support your own review.