Home
How to migrate to NOWNodes

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.

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>/ or https://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:

Copied!
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:

MethodMigration
eth_chainIdDirect
eth_blockNumberDirect
eth_getBalanceDirect
eth_callDirect
eth_estimateGasDirect
eth_getLogsDirect, but check ranges
eth_getTransactionReceiptDirect
eth_sendRawTransactionDirect, but test nonce and gas behavior
debug_traceTransactionCheck NOWNodes Trace & Debug support first

GetBlock endpoints include the access token in the URL:

Copied!
https://go.getblock.io/YOUR_GETBLOCK_ACCESS_TOKEN/

NOWNodes uses a network endpoint plus the api-key header:

Copied!
https://eth.nownodes.io/
api-key: YOUR_NOWNODES_API_KEY

3. What Does Not Move Directly

Do not treat these as simple URL replacements:

GetBlock featureWhat to do instead
Archive mode endpointUse NOWNodes archive endpoint and compare behavior
Dedicated nodeUse NOWNodes Dedicated Nodes or standard RPC if enough
Dedicated archive nodeUse NOWNodes archive endpoint or dedicated archive setup
Explorer APIReplace with Blockbook, NOWNodes APIs, or another data source
Regional endpoint selectionChoose the closest NOWNodes-supported endpoint/region
Custom interface such as GraphQLReplace with matching NOWNodes interface if available, or redesign
Access-token managementMove 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.

NetworkGetBlock HTTP patternNOWNodes HTTPNOWNodes WSS
Ethereum Mainnethttps://go.getblock.io/{ACCESS_TOKEN}/https://eth.nownodes.io/wss://eth.nownodes.io/wss/{NOWNODES_API_KEY}
Ethereum SepoliaGetBlock dashboard URLhttps://eth-sepolia.nownodes.io/Check NOWNodes docs
Polygon MainnetGetBlock dashboard URLhttps://matic.nownodes.io/wss://matic.nownodes.io/wss/{NOWNODES_API_KEY}
Base MainnetGetBlock dashboard URLhttps://base.nownodes.io/wss://base.nownodes.io/wss/{NOWNODES_API_KEY}
Arbitrum OneGetBlock dashboard URLhttps://arbitrum.nownodes.io/Check NOWNodes docs
Optimism MainnetGetBlock dashboard URLhttps://optimism.nownodes.io/wss://optimism.nownodes.io/wss/{NOWNODES_API_KEY}
BNB Smart ChainGetBlock dashboard URLhttps://bsc.nownodes.io/wss://bsc.nownodes.io/wss/{NOWNODES_API_KEY}
Solana MainnetGetBlock dashboard URLhttps://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:

Copied!
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:

Copied!
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_KEY

During rollout, keep both providers:

Copied!
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_KEY

This makes rollback a configuration change.

6. Test the New RPC Endpoint

Check the current GetBlock response:

Copied!
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:

Copied!
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, or 5xx errors appear;
  • latency is acceptable.

Verify the network:

Copied!
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:

Copied!
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:

Copied!
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

Copied!
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.

Copied!
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.

Copied!
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.

Copied!
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.

Copied!
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.

Copied!
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:

Copied!
wscat -c "wss://go.getblock.io/$GETBLOCK_ACCESS_TOKEN"

NOWNodes:

Copied!
wscat -c "wss://eth.nownodes.io/wss/$NOWNODES_API_KEY"

Subscribe to new blocks:

Copied!
{"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:

Copied!
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:

Copied!
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:

Copied!
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:

Copied!
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:

  1. List every method currently used.
  2. Check NOWNodes Trace & Debug support for the same chain.
  3. Test known transaction hashes.
  4. 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 429 and 5xx.

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.

Copied!
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:

  1. Test NOWNodes locally.
  2. Move staging read requests.
  3. Compare selected production reads in shadow mode.
  4. Move 5-10% of production read traffic.
  5. Move all read traffic.
  6. Move transaction broadcasting.
  7. Move WebSocket/indexers after reconnect and backfill tests.
  8. Migrate archive/dedicated/non-RPC flows separately.

Feature flag example:

Copied!
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:

  1. Set RPC_PROVIDER=getblock.
  2. Restart affected services.
  3. Check eth_blockNumber.
  4. Check transaction broadcasting.
  5. Check indexer lag and WebSocket subscriptions.
  6. Keep the NOWNodes config until the issue is diagnosed.

14. Troubleshooting

SymptomCauseFix
401 UnauthorizedMissing or invalid api-key headerSend api-key: $NOWNODES_API_KEY
Wrong chainIdWrong network endpointUse the correct NOWNodes endpoint
Empty eth_getLogsWrong filter, old range, or archive issueCheck topics, split ranges, use archive
429 Too Many RequestsRate limit exceededAdd throttling/backoff or upgrade the plan
Archive request failsStandard endpoint used for historical stateUse archive endpoint
WSS disconnectsNetwork interruption or endpoint limitsReconnect and resubscribe automatically
Missed eventsNo backfill after reconnectBackfill with eth_getLogs
Different trace responseClient or trace implementation differsUpdate 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.