Every Solana explorer is a front end on top of an API. When you search a signature on Solscan or Solana Explorer, the site calls Solana’s JSON-RPC interface, often through its own indexer, and renders the result. So when people search for a Solana explorer API, they usually want one of three things: raw on-chain data they can fetch for free, a richer indexed API with labels and history, or market data like prices and trading pairs. This guide compares all three as of September 2026, with working code and the limits we measured ourselves.
Solana explorer API options at a glance
The short answer: use JSON-RPC for raw data, an indexer for history and parsing, and market APIs for prices. The table summarises the options we tested for Solscanner’s own live lookup tool.
| Provider | Key needed | Good for | Limits |
|---|---|---|---|
| api.mainnet-beta.solana.com | No | Testing, light scripts | 100 req / 10 s per IP |
| solana-rpc.publicnode.com | No | Tx, signatures, balances, blocks | No indexed token calls |
| public.rpc.solanavibestation.com | No | Token accounts, holders, supply | Rate-limited |
| Solscan Pro API | Yes | Labels, transfers, token data | Lite: $49/mo, 20M CU |
| Helius | Yes | Parsed history, DAS, archival | Free: 1M credits, 10 req/s |
| Jupiter lite-api | No | Token prices, metadata | Rate-limited |
| DexScreener | No | DEX pairs, liquidity | 60–300 req/min |
A few more results from our tests, so you don’t waste an afternoon. Tatum’s anonymous access allowed only 5 requests per minute and many methods were paid. Ankr needed a key. dRPC’s free plan did not include Solana. BlockEden was paid-only. The public SolanaFM and Solana Beach APIs returned HTTP 502 during our checks.
The core JSON-RPC methods every explorer uses
Four methods cover most of what an explorer page shows. Each takes a JSON body with jsonrpc, id, method and params, sent by POST to any RPC endpoint.
- getSignaturesForAddress returns the transaction signatures that touched an address, newest first. Each entry includes
signature,slot,err(null on success),memo,blockTimeandconfirmationStatus.limitranges from 1 to 1,000 and defaults to 1,000. This is the “history” list on a wallet page. - getTransaction returns the full transaction for one signature: instructions, accounts, fee, compute units consumed, logs, and pre/post balances. Pass
"maxSupportedTransactionVersion": 0or versioned transactions will fail. - getBalance returns an account’s SOL balance in lamports (1 SOL = 1,000,000,000 lamports).
- getTokenAccountsByOwner returns the SPL token accounts a wallet owns, filtered by mint or by token program (legacy SPL Token or Token-2022). Use
jsonParsedencoding to get readable balances.
These are the building blocks of the wallet explorer and transaction explorer views. Holder lists, token supply and program-owned account scans use heavier methods such as getTokenLargestAccounts, getSupply and getProgramAccounts, which many public nodes treat as “indexed” requests and block.
getSignaturesForAddress example: fetch and curl
Here is a minimal browser or Node 18+ example that lists the latest 25 signatures for an address. It uses the USDC mint as a sample address, but any wallet or program works.
const RPC = 'https://solana-rpc.publicnode.com';
const address = 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v';
const res = await fetch(RPC, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
jsonrpc: '2.0',
id: 1,
method: 'getSignaturesForAddress',
params: [address, { limit: 25, commitment: 'confirmed' }],
}),
});
const { result, error } = await res.json();
if (error) throw new Error(`${error.code}: ${error.message}`);
for (const s of result) {
console.log(s.signature, s.slot, s.err ? 'failed' : 'ok', s.blockTime);
}
The same call from a terminal:
curl -s https://solana-rpc.publicnode.com \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"getSignaturesForAddress",
"params":["EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",{"limit":5}]}'
To fetch one of those transactions, change the method to getTransaction and pass [signature, { "encoding": "jsonParsed", "maxSupportedTransactionVersion": 0 }]. blockTime is a Unix timestamp in seconds and can be null for very old or pruned data.
Pagination with before and until
getSignaturesForAddress pages backwards in time. Pass before with the last signature from the previous page to get the next, older page; pass until to stop once a known signature is reached. An empty array means you have reached the end of the history the node keeps.
async function allSignatures(address, max = 5000) {
const out = [];
let before;
while (out.length < max) {
const params = [address, { limit: 1000, ...(before && { before }) }];
const page = await rpc('getSignaturesForAddress', params); // your POST helper
if (!page.length) break;
out.push(...page);
before = page[page.length - 1].signature;
}
return out;
}
For incremental syncs, store the newest signature you have seen and pass it as until next time. You then fetch only what is new, which keeps you well inside public rate limits.
History depth varies: not every RPC node keeps the full ledger. A public node may return a short history for an old wallet while an archival provider returns years of it. If a wallet's history looks suspiciously short, try an indexed API before concluding the account is new.
Commitment levels: processed, confirmed, finalized
Commitment tells the node how settled a block must be before it answers. The official RPC docs define three levels, and finalized is the usual default.
- processed: the node’s latest block. Fastest, but it can still be rolled back.
- confirmed: voted on by a supermajority, more than two-thirds of active stake.
- finalized: maximum lockout; the strongest guarantee.
getSignaturesForAddress accepts only confirmed or finalized. For explorer-style pages, confirmed is the common compromise: a new signature appears within a couple of slots (slots are ~250–300 ms since the Aug–Sep 2026 reductions) and rollbacks at that level are very rare. For anything that moves money or updates a database of record, wait for finalized.
Rate-limit etiquette on public endpoints
Public endpoints are shared, so behave like a polite guest. The official mainnet, devnet and testnet endpoints allow 100 requests per 10 seconds per IP, 40 per 10 seconds for any single method, and 40 concurrent connections, and are explicitly not meant for production.
Practical rules we follow in Solscanner’s own client (rpc.ts):
- Rotate, don’t hammer. Our lookup tool keeps two pools. “Light” calls (transactions, signatures, balances, blocks, epoch) go to publicnode first, then Solana Vibe Station, then the official endpoint. “Heavy” indexed calls (
getTokenAccountsByOwner,getTokenLargestAccounts,getSupply,getProgramAccounts,getTokenSupply) go to Solana Vibe Station first. Devnet and testnet use the official endpoints. - Treat rate-limit errors as “try elsewhere”. Codes such as -32005, 429 and 403, or messages mentioning limits or plans, move the request to the next endpoint instead of failing.
- Remember what worked. The last endpoint that answered becomes the first choice next time.
- Time out. Each request aborts after 14 seconds so a slow node can’t freeze the page.
- Cache and batch. Don’t refetch finalized transactions; they never change.
For market data we call Jupiter’s keyless lite-api.jup.ag for token prices and metadata (up to 100 mints per request in our client), CoinGecko as a SOL-price fallback, and DexScreener for trading pairs. DexScreener documents 60 requests per minute for token profile endpoints and 300 per minute for pair endpoints in its API reference. Our DeFi explorer guide explains what those pair numbers mean.
Solscan Pro API, Helius and other paid explorer APIs
Paid APIs are worth it when you need indexed data that plain RPC can’t give you cheaply: labelled transfers, token holder rankings, decoded DeFi activity, or years of history in a single request.
Solscan Pro API. Solscan, owned by Etherscan since January 2024, exposes its indexed data (accounts, transfers, tokens, NFTs, markets) through the Pro API. There is a free tier; the Lite plan costs $49 per month with 20 million compute units and 1,000 requests per 60 seconds, and excludes multi-endpoints, Market/price-ohlcv, Account/metadata and Account/funded_by. Higher tiers exist, but we could not verify their current prices, so check Solscan’s pricing page yourself. API plans are non-refundable.
Helius. Helius, the team behind the Orb explorer, offers a free plan with an API key: 1 million credits per month and 10 RPC requests per second at the time of writing. Its enhanced APIs return parsed, human-readable transactions, and Orb itself is powered by Helius archival data and the getTransactionsForAddress method.
Solana Beach API. Solana Beach publishes docs at solanabeach.io/docs and a GitHub repo, focused on validators and staking. It returned 502 in our tests, so verify its status first.
Common Solana API errors and what they mean
Most API failures fall into a few patterns, and the error body usually tells you which one. Read error.code and error.message before retrying anything.
HTTP 403 or 429. The endpoint is blocking or rate-limiting your IP. Back off, rotate to another endpoint, or move to a keyed plan. The official mainnet endpoint returned 403 to us from a data-centre IP, which is common for shared cloud addresses.
Error -32005 or “plan” messages. The provider does not serve that method on your tier. Indexed calls such as getTokenAccountsByOwner are the usual victims on free nodes.
CORS errors in the browser console. The endpoint works from curl but refuses requests from a web page. Every keyless endpoint in our table accepted browser requests in September 2026, which is why a static site like Solscanner can run its lookup tool without a back end. If you add a provider that needs a key, call it from a server so the key never ships to users.
A null result. For getTransaction, null usually means the signature is unknown to that node: wrong cluster, not yet at your commitment level, or outside the node’s history. Our client can retry such calls on the next endpoint before reporting “not found”.
When do you need an indexer instead of RPC?
You need an indexer when your question spans many accounts or long time ranges. RPC answers “what is this account now?” and “what did this transaction do?” well. It answers “every USDC transfer this wallet made since 2023, with USD values” badly, because you would loop through thousands of signatures and parse each one.
Signs you have outgrown raw RPC:
- You call
getTransactionhundreds of times per page view. - You need token holder counts or rankings (public nodes often block
getTokenLargestAccountsandgetProgramAccounts). - You need human labels (exchanges, programs, known wallets) or historical USD prices.
- You need history older than your node keeps.
At that point, Helius, Solscan Pro or your own indexer (a Geyser plugin feeding a database) pays for itself. If you are still prototyping, test against the devnet endpoints first, and read the program explorer guide for decoding instructions with an IDL. For a user-facing comparison of the explorers built on these APIs, see our best Solana explorers ranking.
By the Solscanner research deskUpdated · Review methodology