DEV Community

OnFinality
OnFinality

Posted on Originally published at onfinality.io

Polygon RPC API: Endpoint Settings & Debugging

The Polygon RPC API is the JSON-RPC surface your application uses to read Polygon PoS state and broadcast transactions. If you are wiring up a wallet, a backend indexer, or a dApp frontend, you need three things: the correct chain settings, a working request pattern, and a clear idea of which failures are your code versus the endpoint. This page gives you all three, then helps you decide whether a shared public endpoint or a dedicated Polygon node fits your workload.

Chain settings at a glance

Before you send a single request, confirm the network parameters. Polygon PoS mainnet and Polygon Amoy testnet use different chain IDs and different native currency symbols, and mixing them up is one of the most common setup mistakes.

Setting Polygon mainnet Polygon Amoy testnet
Chain ID 137 80002
Chain name Polygon Mainnet Amoy
Native currency POL (18 decimals) POL (18 decimals)
Block explorer polygonscan.com amoy.polygonscan.com
Transport HTTP, WebSocket HTTP, WebSocket
Example endpoint https://polygon.api.onfinality.io/public https://polygon-amoy.api.onfinality.io/public

Those public endpoints are useful for quick tests and low-volume reads. For production traffic, rate limits and shared capacity apply, so most teams move to a managed or dedicated endpoint. You can review the full Polygon RPC network page for supported transports and current access options.

If you are adding Polygon to a wallet or a frontend network switcher, the configuration usually looks like this:

const polygonMainnet = {
  chainId: '0x89', // 137
  chainName: 'Polygon Mainnet',
  nativeCurrency: { name: 'POL', symbol: 'POL', decimals: 18 },
  rpcUrls: ['https://polygon.api.onfinality.io/public'],
  blockExplorerUrls: ['https://polygonscan.com'],
};
Enter fullscreen mode Exit fullscreen mode

How to decide: public endpoint or dedicated node

The decision is usually about workload shape, not about which endpoint is "better" in the abstract. Use the table below to place your own traffic pattern.

Your workload Shared public endpoint Managed RPC API Dedicated Polygon node
Wallet reads, occasional eth_call Fine for testing Good fit Overkill
dApp frontend with steady user traffic Rate limits become visible Good fit Consider at high volume
Backend indexer scanning eth_getLogs Not suitable Possible with tuned ranges Strong fit
High-frequency trading or bots Not suitable Possible Strong fit
Archive queries over old blocks Not available Depends on plan Strong fit
Debug/trace calls Not available Depends on plan Strong fit

A practical rule: if your app can tolerate occasional 429 responses and you only read recent state, a shared endpoint is enough. If you depend on log queries, historical state, trace calls, or predictable throughput, plan for a managed or dedicated setup. OnFinality offers both managed RPC API access and dedicated nodes for teams that need isolated capacity.

Sending your first Polygon JSON-RPC request

Every Polygon RPC call follows the same JSON-RPC 2.0 envelope. Start with a simple health check to confirm the endpoint is reachable and returning the expected chain.

curl -s https://polygon.api.onfinality.io/public \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"eth_chainId","params":[]}'
Enter fullscreen mode Exit fullscreen mode

A correct response returns the chain ID as a hex string:

{"jsonrpc":"2.0","id":1,"result":"0x89"}
Enter fullscreen mode Exit fullscreen mode

If you get 0x89, you are on Polygon mainnet. If you get 0x13882, you are on Amoy testnet (80002). If you get a different value entirely, your endpoint is pointing at another network.

Reading a balance follows the same shape:

curl -s https://polygon.api.onfinality.io/public \
  -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":2,"method":"eth_getBalance","params":["0x0000000000000000000000000000000000001010","latest"]}'
Enter fullscreen mode Exit fullscreen mode

In JavaScript, the same call through ethers looks like this:

import { JsonRpcProvider } from 'ethers';

const provider = new JsonRpcProvider('https://polygon.api.onfinality.io/public');
const block = await provider.getBlockNumber();
const balance = await provider.getBalance('0x0000000000000000000000000000000000001010');
console.log({ block, balance: balance.toString() });
Enter fullscreen mode Exit fullscreen mode

Polygon RPC methods you will actually use

Polygon PoS is EVM-compatible, so the method set matches Ethereum. The methods below cover most production traffic.

Method Purpose Notes
eth_chainId Identify the network Use as a startup health check
eth_blockNumber Latest block height Cheap and safe to poll
eth_getBalance Account balance Returns hex wei
eth_call Read contract state No gas, no state change
eth_getLogs Query event logs Range limits apply on shared endpoints
eth_getTransactionReceipt Confirm a transaction Poll after broadcast
eth_sendRawTransaction Broadcast a signed tx Requires a funded signer
eth_getCode Check contract deployment Useful for address validation

Two Polygon-specific details are worth remembering. First, the native gas token is POL, and the well-known fee address 0x0000000000000000000000000000000000001010 is used in gas accounting. Second, because Polygon PoS has had reorgs and state-sync delays historically, backends that index logs should track confirmations rather than assuming a block is final the moment it appears.

WebSocket subscriptions for live data

If you need push updates instead of polling, connect over WebSocket. The OnFinality Polygon endpoint supports both HTTP and WebSocket transport.

import WebSocket from 'ws';

const ws = new WebSocket('wss://polygon.api.onfinality.io/public/ws');

