Bitcoin Runes and Ordinals API: Inscriptions, Rune Balances and Safe UTXOs
Ordinals and runes turned Bitcoin UTXOs into carriers of assets. An inscription lives on a specific satoshi. A rune balance lives on a specific output. For anyone building a wallet, marketplace, portfolio tracker or exchange integration, that changes what "read the balance" means. You now need to know not only how many sats an address holds, but which outputs carry inscriptions or runes and must not be spent by accident.
This guide explains what a runes and ordinals API needs to return, the endpoints you will call most, and the UTXO handling mistake that quietly destroys user assets.
Who needs a runes and ordinals API
Wallets that show inscriptions and rune balances, and must avoid spending them as fees.
Marketplaces and launchpads that list inscriptions or runes and verify ownership before a trade.
Portfolio and tax tools that value rune holdings and track inscriptions over time.
Exchanges and custodians that credit rune deposits and need to know exactly what arrived in each output.
All of them share one requirement: an index that follows the ord protocol rules precisely, since a balance computed with slightly different rules is simply wrong.
Ordinals and runes in two paragraphs
Ordinals number every satoshi in the order it was mined. An inscription attaches content (an image, text, JSON or other data) to one of those satoshis, and the inscription moves with that sat from output to output. Each inscription has an ID made of the reveal transaction ID, the letter i, and an index, for example 6fb9...e9a5i0, and a sequential inscription number.
Runes are fungible tokens recorded with OP_RETURN messages. A rune is etched once, with a name such as UNCOMMON•GOODS, a block:tx ID, a divisibility and optional mint terms. Balances are held by transaction outputs, and transfers move them between outputs according to the runestone in each transaction.
Three ways to get the data
Run
ordyourself. The reference indexer is open source and authoritative. It also needs a full Bitcoin Core node, a large and growing index, and someone to keep both healthy and in sync.Use a Bitcoin specialist API. Several Bitcoin-focused providers offer ordinals and runes endpoints. Check coverage, rate limits and whether their index tracks the current ord release.
Use a multi-chain UTXO API. If you also build on Cardano or Midnight, one provider for all your UTXO chains means one account, one bill and one set of docs.
Whichever you choose, verify three things: that inscription and rune data are returned on the UTXO, not only per address; that the index exposes its sync height so you can tell when it lags the chain tip; and that batch lookups exist, because checking outputs one at a time does not scale.
The endpoints you will use
The examples below use Nexus, the multi-chain data and transaction API from A.D. Labs, which runs Bitcoin Core, electrs and ord behind one API surface. Requests go to https://nexus.gerowallet.io with a Bitcoin-scoped key in the X-Api-Key header. The paths are representative of what any good runes and ordinals API should offer.
Everything an address holds
curl -H "X-Api-Key: $NEXUS_BTC_KEY" \
"https://nexus.gerowallet.io/api/btc/addresses/$ADDRESS/ordinals"
Returns the address with its inscriptions, its outputs, a runesBalances list and its satBalance. Each rune balance carries runeId, name, amount (in raw units), divisibility and symbol. Divide amount by 10 to the power of divisibility to display it.
Inscriptions held by an address, paged
curl -H "X-Api-Key: $NEXUS_BTC_KEY" \
"https://nexus.gerowallet.io/api/btc/addresses/$ADDRESS/inscriptions?limit=25"
Each entry has the inscription id, number, satpoint, txid, vout, satOffset, value and genesisHeight. Follow nextCursor for the next page (up to 100 per page).
One inscription in detail
curl -H "X-Api-Key: $NEXUS_BTC_KEY" \
"https://nexus.gerowallet.io/api/btc/ordinals/inscriptions/$INSCRIPTION_ID"
Returns the current address, contentType, contentLength, height, timestamp, sat, satpoint, parents, children, charms and, when present, the rune it etched.
One rune
curl -H "X-Api-Key: $NEXUS_BTC_KEY" \
"https://nexus.gerowallet.io/api/btc/ordinals/runes/UNCOMMON%E2%80%A2GOODS"
You can pass either the spaced name (URL encoded, the separator is •) or the block:tx ID. The response includes name, symbol, divisibility, etching, premine, mints, burned, mintable, turbo and the mint terms.
What sits on a specific output
curl -H "X-Api-Key: $NEXUS_BTC_KEY" \
"https://nexus.gerowallet.io/api/btc/ordinals/outputs/$TXID:$VOUT"
For many outputs at once, POST /api/btc/ordinals/outputs accepts up to 250 outpoints and returns each one's value, spent, confirmations, inscriptions and runes.
The mistake that burns inscriptions
A standard Bitcoin wallet picks UTXOs by value. It sees a 546 sat output and a 10,000 sat output and happily spends either one to cover a payment or a fee. If that 546 sat output carries an inscription, the inscription is sent to the recipient or, worse, given to a miner as fee. If an output carrying runes is spent without a runestone, its runes move to the first non-OP_RETURN output, which may be the payment recipient. If the runestone is malformed, the runes are burned.
The fix is to make coin selection asset-aware. Fetch UTXOs with their ordinals data attached and exclude any output that carries an inscription or a rune balance, unless the user is deliberately sending that asset:
curl -H "X-Api-Key: $NEXUS_BTC_KEY" \
"https://nexus.gerowallet.io/api/btc/addresses/$ADDRESS/utxos/page?includeOrdinals=true&limit=100"
With includeOrdinals=true, each UTXO includes ordinalsIndexed, an inscriptions array and a runes array. A safe selection rule is short:
const spendable = utxos.filter(
(u) => u.ordinalsIndexed && u.inscriptions.length === 0 && u.runes.length === 0
);
Note the ordinalsIndexed check. If the ord index has not yet processed an output, treat it as unsafe rather than empty. That single condition is the difference between a cautious wallet and one that loses assets during index lag. The response also returns the chain tip, so you can show users when data is a block or two behind.
Fees, broadcast and the rest of the stack
Asset-aware wallets need the ordinary Bitcoin endpoints too:
GET /api/btc/feesfor fee estimates, andGET /api/btc/mempoolfor mempool state.GET /api/btc/addresses/{address}/balanceand/txsfor balances and paged history.GET /api/btc/blocksandGET /api/btc/chain/tipfor chain state.POST /api/btc/txs/submitwith{"rawTxHex": "..."}to broadcast a transaction you built and signed client side.
Nexus does not construct Bitcoin transactions server side. You build and sign them in your own code or with a library such as bitcoinjs-lib, then submit through the API.
Where Nexus fits
Nexus is built for teams that work on more than one UTXO chain. The same account that serves Bitcoin addresses, fees, mempool, ordinals inscriptions and runes also serves Cardano, with the deepest coverage there (DEX market data, wallet P&L, transaction building and streaming), and Midnight. API keys are scoped to one chain and one network, so a Bitcoin key and a Cardano key sit side by side under one subscription and one bill.
Pricing is flat and published: Builder is $29 a month with a 7-day trial, then Growth $79, Scale $199 and Enterprise $499. There is no credit multiplier for heavier endpoints. Component health for bitcoind, electrs and ord is visible on the public status page.
To be precise about the limits: there is currently no endpoint that lists every holder of a rune, and no endpoint that lists or searches all runes. Lookups are by address, by output, by inscription ID and by rune name or ID.
For a broader view of Bitcoin data needs beyond ordinals, read Bitcoin Data Infrastructure: What Your App Actually Needs. If you are moving off a retired provider, Maestro Alternatives for Bitcoin and Cardano includes an endpoint migration map.
Common questions
How do I display a rune amount correctly?
APIs return rune amounts in raw units. Divide by 10 to the power of the rune's divisibility. A balance of 150000 for a rune with divisibility 2 is 1,500.00.
Can I look up a rune by name?
Yes. Use the spaced name with the • separator, URL encoded, or the block:tx rune ID. Names are uppercase.
Why does a fresh UTXO show ordinalsIndexed: false?
The ord index processes each block after it is confirmed. Until it does, the API cannot say whether that output carries assets, so your wallet should not spend it.
Does this work on testnet?
Bitcoin keys are scoped to a network. Nexus supports Bitcoin mainnet and testnet4.
Get started
To try these endpoints against your own addresses, start the 7-day Builder trial, create a Bitcoin key, and follow the Quick Start.