Summary
Solana RPC access uses JSON-RPC over HTTP and WebSocket. Public endpoints such as https://api.mainnet-beta.solana.com require no key but enforce changing rate limits and are intended for devnet/testnet work or low-volume testing. Production workloads should use an authenticated managed endpoint from OnFinality or another provider; you supply an API key as a header or query parameter. If the key is missing, expired, or lacks plan entitlements, requests return 401 Unauthorized or 403 Forbidden. Exceeding your plan or public limit returns 429 Too Many Requests; implement client-side throttling and exponential backoff with jitter instead of retrying immediately. Timeouts can come from node congestion or network path issues, so use bounded timeouts and one or more fallback endpoints with a circuit breaker. Stale data occurs when reads come from a lagging node or cached response; enforce a minimum confirmed commitment and check recent blockhash freshness before signing. Before moving traffic, verify the current Solana endpoints, plan limits, WebSocket support, and fallback configuration on the Solana network page. Collect request IDs, timestamps, endpoint URLs, and response bodies before contacting support.
Key Takeaways
- Public Solana endpoints are for testing; production traffic should use authenticated managed RPC.
- 401/403 indicate missing, invalid, or unauthorized API keys; 429 indicates rate limit exceeded.
- Use bounded timeouts, exponential backoff with jitter, and a fallback endpoint to stay resilient.
- Check commitment level and blockhash freshness to avoid stale reads and failed transactions.
Set Up Solana RPC Authentication
Solana RPC access uses JSON-RPC over HTTP POST and WebSocket. The public mainnet endpoint https://api.mainnet-beta.solana.com and devnet endpoint https://api.devnet.solana.com do not require an API key, but their rate limits can change and are not intended for production traffic. Managed RPC providers such as OnFinality issue authenticated endpoints where you include your API key as a request header or query parameter. The exact header name and whether WebSocket connections use the same key can vary by provider, so confirm these details on the current Solana network page /networks/solana.
OnFinality's Solana network page lists an HTTPS endpoint and a WebSocket endpoint with archive support for mainnet, and regions such as N. Virginia and Hong Kong. Verify current plan entitlements and endpoint paths before using them in code. For method-level guidance, see the Solana API guide /rpc-assistant/solana-api-guide.
- Use public https://api.mainnet-beta.solana.com only for development, CLI checks, or low-volume testing.
- For managed endpoints, store API keys in environment variables or secret managers; never commit them to source control.
- Test the authenticated endpoint with a lightweight method such as getHealth or getVersion before building the full integration.
- Confirm whether your plan includes WebSocket authentication and archive access on /networks/solana.
Troubleshoot 401 and 403 Errors
401 Unauthorized usually means the Solana RPC endpoint could not authenticate the request because the API key is missing, malformed, expired, or sent in the wrong header or query parameter. 403 Forbidden often means the key is valid but the account does not have access to the requested endpoint, region, or feature tier. Both errors require checking the request exactly as it was sent, not just the code path.
Start by reproducing the failing call with a tool like curl or Postman using the exact URL, headers, and body. Then compare it with the provider's documented authentication format. If the key has been rotated, update all consumers. For plan-level entitlements, check the current pricing page /pricing/rpc to confirm what is included in your tier.
- Verify the API key value, expiration date, and whether it belongs to the correct environment (mainnet, devnet, or testnet).
- Check the header name—common variants include Authorization, x-api-key, or a provider-specific header; do not assume.
- Confirm the endpoint path includes your key only if the provider uses URL-based authentication; some providers require header-only.
- Test a basic JSON-RPC method such as getHealth to isolate authentication issues from method-specific problems.
| Criterion | What to check | Why it matters |
|---|---|---|
| 401 Unauthorized | Missing or invalid API key, wrong header name, expired key | Authentication failures block all requests and must be fixed before other debugging. |
| 403 Forbidden | Valid key but not entitled to endpoint, region, or plan feature | Authorization errors indicate a plan or configuration mismatch rather than a code bug. |
| 429 Too Many Requests | Request volume, burst pattern, current rate limit, Retry-After header | Rate limits require client-side throttling or a plan change to avoid repeated failures. |
Handle 429 Rate Limits
429 Too Many Requests means your client exceeded the rate limit for the endpoint. Public Solana endpoints enforce changing limits that are not documented as a stable contract. Managed plans also have limits that vary by tier and can change; exact numbers should be verified in current documentation or the provider dashboard. Do not assume a fixed RPS from old examples.
When you receive a 429, stop retrying immediately. Wait for the Retry-After header if present, or apply exponential backoff with jitter. Implement client-side throttling such as a token bucket or sliding window to stay under the limit. If sustained traffic consistently hits 429, compare plan options on /pricing/rpc or isolate high-volume jobs onto a dedicated endpoint.
- Respect Retry-After when the server provides it; do not retry faster than requested.
- Add jitter to backoff delays to avoid thundering herd when many clients retry at once.
- Monitor usage dashboards to see which methods or background jobs consume the most requests.
- Separate user-facing reads from heavy indexing or analytical jobs to avoid exhausting a shared limit.
Timeouts, Retries, and Backoff
Timeouts happen when a Solana RPC node takes too long to respond, often because of node congestion, large batched requests, or network path issues between your application and the provider region. Configure explicit connect and read timeouts instead of relying on library defaults. A reasonable starting point is 5 seconds for connect and 15-30 seconds for read, but tune this to your workload and provider region.
Retry only methods that are safe to repeat. For example, getBalance, getAccountInfo, and getSlot are idempotent and can be retried with backoff. Sending a transaction is not automatically idempotent because a retry could submit the same signed transaction twice; if your transaction signature is already known, first query getSignatureStatuses before deciding to resend. Use exponential backoff with full jitter and a maximum retry limit (for example, 3-5 attempts) before failing over to a secondary endpoint.
- Set separate connect and read timeouts; avoid unbounded waits.
- Classify errors: retry on 429, 5xx, network errors; do not retry on 401 or 403.
- Use exponential backoff with jitter, such as base 200ms doubling to a cap of 5s.
- Implement a fallback endpoint with a circuit breaker that opens after repeated failures and half-opens for probing.
- For transaction submissions, always check getSignatureStatuses before resending to avoid duplicates.
Stale Data and Fallback Behavior
Stale data occurs when your RPC read comes from a node that is behind the tip, or when a provider returns cached data with a lagging commitment. For transaction submission, always fetch a recent blockhash with getLatestBlockhash and use the returned blockhash; do not reuse an old one. For account and program reads, set the commitment parameter to at least confirmed, or finalized if your application cannot tolerate rollback.
Fallback behavior should preserve the same cluster and commitment semantics. If your primary mainnet endpoint fails, fail over to a secondary mainnet endpoint from the same or another provider—never to devnet. Test fallback paths on devnet first, using test SOL from the official faucet https://faucet.solana.com. Compare providers and endpoint strategies in /rpc-assistant/best-solana-rpc-provider. To verify current HTTP and WebSocket endpoints for OnFinality, including archive support and regions such as N. Virginia and Hong Kong, check /networks/solana.
- Use getLatestBlockhash and ensure the blockhash is no older than a few seconds before signing.
- Set commitment to confirmed or finalized for balance and account reads; avoid processed for user-facing data.
- Keep fallback endpoints in the same network (mainnet-beta to mainnet-beta).
- Log primary and fallback latency and block heights to detect a lagging node before it causes errors.
Production Access Checklist
Use this checklist before putting production traffic on a Solana RPC endpoint. It covers the access and error-handling concerns from the sections above.
| Criterion | What to check | Why it matters |
|---|---|---|
| Authentication | API key present in header or query, key rotation process, secret storage | Prevents 401/403 outages and limits exposure if a key leaks. |
| Rate limits | Plan limits, burst allowance, Retry-After handling, throttling library | Avoids 429 storms and degraded user experience during traffic spikes. |
| Timeouts and retries | Connect/read timeouts, retry policy, jitter, circuit breaker | Keeps the app responsive when a node is slow or unreachable. |
| Data freshness | Commitment level, blockhash freshness, getSlot comparison against provider tip | Reduces risk of failed sends or reading stale balances. |
| Fallback | Secondary endpoint in same cluster, failover trigger, automatic recovery | Maintains availability during provider or node outages. |
| Monitoring and logging | Request latency, error rate by status code, method-level usage, request IDs | Enables fast diagnosis and capacity planning before users report problems. |
What to Collect Before Contacting Support
Support teams can resolve Solana RPC access issues faster when you provide complete request-level context. Collect the following information before opening a ticket.
- UTC timestamp and time zone of the failed requests, including multiple attempts if available.
- Exact endpoint URL used, including host, path, and query string (redact only the API key if necessary).
- HTTP status code and full JSON-RPC error response body; do not truncate error messages.
- Request method and parameters, sanitized to remove private keys or wallet addresses if not necessary.
- Client library and version (for example, @solana/web3.js 1.87.1) plus connection settings like commitment.
- Rate limit headers or usage dashboard screenshot showing the request count around the failure.
- Network region from which your application connects (for example, AWS us-east-1) and the provider region used.
- Steps to reproduce the issue with a minimal script or curl command.
Frequently Asked Questions
How do I authenticate Solana WebSocket connections?
Authentication for Solana WebSocket endpoints typically uses the same API key as HTTP, either in the URL query string or an initial WebSocket header, depending on the provider. Check the OnFinality Solana network page /networks/solana for the current WebSocket URL format and authentication method. If the key is missing, you will usually see the WebSocket connection rejected before any subscription messages.
Does a 403 error always mean my API key is wrong?
No. A 403 can also mean the API key is valid but your plan does not include the requested endpoint, region, archive depth, or WebSocket feature. Verify the key against a simple method like getHealth, then compare your plan entitlements on /pricing/rpc before rotating the key.
What backoff strategy should I use for 429 rate limit responses?
Start with a small base delay, such as 200-500ms, double it on each subsequent 429, add random jitter, and cap the delay at a reasonable maximum like 5-10 seconds. Stop retries after 3-5 attempts or respect the Retry-After header if present. Persistent 429s indicate you need client-side throttling or a higher plan.
How can I detect stale data before submitting a transaction?
Call getLatestBlockhash right before constructing the transaction and submit immediately. After sending, query getSignatureStatuses and confirm the transaction reached a confirmed or finalized commitment. If the blockhash is more than a few seconds old, the transaction may be rejected with a blockhash not found error.
How can I test fallback behavior safely?
Use Solana Devnet with test SOL from the official faucet at https://faucet.solana.com. Configure two devnet endpoints in your application and simulate the primary failing by using an unreachable host or a timeout. Verify that the fallback receives the same method calls and that no devnet-to-mainnet crossover occurs.