How to Verify a Solana RPC Provider's Enhanced APIs Before You Commit

A practical checklist and runnable Node.js script for confirming that a Solana RPC provider actually exposes the enhanced APIs your app depends on, and for separating RPC access from indexing.

The short answer: yes, several providers advertise enhanced Solana APIs, but you should not pick one from a marketing page. Instead, pick a candidate endpoint, then run a small verification script against it that checks the specific methods you need (for example getTokenAccountsByOwner, getProgramAccounts with filters, or getSignaturesForAddress), confirms the response shape, and measures latency yourself. This guide gives you that script and explains why an RPC endpoint alone will not answer historical or aggregate questions — that is an indexing job.

Step 1: Write down the exact methods you need

"Enhanced APIs" is not a standard term, so it means different things per provider. Before comparing anything, list the JSON-RPC methods your application calls and the filters or parameters it relies on. A wallet app might need getTokenAccountsByOwner and getSignaturesForAddress; an analytics dashboard might lean on getProgramAccounts with memcmp filters or getTransaction with maxSupportedTransactionVersion.

Once you have that list, you can test each candidate endpoint against it. This is faster and more honest than reading feature tables, because a method either returns a well-formed result or it does not. If you are still choosing a network to point at, the Solana network overview on OnFinality is a reasonable starting reference for endpoint options and network context.

  • List every RPC method and parameter your app depends on.
  • Note which calls are latency-sensitive versus background jobs.
  • Decide which questions are historical/aggregate — those belong to an indexer, not an RPC.

Step 2: Separate RPC access from indexing and querying

An RPC endpoint answers point queries about current or recent chain state: account data, balances, transaction details, slot height. It is not a database. If you need "all swaps for this program in the last 30 days" or "daily active wallets for this token," you are asking an indexing question, and no RPC provider will answer it efficiently with a single call.

The practical split is: use RPC for reads your UI needs right now, and use an indexer (SubQuery, or your own ingestion pipeline) for anything that requires scanning history, joining datasets, or aggregating. When you evaluate a provider, ask whether they offer both, and test them separately. The OnFinality Learn library has background material on how these layers differ if you want to go deeper before writing code.

  • RPC: single-account reads, recent transactions, current slot.
  • Indexing: history scans, aggregations, cross-account joins.
  • Do not benchmark an indexer with an RPC call, or vice versa.

Step 3: Run a verification script against the candidate endpoint

The script below takes an endpoint URL from an environment variable (never hardcode one), calls a small set of methods, and reports pass/fail plus round-trip time per call. It uses only Node.js 18+ built-ins, so there is nothing to install. Run it against each candidate and compare the output yourself — do not trust anyone else's numbers, including mine.

JavaScript · Node.js
// verify-solana-rpc.mjs — Node.js 18+
const ENDPOINT = process.env.SOLANA_RPC_URL;
if (!ENDPOINT) {
  console.error('Set SOLANA_RPC_URL to the endpoint you want to test.');
  process.exit(1);
}

const USDC_MINT = 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v';
const SYSTEM_PROGRAM = '11111111111111111111111111111111';

async function call(method, params) {
  const started = performance.now();
  const res = await fetch(ENDPOINT, {
    method: 'POST',
    headers: { 'content-type': 'application/json' },
    body: JSON.stringify({ jsonrpc: '2.0', id: 1, method, params }),
  });
  const ms = Math.round(performance.now() - started);
  if (!res.ok) throw new Error(`${method}: HTTP ${res.status}`);
  const body = await res.json();
  if (body.error) throw new Error(`${method}: ${body.error.message}`);
  return { result: body.result, ms };
}

const checks = [
  ['getHealth', []],
  ['getSlot', [{ commitment: 'confirmed' }]],
  ['getTokenAccountsByOwner', [
    '11111111111111111111111111111111',
    { mint: USDC_MINT },
    { encoding: 'jsonParsed' },
  ]],
  ['getProgramAccounts', [
    SYSTEM_PROGRAM,
    { encoding: 'base64', dataSlice: { offset: 0, length: 0 }, filters: [{ dataSize: 0 }] },
  ]],
];

for (const [method, params] of checks) {
  try {
    const { result, ms } = await call(method, params);
    const shape = Array.isArray(result) ? `array(${result.length})` : typeof result;
    console.log(`PASS ${method} ${ms}ms -> ${shape}`);
  } catch (err) {
    console.log(`FAIL ${method} -> ${err.message}`);
  }
}

Expected result: four lines starting with PASS, each showing a millisecond figure and a result type such as string or array(0). The array length will vary by account, so treat array(n) as informational, not a correctness check.

Failure handling: the script catches per-method errors so one unsupported method does not abort the run. A FAIL line usually means the method is disabled, rate-limited, or rejected the parameters — all of which are things you need to know before shipping. If every call fails with HTTP 401 or 403, the endpoint likely needs an API key; check the provider's docs rather than guessing a header name.

Step 4: Interpret results and pick your next step

Run the script several times, at different times of day, and record the median latency per method yourself. That is the only benchmark that reflects your traffic pattern. If a method you need fails consistently, that provider is not a fit regardless of what its feature list says. If it passes, you still need to confirm rate limits and whether the enhanced methods are metered differently.

If you want help narrowing candidates or translating your method list into a concrete request, the OnFinality RPC Assistant is designed for exactly that kind of question. Use it after you have your method list in hand, so the recommendation is grounded in what your app actually calls.

  • Repeat the script and record medians yourself; do not rely on published benchmarks.
  • Confirm rate limits and per-method metering in the provider's docs.
  • Re-run the script after any plan or endpoint change.