A Bitcoin API is not a single interface it is a layered set of access points, each designed for a different operational task. Bitcoin Core exposes a JSON-RPC server for raw protocol interaction. Esplora and mempool.space add address indexing on top. Understanding which layer you actually need, and why, is the decision that determines how much infrastructure you'll end up running.
This guide is for developers who know how REST APIs work and want to build something on Bitcoin a wallet backend, a transaction broadcaster, a fee estimator, or a payment verification tool. It assumes you're past the "what is Bitcoin" stage.
The UTXO Model Changes Everything About How You Query Bitcoin
Before touching any endpoint, you need to understand why Bitcoin APIs behave differently from APIs you've used on Ethereum or any account-based chain.
Bitcoin has no native concept of an address balance. There is no on-chain data structure that says "address X holds 0.5 BTC." What exists instead are unspent transaction outputs (UTXOs) discrete chunks of value locked to a scriptPubKey. An address's balance is the sum of all UTXOs whose scriptPubKey encodes that address. Computing that sum requires scanning the entire UTXO set for matching outputs, which is not a query Bitcoin Core was designed to serve by default.
This is the root cause of the most common confusion in Bitcoin API development: bitcoind cannot tell you the balance of an arbitrary address unless you've added a separate indexing layer. The RPC getbalance command works only for addresses in your own wallet. The scantxoutset RPC exists as a workaround but it scans the full UTXO set on each call, making it impractical for production use at any volume.
The practical implication: if your application needs to watch arbitrary addresses monitoring a merchant wallet, tracking on-chain activity for an exchange you need either a third-party API with indexing built in, or a self-hosted node running ElectrumX or Electrs as an address indexing layer on top of bitcoind.
Bitcoin Core's JSON-RPC Interface: The Ground Truth
Bitcoin Core runs a JSON-RPC 1.0 server on port 8332 (mainnet) by default, enabled via server=1 in bitcoin.conf. Every other Bitcoin API ultimately derives its data from a node like this one, so understanding it directly avoids the opacity of intermediary services.
Authentication and Basic Setup
Connections require HTTP Basic Auth. The credentials are set in bitcoin.conf:
rpcuser=youruser
rpcpassword=yourpassword
rpcallowip=127.0.0.1
Requests follow the JSON-RPC 1.0 envelope:
curl --user youruser:yourpassword \
--data-binary '{"jsonrpc":"1.0","id":"req1","method":"getblockchaininfo","params":[]}' \
-H 'content-type: text/plain;' \
http://127.0.0.1:8332/
The response includes fields like blocks (current chain height), difficulty, and chain ("main", "test", or "regtest"). For development, regtest lets you mine blocks on demand without waiting for real confirmations the fastest way to test a transaction pipeline end to end.
Transaction Lifecycle via RPC
Building and broadcasting a transaction through Bitcoin Core's RPC involves four distinct steps. Understanding each one also tells you what any third-party API is abstracting away on your behalf.
1. Select UTXOs with listunspent
bitcoin-cli listunspent 1 9999999 '["bc1q...youraddress"]'
This returns an array of UTXO objects, each with txid, vout (output index), amount, confirmations, and scriptPubKey. You select which UTXOs to spend as inputs. This is coin selection a decision that affects transaction size, fee, and privacy.
2. Construct the transaction with createrawtransaction
bitcoin-cli createrawtransaction \
'[{"txid":"abc123...","vout":0}]' \
'[{"bc1q...recipient": 0.01}]'
This returns a raw hex-encoded unsigned transaction. No signing happens here.
3. Sign with signrawtransactionwithwallet or use PSBT
For wallet transactions: bitcoin-cli signrawtransactionwithwallet <hex>. For multisig or hardware signer flows, the modern approach is Partially Signed Bitcoin Transactions (BIP-174), using createpsbt, walletprocesspsbt, and finalizepsbt. PSBT separates transaction construction from signing, which is the correct model for any setup where keys and the node are on different machines.
4. Validate before broadcasting with testmempoolaccept
This is a step most guides skip entirely. Before calling sendrawtransaction, you can dry-run the transaction against your node's mempool policy:
bitcoin-cli testmempoolaccept '["<signedrawtransaction_hex>"]'
The response tells you whether the transaction would be accepted, its vsize (virtual size, per BIP-141's SegWit discount), and the reject-reason if it fails. (Source: Bitcoin Core documentation, developer.bitcoin.org) Common rejection reasons include min relay fee not met and non-mandatory-script-verify-flag, each pointing to a distinct problem. Catching these before broadcast saves you from debugging failed transactions after the fact.
5. Broadcast with sendrawtransaction
If testmempoolaccept returns "allowed": true, send it. The node propagates the transaction to peers and returns the txid.
The txindex Flag and Its Consequences
By default, Bitcoin Core only indexes transactions that belong to your wallet. If you call getrawtransaction on an arbitrary txid without passing its block hash, it will fail unless you've started bitcoind with txindex=1 in bitcoin.conf.
Enabling txindex requires a full reindex on first use roughly 6–12 hours on modern hardware and adds about 50 GB to node storage requirements as of 2026. It is worth doing for any application that needs to look up historical transactions by ID. It does not, however, solve the address balance problem described earlier. For that, you still need Electrs.
The REST Interface: Lighter Queries Without Full RPC
Bitcoin Core also exposes an optional REST server, enabled with rest=1 in bitcoin.conf. Unlike the RPC interface, REST endpoints use standard HTTP GET requests and return JSON, hex, or binary depending on the file extension you append.
Key REST endpoints (Source: Bitcoin Core REST interface documentation, github.com/bitcoin/bitcoin):
GET /rest/tx/<TXID>.json — transaction data
GET /rest/block/<BLOCKHASH>.json — full block with transactions
GET /rest/getutxos/<TXID>-<N>.json — UTXO query for specific outpoints
GET /rest/mempool/contents.json — full mempool transaction list
GET /rest/chaininfo.json — equivalent to getblockchaininfo
The UTXO endpoint (/rest/getutxos/) is notable: it implements BIP-64, and the /checkmempool/ variant also includes unconfirmed outputs. This is useful for verifying payment receipt before a transaction confirms. The response includes scriptPubKey with the decoded address, value in BTC, and coin height (set to 2147483647 for unconfirmed outputs, which is a signal worth checking in any payment verification logic).
The REST interface is faster for read-heavy workloads because it bypasses the JSON-RPC authentication overhead, but it exposes no wallet functionality and has no built-in rate limiting opening it on a public interface is a significant operational risk.
Esplora and mempool.space: When You Don't Want to Run the Indexer
For most applications that need address-level queries, the practical choice is an external API with indexing built in. The two dominant open-source options are Blockstream Esplora and mempool.space, and they serve different primary purposes despite overlapping APIs.
Esplora (which powers blockstream.info) is built on Bitcoin Core plus Electrs (an Electrum server implementation in Rust) and exposes a clean REST API. The public endpoint at https://blockstream.info/api is free, rate-limited, and sufficient for development. For production, Blockstream's documentation explicitly recommends self-hosting. Its address endpoint returns a transaction history with a chain_stats and mempool_stats object that splits confirmed and unconfirmed balances separately a design that correctly reflects Bitcoin's UTXO reality.
mempool.space goes further on mempool-specific data. Its fee estimation endpoint at GET /api/v1/fees/recommended returns four fee tiers — fastestFee, halfHourFee, hourFee, and economyFee all in sat/vB (satoshis per virtual byte). This is the correct unit for Bitcoin fee calculation post-SegWit. (Source: mempool.space API documentation) Bitcoin Core's own estimatesmartfee uses BTC/kB, which requires unit conversion and is arguably less intuitive for developers used to working with individual transactions.
The critical difference in fee estimation method: mempool.space uses live mempool analysis, looking at current fee rates of queued transactions to estimate what rate gets you into the next block. Bitcoin Core's estimatesmartfee is history-based, extrapolating from how long past transactions took to confirm. Mempool-based estimation is more accurate during rapid fee spikes; history-based estimation is more stable during normal conditions. Production fee estimators like the one maintained by LN Zap combine both sources, using mempool-based estimates for the next 1–6 blocks and history-based for targets further out. (Source: Strike, "Blended Bitcoin Fee Estimations," strike.me)
Fee Calculation in Practice
Fee rate is expressed in sat/vB. Virtual size (vsize) differs from raw byte size for SegWit transactions because witness data is discounted at a 4:1 ratio per BIP-141:
vsize = (non-witness bytes × 4 + witness bytes) ÷ 4
For a typical native SegWit (P2WPKH) single-input, single-output transaction, the vsize is approximately 110 vB. At a fee rate of 20 sat/vB:
fee = 110 vB × 20 sat/vB = 2,200 satoshis ≈ $0.02 at $90,000/BTC
The testmempoolaccept response includes the computed vsize for your specific transaction, which makes it a reliable source of truth before you commit to a fee rate. Constructing the transaction, checking vsize via testmempoolaccept, then fetching a live fee rate from mempool.space's API and computing the fee then reconstructing with the correct output is the correct sequence for a fee-aware broadcast workflow.
Choosing the Right Layer for Your Use Case
Different applications need different parts of this stack. The decision tree is straightforward once you map your requirements:
You need to broadcast transactions and have full signing control → Bitcoin Core RPC + PSBT workflow. No external dependency; the ground truth.
You need address balance lookups or full transaction history for arbitrary addresses → Esplora API (self-hosted with Electrs for production, blockstream.info/api for development).
You need real-time fee estimation and mempool visualization → mempool.space API. Their /api/v1/fees/recommended endpoint is updated every 30 seconds and is the most widely used fee source in the ecosystem.
You need WebSocket push for new transactions or blocks → mempool.space exposes a WebSocket connection at wss://mempool.space/api/v1/ws. You send a JSON subscription message for address tracking or block announcements and receive push events without polling. This is substantially more efficient than polling /rest/mempool/contents.json for high-frequency monitoring.
You need payment processing with fiat settlement → a hosted provider (Blockonomics, BitPay, Cobo WaaS) is the appropriate tool. These are payment gateway products, not data APIs, and they trade sovereignty for integration speed.
The mistake to avoid is treating any hosted API as a substitute for a node in a production system that handles funds. Hosted APIs have rate limits, outages, and occasionally return stale data during blockchain reorganizations. For a wallet backend or exchange infrastructure, running your own Bitcoin Core node with an appropriate indexing layer is not optional infrastructure it is the baseline.
A Note on Privacy and Data Exposure
Every request to a third-party API is a data disclosure. When your application calls blockstream.info/api/address/bc1q..., you are telling Blockstream's servers that your application is interested in that address. For wallet software especially, this is a material privacy consideration. The Electrum protocol (used by Electrs) was designed partly to mitigate this via bloom filters, though that approach has well-documented limitations.
Self-hosting Electrs alongside your Bitcoin Core node eliminates this entirely and costs roughly 30–50 GB of additional storage for the full address index. For any application managing user funds, this is the correct production architecture. For BTC trading applications where transaction monitoring is involved, the same principle applies: own your data pipeline.
FAQ
Can I get the balance of any Bitcoin address without running my own node?
Yes, using a third-party API like blockstream.info/api/address/<address> or mempool.space. The response includes chain_stats.funded_txo_sum minus chain_stats.spent_txo_sum for confirmed balance, and equivalent mempool_stats fields for unconfirmed. However, this discloses the address to the API provider. For production systems handling real funds, self-hosting Electrs is the recommended approach.
Why does getrawtransaction fail for transactions not in my wallet?
By default, Bitcoin Core only indexes wallet transactions. To query arbitrary transactions by txid, you must enable txindex=1 in bitcoin.conf and perform a full reindex. Without this flag, you can still retrieve a transaction if you provide its block hash as a second parameter, since Bitcoin Core can locate it by scanning the block directly.
What is the correct unit for Bitcoin transaction fees in 2026?
Satoshis per virtual byte (sat/vB). The "virtual" refers to BIP-141's SegWit discount, which weights witness data at 1/4 of a byte for fee purposes. All modern fee estimators, including mempool.space and most wallet software, express fees in sat/vB. Bitcoin Core's estimatesmartfee uses BTC/kVB (BTC per 1,000 virtual bytes), which equals sat/vB × 100,000 a conversion worth hard-coding as a constant to avoid fee miscalculations.
What is PSBT and when should I use it?
Partially Signed Bitcoin Transactions (BIP-174) is a standard for passing unsigned or partially signed transactions between participants in a signing workflow. Use it whenever keys and the node are on different machines hardware wallets, multisig setups, or any air-gapped signing environment. PSBT separates UTXO selection and transaction construction (done by the online node) from key operations (done by the signer), which is the correct security model for any significant amount of bitcoin.
Is mempool.space free to use in production?
The public mempool.space API is free with rate limits that are adequate for light production use. For high-throughput applications, mempool.space documentation recommends self-hosting, and the full stack is open-source (AGPL-3.0, written in TypeScript and Rust). Self-hosting also gives you control over the data you expose and eliminates third-party availability risk.
This article is for educational purposes only and does not constitute financial advice.