Summary
BNB Chain (BNB Smart Chain) exposes a standard EVM JSON-RPC interface, so most tooling that works with Ethereum works here after you change the chain ID, RPC URL, and symbol. This page covers the mainnet and testnet chain settings, how to wire an endpoint into wallets and libraries, and what rate limits and workload patterns to plan for.
Use it as a working reference: copy the chain settings, test a request with curl, then decide whether a shared public endpoint, a managed RPC API, or a dedicated node fits your traffic. OnFinality provides BNB Chain RPC API access and dedicated node infrastructure if you need more headroom than public endpoints allow.
BNB Chain (BNB Smart Chain) is an EVM-compatible network, which means its RPC surface is the same JSON-RPC interface you already use for Ethereum. The practical work is not learning a new API — it is getting the chain settings right, wiring the endpoint into your wallet or library, and understanding how rate limits and request patterns affect reliability as your traffic grows.
This reference covers the mainnet and testnet settings, a working setup path, and the limit and workload questions that matter when you move from a quick test to production traffic.
Which BNB Chain endpoint should you start with?
Pick your starting point based on what you are doing right now, not on what you might do later.
| Your situation | Sensible starting point | Why |
|---|---|---|
| Reading docs, testing a script, one-off queries | Public RPC endpoint | No signup, fine for low volume and manual testing |
| A dApp, bot, or backend with steady traffic | Managed RPC API | Predictable access, better headroom, monitoring and support |
Heavy eth_getLogs, archive queries, or sustained throughput | Dedicated node | Isolated capacity, no noisy-neighbour effects from shared pools |
| You need WebSocket subscriptions at scale | Managed or dedicated with WS support | Public endpoints often restrict or throttle subscriptions |
If you are still exploring, start with a public endpoint and move on once you hit your first rate limit or timeout. If you already know you will run production traffic, skip the public tier and evaluate a managed RPC API early — migrating later costs more time than choosing well up front.
For a broader framework, see how to choose an RPC provider.
BNB Chain network settings at a glance
These are the values you paste into a wallet, a .env file, or a framework config. Keep mainnet and testnet separate — mixing them is one of the most common setup mistakes.
| Setting | BNB Smart Chain Mainnet | BNB Smart Chain Testnet |
|---|---|---|
| Chain ID | 56 | 97 |
| Native currency | BNB (18 decimals) | tBNB (18 decimals) |
| Block explorer | https://bscscan.com | https://testnet.bscscan.com |
| Transport | HTTP and WebSocket | HTTP |
| Typical use | Production dApps, bots, indexers | Development, staging, faucet testing |
OnFinality exposes public endpoints for both networks:
- Mainnet:
https://bnb.api.onfinality.io/public - Testnet:
https://bnb-testnet.api.onfinality.io/public
These are shared public endpoints, so treat them as a starting point rather than a production guarantee. For managed access with higher limits, see BNB Chain RPC and BNB Chain Testnet RPC.
Adding BNB Chain to a wallet
Most EVM wallets accept a custom network. The fields map directly to the settings above:
{
"chainId": "0x38",
"chainName": "BNB Smart Chain Mainnet",
"nativeCurrency": {
"name": "BNB Chain Native Token",
"symbol": "BNB",
"decimals": 18
},
"rpcUrls": ["https://bnb.api.onfinality.io/public"],
"blockExplorerUrls": ["https://bscscan.com"]
}
Note that chainId is hexadecimal in wallet configs: 56 decimal is 0x38, and 97 decimal is 0x61. If a wallet rejects your network, a wrong hex chain ID is the usual cause.
Testing the endpoint with curl
Before you wire anything into an application, confirm the endpoint responds and reports the chain you expect:
curl -s https://bnb.api.onfinality.io/public \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"eth_chainId","params":[]}'
A correct mainnet response returns 0x38. To check that the node is synced, call eth_blockNumber and compare it against a block explorer:
curl -s https://bnb.api.onfinality.io/public \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"eth_blockNumber","params":[]}'
If eth_chainId returns the wrong value, you are pointed at the wrong network. If eth_blockNumber lags far behind the explorer, the node may be catching up or the endpoint may be degraded.
Wiring BNB Chain into JavaScript
With ethers or viem, setup is a one-line change once you have the endpoint:
import { JsonRpcProvider } from "ethers";
const provider = new JsonRpcProvider(
"https://bnb.api.onfinality.io/public",
{ chainId: 56, name: "bnb" }
);
const block = await provider.getBlockNumber();
console.log("Latest BNB Chain block:", block);
For testnet, swap the URL to https://bnb-testnet.api.onfinality.io/public and set chainId: 97. Keep these values in environment variables rather than hard-coding them, so you can rotate endpoints without a redeploy.
How rate limits actually affect BNB Chain apps
Rate limits are usually expressed as requests per second or per minute, but the number alone does not tell you whether an endpoint will hold up. What matters is how your workload maps onto those limits.
- Method weight. Cheap calls like
eth_blockNumberandeth_chainIdconsume far less capacity thaneth_getLogs,eth_callagainst complex contracts, or trace methods. A limit that feels generous for block polling can disappear quickly under log queries. - Burst vs sustained. Many providers allow short bursts above the sustained rate. A bot that fires 200 requests in a second and then idles behaves very differently from one that sends 20 requests every second forever.
- Shared vs isolated. Public and shared endpoints pool capacity across all users, so your effective throughput can drop when the pool is busy. Dedicated nodes remove that variability.
- Payload size. Large
eth_getLogsranges return big responses. Some providers cap result size or block range regardless of request count.
A practical way to plan: measure your real request mix, not a guess. Log method names and counts for a day, then size your endpoint against the heaviest methods rather than the average.
Matching workload to endpoint type
| Workload pattern | What stresses the endpoint | Endpoint type that fits |
|---|---|---|
| Wallet or dashboard reading balances | Low volume, occasional eth_call | Public or shared managed |
| Trading bot polling blocks and mempool | Sustained request rate, low latency | Managed RPC API |
| Indexer scanning event logs | Large eth_getLogs ranges, archive data | Dedicated node with archive access |
| dApp with WebSocket subscriptions | Persistent connections, event fan-out | Managed or dedicated with WS support |
| Staging and CI test runs | Bursty, unpredictable | Testnet endpoint, separate from production |
If your row in this table lands on "dedicated", the decision is less about rate limits and more about isolation and predictable capacity. See dedicated node for how that model works.
Common setup and limit problems
Wrong chain ID. A wallet or library configured with 0x1 (Ethereum) instead of 0x38 will connect but return confusing results. Always verify with eth_chainId.
Testnet keys in production. Testnet tBNB has no value. If a deployment silently points at chain 97, transactions will appear to succeed but never settle on mainnet.
eth_getLogs range too wide. Many endpoints reject or truncate very large block ranges. Split queries into smaller windows and paginate.
429 responses under load. A sudden spike in 429 Too Many Requests usually means burst traffic exceeded the plan. Add retry with backoff, and consider a higher tier or dedicated node if it recurs.
WebSocket drops. Long-lived subscriptions can be closed by intermediaries. Implement reconnect logic and re-subscribe on reconnect rather than assuming the socket stays open.
Stale block height. If eth_blockNumber stops advancing, the endpoint may be resyncing. Fail over to a second endpoint rather than retrying the same one.
Running BNB Chain RPC in production
Once you are past setup, the operational questions change. Three things matter most:
- Failover. Configure at least two endpoints and switch on error or lag. A single endpoint is a single point of failure regardless of provider.
- Monitoring. Track request success rate, latency percentiles, and block height lag. Alert on lag before users notice.
- Capacity planning. Re-measure your request mix after each major feature launch. Log-heavy features change your profile more than user growth does.
OnFinality offers BNB Chain RPC API access and dedicated node infrastructure for teams that need more predictable capacity than public endpoints provide. Compare options on RPC pricing and review supported RPC networks if you run across multiple chains.
Key Takeaways
- BNB Smart Chain uses chain ID 56 (mainnet) and 97 (testnet), with standard EVM JSON-RPC methods.
- Public endpoints are fine for testing; production traffic needs predictable limits and failover.
- Rate limits depend on method weight and burst patterns, not just requests per second.
eth_getLogsand archive queries are the most common sources of limit and timeout issues.- Verify chain ID and block height before debugging anything else.
- Managed RPC APIs and dedicated nodes trade cost for isolation and headroom.
FAQ
What is the BNB Chain mainnet RPC URL?
OnFinality's public mainnet endpoint is https://bnb.api.onfinality.io/public. For managed access, see the BNB Chain network page.
What chain ID does BNB Smart Chain use?
56 for mainnet (0x38 in hex) and 97 for testnet (0x61 in hex).
Does BNB Chain RPC support WebSocket? Mainnet supports HTTP and WebSocket transport. Check the specific endpoint and plan, since public endpoints may restrict subscriptions.
Why am I getting 429 errors? You are likely exceeding a burst or sustained rate limit. Add retry with backoff, reduce request frequency, or move to a higher tier or dedicated node.
Can I use the same endpoint for testnet and mainnet? No. They are separate networks with separate chain IDs and endpoints. Keep them in separate configuration.
How do I know if an endpoint is synced?
Call eth_blockNumber and compare it with a block explorer. A large gap suggests the node is catching up or degraded.