A BNB Chain explorer API is any service that returns BNB Smart Chain data — blocks, transactions, balances, tokens — to your code. In 2026 you have three free routes: BNB Chain’s public JSON-RPC endpoints (no key, eth_call included), key-less indexers like Binplorer and GoPlus, and BSCTrace’s MegaNode free plan. BscScan’s free API no longer exists.
That last sentence broke a lot of bots, dashboards and tax scripts over the winter. This guide is the fix. We start with what changed, compare every option on price and limits, then hand you copy-paste curl commands for the calls developers make most often — block height, balances, receipts, balanceOf via eth_call, token metadata and revert reasons — all tested against the live endpoints in September 2026. At the end you will see exactly how our own BNB transaction explorer reads the chain without a single API key.
The BscScan API is deprecated. What replaced it?
In December 2025 BNB Chain developers announced that the BscScan API was deprecated in favour of Etherscan API V2, which uses one key and one base URL for more than 60 chains and selects the network with a chainid parameter. The catch: Etherscan’s supported-chains table marks BNB Smart Chain mainnet (56) and testnet (97) as “Paid Tier Only”. We tried it with a free key:
curl -s "https://api.etherscan.io/v2/api?chainid=56&module=proxy&action=eth_blockNumber&apikey=YOUR_FREE_KEY"
{"status":"0","message":"NOTOK",
"result":"Free API access is not supported for this chain. Please upgrade your api plan for full chain coverage. https://etherscan.io/apis"} Etherscan’s free tier gives 3 calls per second and up to 100,000 a day, but only on selected chains. The cheapest plan that covers BSC is the Lite plan (5 calls per second, 100,000 a day), which Etherscan introduced at a quarter of the price of its previous lowest paid tier. Two exceptions are worth knowing. Verified source code and ABI endpoints (getsourcecode, getabi) stay free on every chain, BSC included. And opBNB mainnet (204) and opBNB testnet (5611) remain on the free tier. For the full story of the explorer itself, see our BscScan review.
BNB Chain’s own answer was a migration guide from BscScan API to BSCTrace via MegaNode, published the same month. It maps BscScan’s module/action calls to JSON-RPC: account/balance becomes eth_getBalance, proxy/eth_getTransactionReceipt becomes the method of the same name, and account/txlist becomes NodeReal’s nr_getAssetTransfers.
Your BSC API options in 2026, compared
Here is the landscape on one screen. “Free” means usable without paying; some options still require a sign-up to get a key.
| Service | Free on BSC? | Free limits | Paid from | Best for |
|---|---|---|---|---|
| BNB Chain public RPC | Yes, no key | 10K req / 5 min / IP | — | Live reads, eth_call |
| PublicNode · 1RPC | Yes, no key | Fair use | Provider plans | Failover, small getLogs |
| BSCTrace / MegaNode | Yes, free key | 10M CU/mo · 150 CUPS | $31/mo (annual) | History, transfers, archive |
| Binplorer | Yes, freekey | 2/s · 1,000/day | Personal key | Token balances, prices |
| GoPlus Security | Yes, no key | Fair use | Paid plans | Token risk flags |
| Etherscan API V2 | No (paid only) | ABI & source only | Lite plan | Legacy BscScan code |
| Blockscout | No BSC instance | — | — | Self-host only |
Most real projects combine two or three of these: public RPC for anything a node can answer, an indexer for history, and a paid plan only when volume demands it. Blockscout is on the list because people search for it; there is no public BSC instance, as our BNB Smart Chain Blockscout explainer shows. For the explorer UIs behind these APIs, our BSCTrace review and the explorer ranking go deeper.
BSC RPC endpoints and limits
BNB Chain publishes its official endpoints in the JSON-RPC endpoint docs. We tested each of the following with eth_chainId and eth_blockNumber:
Ten thousand requests per five minutes works out to about 33 per second from one IP — generous for a dashboard or a bot, not enough to index the chain. dRPC’s public endpoint (bsc.drpc.org) also works without a key but throttled us quickly, and Ankr’s formerly public BSC URL now demands an API key. Testnet endpoints and faucets are covered in our BNB testnet explorer guide.
Tested curl examples: eth_call and friends, no API key
Every command below ran against the live endpoints while we wrote this. Results change with every block, so your numbers will differ; the shapes will not. All values come back as hex strings — convert with printf '%d' 0x… or your language’s BigInt.
eth_blockNumber — latest block height
curl -s -X POST https://bsc-dataseed.bnbchain.org \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}'
{"jsonrpc":"2.0","id":1,"result":"0x7628198"} # 0x7628198 = 123,896,216 eth_getBalance — native BNB balance
Returns wei (10-18 BNB). The example reads the WBNB contract, which holds all wrapped BNB.
curl -s -X POST https://bsc-dataseed.bnbchain.org \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"eth_getBalance",
"params":["0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c","latest"]}'
{"jsonrpc":"2.0","id":1,"result":"0x14a463f3d72d4db881ec3"}
# wei → BNB: divide by 10^18 → ≈ 1,559,676.77 BNB held by the WBNB contract eth_getTransactionReceipt — did it succeed, what moved?
status is 0x1 for success and 0x0 for a revert. Token movements live in logs: topic 0 of a BEP-20 Transfer is always 0xddf252ad…b3ef, topics 1 and 2 are the sender and recipient padded to 32 bytes, and data is the amount. Our guide to reading a BSC transaction explains the same fields in a UI.
curl -s -X POST https://bsc-dataseed.bnbchain.org \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"eth_getTransactionReceipt",
"params":["0x596be466441dca5c43bff1e90aff65ad19d259e1713c408222ef4cb73700e17a"]}'
{"result":{"status":"0x1", "gasUsed":"0x86d3", # success, 34,515 gas
"to":"0x55d398326f99059ff775485246999027b3197955", # the USDT contract
"logs":[{"topics":["0xddf252ad…b3ef", # Transfer(from,to,value)
"0x…bd612a3f30dca67bf60a39fd0d35e39b7ab80774", # from
"0x…db83e219c36b3d2fd876539402736a4e7a2f4f3d"], # to
"data":"0x…3da08bf6de97920000"}], …}} # 1,136.82 USDT (18 decimals) eth_call balanceOf — build the calldata yourself
Calldata is the 4-byte function selector followed by the arguments, each left-padded to 32 bytes. For balanceOf(address) the selector is 0x70a08231; the argument is the address without 0x, lower-cased, padded with 24 zeros to 64 hex characters. In bash:
ADDR=0x8894E0a0c962CB723c1976a4421c95949bE2D4E3
DATA=0x70a08231$(printf '%064s' $(echo ${ADDR#0x} | tr 'A-F' 'a-f') | tr ' ' 0)
echo $DATA
# 0x70a082310000000000000000000000008894e0a0c962cb723c1976a4421c95949be2d4e3
curl -s -X POST https://bsc-dataseed.bnbchain.org \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"eth_call",
"params":[{"to":"0x55d398326f99059fF775485246999027B3197955","data":"'$DATA'"},"latest"]}'
{"jsonrpc":"2.0","id":1,"result":"0x…0143feb02d6709d2227d9d49"} # raw uint256, divide by 10^18 decimals() and symbol() in one batch
decimals() (0x313ce567) returns a plain uint. symbol() (0x95d89b41) returns an ABI-encoded string: a 32-byte offset, a 32-byte length, then the UTF-8 bytes. A few very old tokens return a bytes32 instead, so a robust decoder handles both.
curl -s -X POST https://bsc-dataseed.bnbchain.org \
-H 'Content-Type: application/json' \
-d '[{"jsonrpc":"2.0","id":1,"method":"eth_call","params":[{"to":"0x55d398326f99059fF775485246999027B3197955","data":"0x313ce567"},"latest"]},
{"jsonrpc":"2.0","id":2,"method":"eth_call","params":[{"to":"0x55d398326f99059fF775485246999027B3197955","data":"0x95d89b41"},"latest"]}]'
[{"jsonrpc":"2.0","id":1,"result":"0x…0012"}, # decimals() = 18
{"jsonrpc":"2.0","id":2,"result":"0x…0020 # offset 32
…0004 # length 4
5553445400…"}] # "USDT" in UTF-8 Get a revert reason before you pay for it
eth_call with a from field simulates a transaction without signing it. If it would fail, the node returns the revert string — here, a USDT transfer from an address with no balance. Run this before broadcasting and you never pay gas for a doomed transaction.
curl -s -X POST https://bsc-dataseed.bnbchain.org \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"eth_call","params":[{
"from":"0x000000000000000000000000000000000000c0Fe",
"to":"0x55d398326f99059fF775485246999027B3197955",
"data":"0xa9059cbb000000000000000000000000000000000000000000000000000000000000beef0000000000000000000000000000000000000000000000000de0b6b3a7640000"},"latest"]}'
{"error":{"code":3,"message":"execution reverted: BEP20: transfer amount exceeds balance", …}} eth_getLogs — where the free lunch ends
# Official endpoint: disabled
curl -s -X POST https://bsc-dataseed.bnbchain.org -H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"eth_getLogs","params":[{"fromBlock":"latest","toBlock":"latest"}]}'
{"jsonrpc":"2.0","id":1,"error":{"code":-32005,"message":"limit exceeded"}}
# PublicNode: fine for small ranges, e.g. USDT Transfer events in the latest block
curl -s -X POST https://bsc-rpc.publicnode.com -H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"eth_getLogs","params":[{"fromBlock":"latest","toBlock":"latest",
"address":"0x55d398326f99059fF775485246999027B3197955",
"topics":["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"]}]}' For event history beyond a few blocks, use MegaNode or a WebSocket subscription, or query an indexer such as Binplorer that has already processed the logs.
JSON-RPC batching: fewer round trips, same data
The JSON-RPC 2.0 spec lets you POST an array of requests and get an array of responses, matched by id. It is the single biggest speed-up for BSC reads: loading a transaction page needs the transaction, its receipt, the current block number and the block timestamp, and a batch fetches the first three in one HTTP request instead of three. The official endpoints accept up to 100 calls per batch; at 120 we got batch length does not support more than 100, while PublicNode accepted 120.
Three rules keep batches reliable. Match responses by id, never by position, because providers may reorder them. Treat each element separately: one failed eth_call does not fail the whole batch. And assume every element counts against rate limits, so batching saves latency, not quota.
Binplorer and GoPlus: indexed data without a key
A node can tell you a balance right now; it cannot list every token a wallet holds or every transfer it made, because that needs an index. Binplorer, from the team behind Ethplorer, runs that index for BSC and exposes it with the public key freekey. Its API documentation caps the free key at 2 requests per second, 20 per minute, 100 per hour, 1,000 per day and 3,000 per week — fine for a prototype or a personal tool, not for production.
curl -s "https://api.binplorer.com/getTokenInfo/0x55d398326f99059fF775485246999027B3197955?apiKey=freekey"
{"address":"0x55d3…7955","name":"Tether","decimals":"18","symbol":"USDT",
"price":{"rate":0.9997, …},"holdersCount": …}
# other freekey endpoints (same base URL)
/getAddressInfo/{address} # BNB + token balances with prices
/getTxInfo/{hash} # decoded tx with token operations
/getAddressHistory/{address} # token transfers (&limit=25)
/getAddressTransactions/{address} # BNB transfers (&limit=25)
/getTopTokens?limit=10 # most active BEP-20 tokens
/getLastBlock # index height GoPlus Security answers a different question: is this token dangerous? Its free token-security endpoint for chain 56 flags honeypots, buy and sell taxes, mint functions, upgradeable proxies, blacklists and owners who can change balances. Treat a red flag as a stop sign and a clean result as “no obvious trap”, not a guarantee. Our BSC token checker guide explains every flag.
curl -s "https://api.gopluslabs.io/api/v1/token_security/56?contract_addresses=0x55d398326f99059fF775485246999027B3197955"
{"code":1,"message":"OK","result":{"0x55d3…7955":{
"buy_tax":"0","sell_tax":"0","is_honeypot":"0","is_open_source":"1",
"is_proxy":"0","is_mintable":"1","owner_change_balance":"0", … }}} BSCTrace via MegaNode: the free keyed option
When you outgrow key-less sources, NodeReal’s MegaNode — the API behind the BSCTrace explorer — is the natural next step. Sign up, create a key, and your endpoint becomes https://bsc-mainnet.nodereal.io/v1/<API_KEY> (testnet: bsc-testnet.nodereal.io). The free plan includes 10 million compute units a month, 150 compute units per second, three API keys, mainnet and testnet, and archive data. Growth costs $31 a month on annual billing, with Team and Business tiers above it.
Everything shown above works there too, plus eth_getLogs, historical state and NodeReal’s enhanced methods: nr_getAssetTransfers for normal, BEP-20, NFT and internal transfers by address, nr_getTokenHolders and nr_getTokenHolderCount, nr_getTokenBalance20 and nr_getContractCreationTransaction. Method details are in the NodeReal migration docs. Keep the key on your server, because it sits in the URL path.
Your API reads are free. Your transactions are not.
Relayers, keepers and deployers all spend BNB on gas. Fund them from a regulated exchange partner operating since 2013.
Rate limits and failover: tips that save you at 3 a.m.
Rotate endpoints. Keep an ordered list — two official hosts, PublicNode, 1RPC — and move to the next on a timeout, an HTTP 429 or a JSON-RPC error that mentions a limit. Remember which one worked last and start there next time.
Back off exponentially. On repeated -32005 or 429 responses, wait 1, 2, 4, 8 seconds before retrying the same host. Hammering a throttled endpoint only extends the ban.
Cache what never changes. Token decimals, symbols, contract bytecode and receipts of finalised blocks are immutable. With fast finality in about a second on BSC, anything a few blocks deep is safe to cache forever.
Poll sensibly. Blocks arrive every 0.45 seconds since the Fermi hard fork, but polling eth_blockNumber once a second is plenty for most apps — 300 requests per five minutes, 3% of the official quota. For real-time feeds use a WebSocket newHeads subscription from a provider.
Verify the chain. Call eth_chainId once at start-up and refuse to continue unless it is 0x38. It is cheap insurance against a mis-pasted testnet URL.
Calling BSC from the browser: CORS and keys
Browsers only let a page read a cross-origin response if the server allows it. The official BNB Chain endpoints and PublicNode both reply with Access-Control-Allow-Origin: *, and Binplorer and GoPlus echo your origin back, so all four work straight from front-end JavaScript — we checked the headers. That is what makes a zero-backend explorer possible.
The other half is secrets. Never ship an Etherscan or MegaNode key in client code; it will be scraped within days. If you need a keyed source in the browser, put a tiny proxy in front of it — a serverless function that adds the key, allow-lists methods and caches responses. And if you add a wallet connection, remember that reading data never requires a signature. Only broadcasting a transaction does. Our MetaMask setup guide lists the correct RPC and explorer URLs for wallets.
How our site reads BSC without any API key
Everything on this site — the explorer, the live stats, the gas widget — runs in your browser on the sources described above. No backend, no keys, nothing stored. The core is a batched JSON-RPC client with failover across five public endpoints:
// Simplified from our explorer's data layer (src/lib/chain.ts)
const RPCS = ['https://bsc-dataseed.bnbchain.org', 'https://bsc-rpc.publicnode.com',
'https://bsc-dataseed1.bnbchain.org', 'https://1rpc.io/bnb', 'https://bsc.drpc.org'];
async function rpcBatch(calls) {
const body = JSON.stringify(calls.map(([method, params], i) =>
({ jsonrpc: '2.0', id: i + 1, method, params })));
for (const url of RPCS) { // failover, in order
try {
const res = await fetch(url, { method: 'POST', body,
headers: { 'Content-Type': 'application/json' },
signal: AbortSignal.timeout(9000) }); // 9 s timeout per endpoint
const arr = [].concat(await res.json());
if (arr.some(x => /limit|rate|exceed/i.test(x?.error?.message ?? '')))
throw new Error('rate limited'); // try the next endpoint
const byId = new Map(arr.map(x => [x.id, x]));
return calls.map((_, i) => byId.get(i + 1)?.result ?? null);
} catch { /* next */ }
}
throw new Error('All RPC endpoints failed');
}
// name, symbol, decimals, totalSupply of a token in ONE round trip
const meta = await rpcBatch(['0x06fdde03', '0x95d89b41', '0x313ce567', '0x18160ddd']
.map(data => ['eth_call', [{ to: token, data }, 'latest']])); Around that core sit a few more key-less calls. A transaction lookup batches eth_getTransactionByHash, eth_getTransactionReceipt and eth_blockNumber, then decodes Transfer logs and fetches token metadata for up to 40 tokens in a single batch. Method names come from a built-in dictionary of common selectors, with the public OpenChain signature database as a fallback. Address pages add Binplorer’s holdings and history on mainnet, ignoring prices of tokens with less than $50,000 of daily volume so that spam airdrops do not inflate balances. Token pages add the GoPlus scan, and the BNB price comes from CoinGecko with Binplorer as backup. Try it on any hash in our BSC explorer, or on the testnet and opBNB networks via the opBNB explorer page.