Query the chain · Double spend detection
Bitcoin double spend detection API and RBF replacement data
A Bitcoin double spend is two transactions spending the same output. The commercially dangerous version is a replacement: a higher-fee transaction that evicts the payment you already credited. Detecting it is outpoint arithmetic on the mempool, not a flag lookup.
REST API · SQL · dashboards · address history from genesis
BTC
Balance trail
informational on-chain data · not financial advice
BitcoinDatabase indexes the full chain and the unconfirmed set together, so you can ask the one question that actually protects a payment flow: has anything else tried to spend the outputs my customer just spent? The inputs table is keyed on prev_txid and prev_vout, which is the exact shape of a conflict, and GET /v1/mempool plus GET /v1/tx/{txid} give you the unconfirmed side over REST. Informational on-chain data only, not financial advice.
Most teams reach for the replace-by-fee flag instead, and it is close to useless as a filter. We sampled the live mempool on 16 September 2026. Of 260 unconfirmed transactions we pulled and parsed individually, 232 signalled opt-in RBF, which is 89.23 percent. A signal carried by nearly nine in ten transactions does not separate risky payments from safe ones. As an independent cross-check we asked BlockCypher for its own opt_in_rbf field on a fresh sample of live mempool transactions: true on 15 of the 17 it could see, 88.24 percent, from a different provider and a different sample.
The flag is also not a boundary. Since full-RBF relay became widespread, a transaction that never signalled can still be replaced. Reading the live replacement feed on mempool.space the same day, between 1 and 5 of the 25 replacement trees visible were flagged fullRbf depending on the minute we looked, meaning the transaction being evicted had not opted in at all. A merchant policy of "reject transactions that signal RBF" therefore rejects most of its revenue and still does not close the hole.
What the replacement itself looks like is cheaper than people expect. Across the 25 trees in that feed, the median fee-rate increase from the original transaction to its replacement was 2.28 percent on one read and 5.5 percent on another minutes earlier, with a range of 1.89 to 7.56 percent. Replacing a transaction is not an expensive attack. It is a rounding error on the fee, which is why the only durable defence is a confirmation policy rather than a risk score.
One more measurement worth knowing before you build against a public endpoint. The Esplora transaction payload, the format served by both Blockstream and mempool.space, carries no replacement field whatsoever. Its top-level keys are fee, locktime, size, status, txid, version, vin, vout and weight. There is no double_spend, no rbf, no replaced_by. And the mempool cannot be snapshotted: on the same host, within the same few minutes, /api/mempool reported a count of 70,803 while /api/mempool/txids returned 72,906 entries, then 76,053. Any figure you publish about the unconfirmed set is a reading at an instant, and should be labelled as one.
History from genesis queryable in seconds
On-chain data not financial advice
Why it works
What you get with Double spend detection
Conflict detection, not flag reading
Ask whether any other unconfirmed transaction spends the same prev_txid and prev_vout as the payment you are waiting on. That question catches opt-in replacements, full-RBF replacements and outright conflicting broadcasts with one piece of logic, because all three look identical at the outpoint level.
The unconfirmed set, queryable
GET /v1/mempool returns the unconfirmed set and fee-rate estimates, and GET /v1/tx/{txid} resolves a transaction before it confirms with a confirmations value of zero. The same indexed data is available in SQL, so your risk rule and your reporting read from one source.
A confirmation policy you can defend
Replacements cost a few percent on the fee, so no detection layer makes a 0-conf credit safe on its own. Set a confirmation threshold by exposure, pin it in code, and use conflict detection to pull a payment back out of pending the moment a competing spend appears.
Side by side
Where a replacement signal actually comes from
Every row was probed against a live endpoint on 16 September 2026. We report what the response body contained, not what the transport status implied.
| Source | Replacement signal | How you get it | Catches full-RBF | What we measured |
|---|---|---|---|---|
| BitcoinDatabase | Yes, by outpoint conflict | inputs keyed on prev_txid and prev_vout, plus GET /v1/mempool | Yes | Conflict detection never depends on the flag |
| Esplora REST (Blockstream, mempool.space) | No field at all | Derive it yourself from vin sequence values | No | Tx keys: fee, locktime, size, status, txid, version, vin, vout, weight |
| mempool.space /api/v1/tx/{txid}/rbf | Partial | Returns replacements and replaces arrays | Yes when cached | Returned both fields as null, and /cached gave HTTP 204 No Content |
| BlockCypher | Yes, double_spend and opt_in_rbf | First-class JSON fields, no key needed | For transactions it saw | Knew 17 of 30 live mempool txids, 404 on the other 13 |
| Bitcoin Core on your own node | Yes | getrawmempool, testmempoolaccept, ZMQ notifications | Yes | Requires running, syncing and operating the node yourself |
A null is not a no. The per-transaction replacement endpoint answered null for a transaction that had never been replaced and would answer null for one it simply had not cached, and the companion cache endpoint returned an empty 204. If your payment logic treats null as safe, it is treating "we do not know" as "nothing happened".
What it handles
The indexed Bitcoin chain, queryable your way
Look up an address, a transaction, a UTXO, the rich list or an on-chain metric, by REST API, SQL or dashboard. The same authoritative data, reconciled block-by-block against the canonical chain, without running a node.
- Watch an outpoint for a conflicting unconfirmed spend
- Resolve a transaction before it confirms
- Pull live mempool state and fee-rate estimates
- Track confirmations against your own credit threshold
- Reconcile pending against confirmed in the same query
GET /v1/address/{addr}
query result
{
"address": "bc1qxy2k…l0wdv8",
"balance_btc": 68432.10,
"balance_usd": 4612165420,
"tx_count": 1284,
"unspent_outputs": 37,
"first_seen": "2014-02-09"
}
Why BitcoinDatabase
One platform, queryable three ways
Not a raw node to sync, not an indexer to build, and not five vendors to stitch together. The fully-indexed Bitcoin blockchain, available as a REST API, as SQL, and as dashboards, on one authoritative dataset.
REST API
Typed JSON for addresses, transactions, balances, UTXOs and metrics. Drop it into apps, wallets, explorers and agents with curl, Python or any HTTP client.
SQL access
Run SQL directly against the indexed Bitcoin dataset for ad-hoc analysis, cohorts and exports, the same data the API and dashboards read from.
Compliance-first
Informational on-chain data and analytics only. Entity labels and flow tracing are framed as tooling to support a regulated team's own review, not accusations.
Good questions
Questions about Double spend detection
Explore more
More ways to query Bitcoin with BitcoinDatabase
Bitcoin mempool API
Read unconfirmed transactions and current fee rates without running a node.
Learn moreBitcoin fee estimation API
Quote Bitcoin fee rates from live mempool state, then audit what your withdrawals actually paid.
Learn moreCrypto transaction monitoring API
Screen Bitcoin addresses and flows for AML risk from one fully-indexed data source.
Learn moreBitcoin dust attack detection
Dust limits per script type, dust transaction data, and the spray patterns behind address poisoning.
Learn moreBitcoin webhook API
Real-time notifications on address activity, incoming payments and confirmations.
Learn moreBitcoin address screening API
Screen a Bitcoin address for sanctions-list matches and exposure to labeled high-risk entities.
Learn moreStop running a node. Just query Bitcoin.
Run your first query now and get on-chain data back by REST API, SQL or dashboard, with address history back to the genesis block over REST. Informational on-chain data only, not financial advice.
History from genesis over REST · SQL · dashboards · addresses, transactions, UTXOs, metrics