Migrating from GetBlock to NOWNodes
This tutorial shows how to move RPC traffic from GetBlock to NOWNodes. Standard JSON-RPC requests usually need only a new endpoint and a new authentication method. GetBlock-specific setup, such as archive mode, dedicated nodes, REST-style products, regional endpoints, and access-token management, should be reviewed separately.
1. Start with a Quick Audit
Before changing code, check what your app currently uses in GetBlock.
Look for:
- HTTP RPC endpoints like
https://go.getblock.io/<ACCESS_TOKEN>/; - regional endpoints like
https://go.getblock.us/<ACCESS_TOKEN>/orhttps://go.getblock.asia/<ACCESS_TOKEN>/; - WSS endpoints like
wss://go.getblock.us/<ACCESS_TOKEN>; - standard JSON-RPC methods:
eth_blockNumber,eth_getBalance,eth_call,eth_getLogs,eth_sendRawTransaction; - archive mode endpoints;
- dedicated node endpoints;
- debug/trace methods;
- Explorer API or other non-RPC APIs;
- current Compute Unit usage, RPS, errors, and alerts.
Search your codebase for:
getblock.io
getblock.us
getblock.asia
GETBLOCK
ACCESS_TOKEN
go.getblock
debug_trace
trace_The important split: standard RPC can move first; archive, dedicated, and non-RPC GetBlock features need separate checks.
2. What Moves Directly
These standard methods can usually be sent to NOWNodes without changing the JSON-RPC body:
| Method | Migration |
|---|---|
eth_chainId | Direct |
eth_blockNumber | Direct |
eth_getBalance | Direct |
eth_call | Direct |
eth_estimateGas | Direct |
eth_getLogs | Direct, but check ranges |
eth_getTransactionReceipt | Direct |
eth_sendRawTransaction | Direct, but test nonce and gas behavior |
debug_traceTransaction | Check NOWNodes Trace & Debug support first |
GetBlock endpoints include the access token in the URL:
https://go.getblock.io/YOUR_GETBLOCK_ACCESS_TOKEN/NOWNodes uses a network endpoint plus the api-key header:
https://eth.nownodes.io/
api-key: YOUR_NOWNODES_API_KEY3. What Does Not Move Directly
Do not treat these as simple URL replacements:
| GetBlock feature | What to do instead |
|---|---|
| Archive mode endpoint | Use NOWNodes archive endpoint and compare behavior |
| Dedicated node | Use NOWNodes Dedicated Nodes or standard RPC if enough |
| Dedicated archive node | Use NOWNodes archive endpoint or dedicated archive setup |
| Explorer API | Replace with Blockbook, NOWNodes APIs, or another data source |
| Regional endpoint selection | Choose the closest NOWNodes-supported endpoint/region |
| Custom interface such as GraphQL | Replace with matching NOWNodes interface if available, or redesign |
| Access-token management | Move secrets to NOWNODES_API_KEY and rotate old tokens after rollout |
Move standard RPC first. Keep GetBlock archive/dedicated/non-RPC flows as temporary fallback until each replacement is tested.
4. Endpoint Mapping
Use the NOWNodes endpoint for the same network.
| Network | GetBlock HTTP pattern | NOWNodes HTTP | NOWNodes WSS |
|---|---|---|---|
| Ethereum Mainnet | https://go.getblock.io/{ACCESS_TOKEN}/ | https://eth.nownodes.io/ | wss://eth.nownodes.io/wss/{NOWNODES_API_KEY} |
| Ethereum Sepolia | GetBlock dashboard URL | https://eth-sepolia.nownodes.io/ | Check NOWNodes docs |
| Polygon Mainnet | GetBlock dashboard URL | https://matic.nownodes.io/ | wss://matic.nownodes.io/wss/{NOWNODES_API_KEY} |
| Base Mainnet | GetBlock dashboard URL | https://base.nownodes.io/ | wss://base.nownodes.io/wss/{NOWNODES_API_KEY} |
| Arbitrum One | GetBlock dashboard URL | https://arbitrum.nownodes.io/ | Check NOWNodes docs |
| Optimism Mainnet | GetBlock dashboard URL | https://optimism.nownodes.io/ | wss://optimism.nownodes.io/wss/{NOWNODES_API_KEY} |
| BNB Smart Chain | GetBlock dashboard URL | https://bsc.nownodes.io/ | wss://bsc.nownodes.io/wss/{NOWNODES_API_KEY} |
| Solana Mainnet | GetBlock dashboard URL | https://sol.nownodes.io/ | wss://sol.nownodes.io/wss/{NOWNODES_API_KEY} |
Always verify the network with eth_chainId or the chain-specific equivalent before sending production traffic.
5. Configure Environment Variables
Before:
GETBLOCK_ETH_RPC_URL=https://go.getblock.io/YOUR_GETBLOCK_ACCESS_TOKEN/
GETBLOCK_ETH_WSS_URL=wss://go.getblock.io/YOUR_GETBLOCK_ACCESS_TOKEN/After:
NOWNODES_ETH_RPC_URL=https://eth.nownodes.io/
NOWNODES_ETH_WSS_URL=wss://eth.nownodes.io/wss/YOUR_NOWNODES_API_KEY
NOWNODES_API_KEY=YOUR_NOWNODES_API_KEYDuring rollout, keep both providers:
RPC_PROVIDER=nownodes
GETBLOCK_ETH_RPC_URL=https://go.getblock.io/YOUR_GETBLOCK_ACCESS_TOKEN/
NOWNODES_ETH_RPC_URL=https://eth.nownodes.io/
NOWNODES_API_KEY=YOUR_NOWNODES_API_KEYThis makes rollback a configuration change.
6. Test the New RPC Endpoint
Check the current GetBlock response:
curl "https://go.getblock.io/$GETBLOCK_ACCESS_TOKEN/" \
-X POST \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":"getblock-check"}'Run the same request through NOWNodes:
curl "https://eth.nownodes.io/" \
-X POST \
-H "api-key: $NOWNODES_API_KEY" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"eth_blockNumber","params":[],"id":"nownodes-check"}'Check:
- both responses return
result; - NOWNodes is close to GetBlock by block number;
- no
401,403,429, or5xxerrors appear; - latency is acceptable.
Verify the network:
curl "https://eth.nownodes.io/" \
-X POST \
-H "api-key: $NOWNODES_API_KEY" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","method":"eth_chainId","params":[],"id":1}'For Ethereum Mainnet, the expected result is 0x1.
7. Update Application Code
Direct fetch
Before:
const response = await fetch(process.env.GETBLOCK_ETH_RPC_URL, {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
jsonrpc: "2.0",
method: "eth_getBalance",
params: [address, "latest"],
id: 1
})
});After:
const response = await fetch(process.env.NOWNODES_ETH_RPC_URL, {
method: "POST",
headers: {
"api-key": process.env.NOWNODES_API_KEY,
"Content-Type": "application/json"
},
body: JSON.stringify({
jsonrpc: "2.0",
method: "eth_getBalance",
params: [address, "latest"],
id: 1
})
});viem
import { createPublicClient, http } from "viem";
import { mainnet } from "viem/chains";
export const client = createPublicClient({
chain: mainnet,
transport: http(process.env.NOWNODES_ETH_RPC_URL, {
fetchOptions: {
headers: {
"api-key": process.env.NOWNODES_API_KEY
}
}
})
});Small RPC Wrapper
Use a wrapper if your library does not pass custom headers cleanly.
export async function rpc(method, params = []) {
const response = await fetch(process.env.NOWNODES_ETH_RPC_URL, {
method: "POST",
headers: {
"api-key": process.env.NOWNODES_API_KEY,
"Content-Type": "application/json"
},
body: JSON.stringify({
jsonrpc: "2.0",
id: Date.now(),
method,
params
})
});
if (!response.ok) {
const error = new Error(`RPC HTTP error: ${response.status}`);
error.status = response.status;
throw error;
}
const payload = await response.json();
if (payload.error) {
const error = new Error(payload.error.message);
error.status = 200;
error.code = payload.error.code;
throw error;
}
return payload.result;
}8. Migrate Common Flows
Balances
Use the same eth_getBalance body and change only endpoint/auth.
curl "https://eth.nownodes.io/" \
-X POST \
-H "api-key: $NOWNODES_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "eth_getBalance",
"params": ["0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045", "latest"],
"id": 1
}'Check that the result is hex wei and the UI still formats it correctly.
Contract Reads
Use the same eth_call body. If the call targets an old block, use archive access.
curl "https://eth.nownodes.io/" \
-X POST \
-H "api-key: $NOWNODES_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "eth_call",
"params": [
{
"to": "0x0000000000000000000000000000000000000000",
"data": "0x"
},
"latest"
],
"id": 1
}'Check ABI decoding and revert handling.
Transaction Broadcasting
Use the same eth_sendRawTransaction body.
curl "https://eth.nownodes.io/" \
-X POST \
-H "api-key: $NOWNODES_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "eth_sendRawTransaction",
"params": ["0xSIGNED_TRANSACTION"],
"id": 1
}'Before production transactions, check chainId, nonce, fee settings, and retry behavior.
Event Indexing
Use eth_getLogs, but avoid huge block ranges.
curl "https://eth.nownodes.io/" \
-X POST \
-H "api-key: $NOWNODES_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "eth_getLogs",
"params": [
{
"fromBlock": "0x12D687",
"toBlock": "latest",
"address": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48",
"topics": [
"0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"
]
}
],
"id": 1
}'Use checkpoints and split large ranges into smaller chunks. After WebSocket reconnects, backfill missed blocks with eth_getLogs.
9. Move WebSocket Subscriptions
GetBlock:
wscat -c "wss://go.getblock.io/$GETBLOCK_ACCESS_TOKEN"NOWNodes:
wscat -c "wss://eth.nownodes.io/wss/$NOWNODES_API_KEY"Subscribe to new blocks:
{"jsonrpc":"2.0","id":1,"method":"eth_subscribe","params":["newHeads"]}Check connection, subscription id, reconnect, resubscribe, and backfill.
10. Replace GetBlock-Specific Setup
Archive Mode
GetBlock supports archive mode on shared endpoints for supported networks and dedicated archive nodes. In NOWNodes, use the matching archive endpoint or dedicated setup.
Ethereum archive endpoint example:
https://eth-archive.nownodes.io/Keep archive traffic separate from regular latest-state traffic where possible.
Dedicated Nodes
If your GetBlock setup uses dedicated nodes, check why:
- high throughput;
- archive access;
- preferred region;
- preferred node client;
- custom performance requirements;
- strict isolation.
If those requirements still apply, use NOWNodes Dedicated Nodes or keep a dedicated fallback until the new setup is validated.
Explorer or Non-RPC APIs
Explorer API and other product APIs are not standard node RPC.
For each API, record:
- endpoint or method used;
- response fields your app reads;
- replacement source;
- parser changes;
- fallback plan.
Solana RPC
GetBlock:
curl "https://go.getblock.io/$GETBLOCK_ACCESS_TOKEN/" \
-X POST \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "getBalance",
"params": ["83astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDLVcri"]
}'NOWNodes:
curl "https://sol.nownodes.io/" \
-X POST \
-H "api-key: $NOWNODES_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "getBalance",
"params": ["83astBRguLMdt2h5U1Tpdq5tjFoJ6noeGwaY3mDLVcri"]
}'Check commitment settings and WSS subscriptions separately.
11. Archive, Trace, and Debug
Use archive access when the app reads old block state, runs historical eth_call, or indexes old ranges.
Historical balance example:
curl "https://eth-archive.nownodes.io/" \
-X POST \
-H "api-key: $NOWNODES_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "eth_getBalance",
"params": ["0xd8dA6BF26964aF9D7eEd9e03E53415D37aA96045", "0xA00000"],
"id": 1
}'For trace/debug:
- List every method currently used.
- Check NOWNodes Trace & Debug support for the same chain.
- Test known transaction hashes.
- Compare response fields before switching parsers.
12. Retries and Rate Limits
GetBlock shared nodes use plan-based request and Compute Unit limits. Dedicated nodes are limited by the allocated hardware and configuration. NOWNodes limits depend on the selected plan.
Before rollout:
- check GetBlock usage for the last 30 days;
- identify heavy calls such as
eth_getLogs, archive calls, debug methods, and batch requests; - add 30-50% headroom above peak usage;
- split large log ranges;
- add retry with backoff for read requests;
- add alerts for
429and5xx.
fn must throw errors with status or code fields. withRetry does not inspect HTTP responses directly. If fn uses fetch, check response.ok inside fn and throw a normalized error before returning the parsed JSON.
async function withRetry(fn, options = {}) {
const maxAttempts = options.maxAttempts ?? 5;
const baseDelayMs = options.baseDelayMs ?? 500;
const maxDelayMs = options.maxDelayMs ?? 8000;
let lastError;
for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
try {
return await fn();
} catch (error) {
lastError = error;
const retryable =
error.status === 429 ||
error.status >= 500 ||
error.code === "ETIMEDOUT" ||
error.code === "ECONNRESET";
if (!retryable || attempt === maxAttempts) {
throw error;
}
const jitter = Math.floor(Math.random() * 250);
const delay = Math.min(baseDelayMs * 2 ** (attempt - 1) + jitter, maxDelayMs);
await new Promise((resolve) => setTimeout(resolve, delay));
}
}
throw lastError;
}For eth_sendRawTransaction, retry carefully. Check transaction hash, nonce, and receipt before sending again.
13. Production Rollout
Use a phased rollout:
- Test NOWNodes locally.
- Move staging read requests.
- Compare selected production reads in shadow mode.
- Move 5-10% of production read traffic.
- Move all read traffic.
- Move transaction broadcasting.
- Move WebSocket/indexers after reconnect and backfill tests.
- Migrate archive/dedicated/non-RPC flows separately.
Feature flag example:
const provider = process.env.RPC_PROVIDER;
const rpcConfig =
provider === "nownodes"
? {
url: process.env.NOWNODES_ETH_RPC_URL,
headers: {
"api-key": process.env.NOWNODES_API_KEY
}
}
: {
url: process.env.GETBLOCK_ETH_RPC_URL,
headers: {
"Content-Type": "application/json"
}
};Rollback:
- Set
RPC_PROVIDER=getblock. - Restart affected services.
- Check
eth_blockNumber. - Check transaction broadcasting.
- Check indexer lag and WebSocket subscriptions.
- Keep the NOWNodes config until the issue is diagnosed.
14. Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
401 Unauthorized | Missing or invalid api-key header | Send api-key: $NOWNODES_API_KEY |
Wrong chainId | Wrong network endpoint | Use the correct NOWNodes endpoint |
Empty eth_getLogs | Wrong filter, old range, or archive issue | Check topics, split ranges, use archive |
429 Too Many Requests | Rate limit exceeded | Add throttling/backoff or upgrade the plan |
| Archive request fails | Standard endpoint used for historical state | Use archive endpoint |
| WSS disconnects | Network interruption or endpoint limits | Reconnect and resubscribe automatically |
| Missed events | No backfill after reconnect | Backfill with eth_getLogs |
| Different trace response | Client or trace implementation differs | Update parser and tests |
15. Final Checklist
Before removing GetBlock fallback, confirm:
- RPC and WSS work via NOWNodes, including broadcasting, reconnect, and backfill.
- On-chain data is intact: balances, logs, contract reads, transaction history, and indexer events.
- GetBlock-specific archive, dedicated, and non-RPC features are replaced or have a tested fallback.
- Monitoring is stable and rollback has been tested.
- NOWNodes API key is secured; revoke unused GetBlock access tokens after the observation period.