ws.on('open', () => {
  ws.send(JSON.stringify({
    jsonrpc: '2.0',
    id: 1,
    method: 'eth_subscribe',
    params: ['newHeads'],
  }));
});

ws.on('message', (data) => {
  const msg = JSON.parse(data.toString());
  if (msg.method === 'eth_subscription') {
    console.log('New head:', msg.params.result.number);
  }
});
Enter fullscreen mode Exit fullscreen mode

WebSocket connections are stateful. If your process restarts or the socket drops, you must resubscribe. Build reconnect logic with backoff, and re-fetch the latest block on reconnect so you do not miss events during the gap.

Debug path: common Polygon RPC failures

When a request fails, the error message usually points at the cause. Use this table to move from symptom to fix.

Symptom Likely cause Next step
429 Too Many Requests Shared endpoint rate limit Reduce polling, batch calls, or move to a managed plan
eth_getLogs returns range error Query window too wide Split into smaller block ranges
eth_call reverts with no reason Contract reverted or wrong ABI Simulate with eth_call and check inputs
Transaction stuck pending Gas price too low for current conditions Re-estimate gas and consider replacement
nonce too low Local nonce out of sync Resync nonce from eth_getTransactionCount
Missing trie node Archive data not available Use an archive-capable endpoint
WebSocket closes silently Idle timeout or network drop Add heartbeat and reconnect logic

A quick diagnostic loop for a failing endpoint:

# 1. Is the endpoint alive and on the right chain?
curl -s https://polygon.api.onfinality.io/public -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"eth_chainId","params":[]}'

# 2. Is it synced to the head?
curl -s https://polygon.api.onfinality.io/public -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":2,"method":"eth_blockNumber","params":[]}'
Enter fullscreen mode Exit fullscreen mode

If eth_chainId is correct but eth_blockNumber lags behind a public block explorer, the node may be catching up. If both succeed but your app still fails, the problem is likely in your request payload, ABI, or nonce handling rather than the endpoint.

Production readiness checklist

Before you point real traffic at any Polygon endpoint, confirm these items:

  • Chain ID and native currency match the network you intend to use (137 for mainnet, 80002 for Amoy).
  • You have a fallback endpoint or provider in case the primary becomes unavailable.
  • Log queries are chunked into ranges the endpoint accepts.
  • WebSocket clients implement reconnect and resubscribe.
  • You monitor error rates, latency, and block height lag rather than only checking uptime.
  • Archive and trace needs are confirmed with your provider before launch, not after.

A simple monitoring probe keeps you ahead of outages:

async function probe(url) {
  const start = Date.now();
  const res = await fetch(url, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ jsonrpc: '2.0', id: 1, method: 'eth_blockNumber', params: [] }),
  });
  const json = await res.json();
  return { ok: res.ok, latencyMs: Date.now() - start, block: parseInt(json.result, 16) };
}
Enter fullscreen mode Exit fullscreen mode

Run this on a schedule and alert when latency rises or the block height stops advancing.

Where OnFinality fits

OnFinality provides RPC API access and dedicated node infrastructure for Polygon and many other networks. For quick tests, the public endpoints above are enough. For production apps that need predictable throughput, archive access, or isolated capacity, a managed or dedicated setup removes the shared-endpoint constraints. You can compare plans on the RPC pricing page and browse other chains on the supported RPC networks list. If you are still weighing providers, the RPC provider selection guide walks through the evaluation criteria that matter most.

Key Takeaways

  • Polygon mainnet uses chain ID 137 and POL as the native currency; Amoy testnet uses 80002.
  • The Polygon RPC API is EVM-compatible, so standard Ethereum JSON-RPC methods apply.
  • Public endpoints are fine for testing and light reads, but log queries, archive data, and high throughput usually need a managed or dedicated endpoint.
  • Most failures trace back to rate limits, log range limits, nonce sync, or missing archive data, and each has a specific fix.
  • Monitor latency and block height lag, not just uptime, and always keep a fallback endpoint.

Frequently Asked Questions

What is the Polygon RPC API?

It is the JSON-RPC interface that lets your application read Polygon PoS state and submit transactions through a node. It follows the JSON-RPC 2.0 standard and supports the same method set as Ethereum because Polygon PoS is EVM-compatible.

What is the Polygon chain ID?

Polygon mainnet uses chain ID 137 (0x89). Polygon Amoy testnet uses chain ID 80002 (0x13882). Always confirm the chain ID with eth_chainId before sending transactions.

Does Polygon RPC support WebSocket?

Yes. The OnFinality Polygon endpoint supports both HTTP and WebSocket transport, which lets you subscribe to newHeads, logs, and other events instead of polling.

Why does eth_getLogs fail on Polygon?

Most log query failures come from requesting too wide a block range. Shared endpoints limit the range to protect capacity. Split your query into smaller windows or use a provider that supports wider ranges.

Can I use a public Polygon RPC endpoint in production?

You can, but shared public endpoints apply rate limits and may not offer archive or trace data. For production traffic, a managed or dedicated endpoint gives you more predictable behavior.

How do I get testnet POL for Amoy?

Use a Polygon Amoy faucet to request testnet POL for development. The Amoy network uses the same POL token symbol as mainnet but on a separate chain, so testnet funds have no mainnet value.

Related resources

Originally published at OnFinality.

Top comments (0)