Resumen
Sui public RPC endpoints are shared, unauthenticated JSON-RPC URLs that let you read chain state, submit transactions, and prototype against Sui mainnet or testnet without provisioning a node. They are the fastest way to get a wallet or script talking to Sui, but they are shared capacity with no account, no SLA, and no visibility into who else is using the same URL.
This page explains what a Sui public RPC endpoint can and cannot do, how to configure Sui JSON-RPC calls correctly, and the signals that tell you it is time to move to a managed RPC API or a dedicated Sui node. OnFinality provides Sui RPC through its RPC API and dedicated node offerings if you need isolated capacity and a support path.
A Sui public RPC endpoint is a shared, unauthenticated JSON-RPC URL that speaks to a Sui fullnode. You point a wallet, script, or indexer at it, send a method call, and get chain data back. No signup, no key, no contract. That convenience is exactly why public endpoints are the default first stop for anyone building on Sui — and exactly why they stop being the right answer once your workload has real users behind it.
This page covers what the public endpoint actually does, how Sui JSON-RPC is structured, the failure modes you will hit first, and the point at which a managed RPC API or a dedicated Sui node becomes the cheaper decision in engineering time.
Is a public Sui RPC endpoint enough for your workload?
Before you copy a URL into your config, decide which of these three situations you are in. The answer changes what you should do next.
| Your situation | Public endpoint fit | What to do next |
|---|---|---|
| Local prototyping, one-off scripts, learning Sui object model | Usually fine | Use a public endpoint, keep calls small, expect occasional failures |
| Wallet, dApp front end, or bot with real users | Risky as a primary path | Add a managed RPC API with a key, and keep a fallback |
| Indexer, high-volume reads, or latency-sensitive writes | Not suitable | Move to a dedicated Sui node or a managed plan sized to your throughput |
If you are in the first row, a public endpoint is a reasonable choice and you can stop reading after the request examples below. If you are in the second or third row, the rest of this page is about what breaks and how to replace it.
The core tradeoff is not speed — it is accountability. A public endpoint has no owner you can page, no capacity guarantee, and no way to see whether your traffic is competing with thousands of other callers. A managed or dedicated endpoint gives you a named counterpart, a capacity model, and a place to look when something is slow.
What Sui JSON-RPC actually looks like
Sui exposes a JSON-RPC interface over HTTP. Requests are POST bodies with a jsonrpc version, a method, params, and an id. Responses follow the standard JSON-RPC envelope with either a result or an error.
A minimal read call looks like this:
curl -sS -X POST "$SUI_RPC_URL" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "sui_getLatestCheckpointSequenceNumber",
"params": []
}'
A few things to notice. First, Sui method names are prefixed with sui_, so you will see calls like sui_getObject, sui_getTransactionBlock, sui_getBalance, and sui_multiGetObjects. Second, many methods take structured parameters — object IDs, owner addresses, or option objects — rather than a single positional argument. Third, the response shape for objects and transaction blocks is richer than a typical EVM receipt, because Sui tracks objects and their versions rather than a flat account balance.
In JavaScript, the same call through a fetch wrapper looks like:
async function suiRpc(url, method, params = []) {
const res = await fetch(url, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ jsonrpc: "2.0", id: Date.now(), method, params })
});
const json = await res.json();
if (json.error) throw new Error(`${json.error.code}: ${json.error.message}`);
return json.result;
}
const checkpoint = await suiRpc(process.env.SUI_RPC_URL, "sui_getLatestCheckpointSequenceNumber");
console.log("latest checkpoint", checkpoint);
Keep the URL in an environment variable from day one. Hardcoding a public endpoint into source is the single most common reason teams get stuck when they need to rotate to a managed provider later.
Sui mainnet and testnet: what changes between them
Sui runs a mainnet and a testnet with separate state, separate object IDs, and separate RPC endpoints. They are not interchangeable, and a transaction built for one will not execute on the other.
| Setting | Mainnet | Testnet |
|---|---|---|
| Purpose | Production assets and contracts | Pre-release testing, integration checks |
| State | Real value | Resets and faucet-funded |
| Endpoint | Separate mainnet URL | Separate testnet URL |
| Typical use | Wallets, dApps, indexers | CI, contract upgrades, wallet QA |
OnFinality exposes Sui through its network pages, and you can see the current endpoint and transport details on the Sui RPC network page. Because public endpoints and their availability change over time, treat any URL you find in a blog post as a starting point and confirm the current one from the network page or your provider dashboard before you ship.
One practical rule: never let a testnet endpoint leak into a production build. Use distinct environment variables such as SUI_MAINNET_RPC_URL and SUI_TESTNET_RPC_URL so a misconfigured deploy fails loudly instead of silently writing to the wrong network.
Failure modes you will hit on a shared endpoint
The first problems on a public endpoint are rarely dramatic. They show up as intermittent errors, slow responses, and calls that work locally but fail in production.
| Symptom | Likely cause | What to check |
|---|---|---|
429 or rate-limit errors | Shared capacity, bursty traffic | Request volume per second, retry logic, batching |
| Timeouts on read calls | Endpoint load or large result sets | Page size, sui_multiGetObjects batch size |
| Inconsistent results across calls | Reading from different nodes behind a load balancer | Whether you need a single consistent endpoint |
| Transaction submission rejected | Gas, object version mismatch, or endpoint policy | Object version freshness, gas budget, error code |
| Works in dev, fails in prod | Different endpoint or network | Environment variables, mainnet vs testnet |
Two of these deserve more detail. Object version mismatches are a Sui-specific trap: if you read an object, then build a transaction against that version, and the object changes before you submit, the transaction fails. This is not a public-endpoint problem, but a public endpoint's variable latency makes the window wider. Retry with a fresh read rather than resubmitting the same transaction.
Rate limiting is the other one. Public endpoints are shared, so a traffic spike from your app or from other callers can push you into throttling. If you see 429 responses, the fix is not a longer retry loop — it is a capacity decision. A managed RPC API with a key gives you a predictable share of capacity, and a dedicated node removes the shared-tenant problem entirely.
When to move to a managed RPC API or a dedicated Sui node
There is no single threshold, but there are clear signals. Move off a public endpoint when any of the following is true:
- You have real users and cannot tolerate unexplained failures.
- You need request volume that a shared endpoint will throttle.
- You want a support path and a named owner for the endpoint.
- You need archive-style historical reads or heavier query patterns.
- You are running an indexer, bot, or backend service with steady load.
The choice between a managed RPC API and a dedicated node comes down to isolation and control. A managed RPC API gives you an authenticated endpoint, a capacity model, and monitoring without you operating anything. A dedicated node gives you isolated hardware and full control over configuration and data access, which matters when your workload is large or has specific requirements.
OnFinality offers both: an RPC API service for teams that want a managed endpoint, and dedicated nodes for teams that need isolation. You can compare cost and capacity shapes on the RPC pricing page, and see the full set of chains on supported RPC networks. If you are still weighing providers generally, the provider selection guide walks through the evaluation criteria.
A migration path that does not break your app
Moving from a public endpoint to a managed one should be a config change, not a rewrite. Structure your code so the endpoint is the only thing that changes.
- Put the endpoint in an environment variable, not in source.
- Wrap all RPC calls in a single client module so retries, timeouts, and error handling live in one place.
- Add a health check that calls a cheap method like
sui_getLatestCheckpointSequenceNumberand records latency and error rate. - Run the managed endpoint alongside the public one for a period, and compare error rates before you cut over.
- Keep a fallback endpoint configured so a single provider issue does not take down your app.
A simple monitoring probe looks like this:
async function probe(url) {
const start = Date.now();
try {
await suiRpc(url, "sui_getLatestCheckpointSequenceNumber");
return { url, ok: true, ms: Date.now() - start };
} catch (err) {
return { url, ok: false, ms: Date.now() - start, error: err.message };
}
}
Run this on a schedule against each endpoint you depend on. The trend matters more than any single result: rising latency or a growing error rate is your signal to add capacity or switch primary endpoints before users notice.
Operational habits that keep Sui RPC stable
A few habits separate teams that rarely have RPC incidents from teams that have them weekly.
- Batch reads where the API supports it, but keep batches modest so a single failure does not lose a large payload.
- Set explicit timeouts on every call. A hanging request is worse than a fast failure.
- Retry with backoff on transient errors, but do not retry transaction submissions blindly — re-read object versions first.
- Log the endpoint URL alongside errors so you can tell which provider failed.
- Track error rate and p95 latency per endpoint, not just overall.
- Separate read traffic from write traffic if your provider offers distinct endpoints, so a heavy indexer does not slow down user transactions.
None of this is Sui-specific, but Sui's object model makes the retry discipline more important than on account-based chains, because a stale object version turns a retry into a guaranteed failure.
Key Takeaways
- A Sui public RPC endpoint is a shared, unauthenticated JSON-RPC URL — good for prototyping, risky as a production primary path.
- Sui JSON-RPC uses
sui_-prefixed methods and structured parameters; keep the endpoint in an environment variable from the start. - Mainnet and testnet are separate networks with separate endpoints and state; never let one leak into the other's build.
- The first failures you hit are rate limits, timeouts, and object version mismatches — all of which point to a capacity decision, not a code fix.
- Move to a managed RPC API when you need predictable capacity and a support path; move to a dedicated Sui node when you need isolation and control.
- Make the endpoint the only thing that changes in a migration, and monitor latency and error rate per endpoint.
Frequently Asked Questions
Is a Sui public RPC endpoint free to use?
Public endpoints are typically open and unauthenticated, which is why they are popular for prototyping. They are shared, so capacity is not guaranteed and heavy or bursty usage can be throttled. For production traffic, a managed or dedicated endpoint is the more predictable option.
What is the difference between Sui mainnet and testnet RPC?
They are separate networks with separate state and separate endpoints. Mainnet carries real assets; testnet is for testing and is faucet-funded. A transaction or object ID from one network will not work on the other.
Why do my Sui transactions fail with object version errors?
Sui tracks object versions. If an object changes between the time you read it and the time you submit a transaction that references it, the transaction fails. Re-read the object and rebuild the transaction rather than resubmitting the same payload.
Do I need a WebSocket connection for Sui?
It depends on your use case. If you need push-style updates, check whether your provider and the current Sui interface support subscriptions for the events you care about. If not, polling with a well-sized interval and a monitored endpoint is a workable alternative.
When should I switch from a public endpoint to OnFinality?
Switch when you have real users, steady or bursty load, or a need for a support path and predictable capacity. OnFinality provides Sui through its RPC API and dedicated node offerings, with details on the Sui network page.
Can I use more than one Sui RPC provider at once?
Yes, and for production apps it is often wise. Configure a primary and a fallback endpoint, monitor both, and route around failures. This reduces the blast radius of any single provider issue.