Polygon Webhooks: Get Real-Time On-Chain Events Without Polling
How Polygon webhooks work, what to watch for on PoS (reorgs, confirmations, duplicates), and how to build a safe, idempotent deposit handler for USDC and POL.

Polygon webhooks are HTTP callbacks that a service sends to your server when something happens on the Polygon chain, such as a USDC deposit landing at one of your addresses. You register a URL, the provider watches the chain, and your backend gets a signed POST instead of hammering an RPC node every few seconds. This guide covers how that works on Polygon PoS, what can go wrong, and how to build a handler you can trust with money.
TL;DR
- A webhook replaces polling: the provider watches Polygon and pushes events (deposits, transfers, token movements) to your endpoint.
- Polygon blocks arrive roughly every 2 seconds, so events are fast, but you still need a confirmation policy before crediting funds.
- Treat every delivery as possibly duplicated, late or out of order: verify the signature, store the event ID, and process idempotently.
- Acknowledge fast, do the work in a queue, and reconcile against the chain on a schedule.
- Chaingateway Webhooks deliver HMAC-signed, pre-decoded Polygon events, so you skip running nodes and parsing logs.
Table of Contents
- What a Polygon webhook actually is
- Why webhooks beat polling on Polygon
- Confirmations, finality and reorgs on Polygon PoS
- What a safe Polygon webhook handler looks like
- Tokens and edge cases on Polygon
- Build it yourself or use a unified API
- Our perspective: webhooks are a ledger problem, not a notification problem
- Getting Polygon webhooks with Chaingateway
- A launch checklist
- FAQ
- Sources
What a Polygon webhook actually is
Polygon PoS is an EVM chain. Every ERC-20 transfer, whether USDC, USDT or a token you issued yourself, emits a Transfer log. Native POL moves as a plain value transfer with no log at all. Raw RPC gives you both in different shapes: logs for tokens, transaction and trace data for native coins. If you want to know that a customer paid, you have to assemble that picture yourself.
A webhook service does the assembly. You subscribe to an address (or a set of them), and when a matching event occurs the service sends a JSON payload to your URL. A good payload tells you the chain, the transaction hash, sender, recipient, token, amount in human units, block number and a unique event identifier. That is the difference between “here is a log with hex topics” and “customer 4812 paid 250 USDC”.
Three things people search for under this keyword are really three different tools:
- Address and payment webhooks: notify me when funds hit these addresses. This is what payment flows need.
- Contract event webhooks: notify me when a given smart contract emits a given event. This is what dApp backends and analytics need.
- Protocol-level webhooks: notifications from a Polygon product itself about its own operations. Those belong to that product’s documentation, not to a general chain listener.
This article is about the first kind, with notes on the second.
Why webhooks beat polling on Polygon
Polygon produces a block about every two seconds, according to this confirmation-time reference. If you poll an RPC endpoint for new blocks and filter logs yourself, you face a trade-off with no good answer:
- Poll every few seconds and you burn through rate limits and pay for mostly empty responses.
- Poll every minute and your customer stares at a spinner for a minute after paying.
- Miss a range after a restart and you have a silent gap in your ledger.
Webhooks flip this. The provider carries the watching, the retries and the block bookkeeping. Your job shrinks to running one endpoint that handles events correctly. We go deeper on the architecture trade-offs in our post on webhooks vs WebSockets, including the ingest, queue and fan-out pattern we recommend.
Confirmations, finality and reorgs on Polygon PoS
A webhook that fires on first sight of a transaction is fast. It is not final. Before you release goods or credit a balance, decide how many blocks you wait.
Polygon PoS confirms quickly. One tracker puts typical first confirmation at 1 to 5 seconds, and notes that exchanges commonly wait for 128 blocks, roughly 4 to 5 minutes, to guard against reorganizations. Another source reports that the Heimdall v2 upgrade in July 2025 reduced hard finality to about 5 seconds. Practices differ between exchanges and tools, and network upgrades change the numbers, so check current Polygon documentation before you fix a threshold in production.
A practical way to choose is to tie the policy to the value at risk:
| Payment size | Suggested handling | Reasoning |
|---|---|---|
| Small (digital goods, tips) | Credit on first event, mark as “pending” | Fast UX, low loss if a rare reorg happens |
| Medium (subscriptions, top-ups) | Credit after a modest block depth | Balanced |
| Large (invoices, withdrawals) | Credit after a deep threshold, such as the exchange-style 128 blocks | Reorg risk matters more than speed |
This table is our suggested policy, not a Polygon rule. Pick numbers that match your own risk tolerance and write them down.
In your data model, give each incoming payment a status such as detected, confirming and final. Show the customer the first state immediately and move funds only on the last. If your provider sends separate events as confirmations accumulate, use them. If not, store the block number from the first event and compare it with the chain head on a timer.
What a safe Polygon webhook handler looks like
The Polygon developer docs include a guide on receiving webhooks for one of their own products, and the principles it teaches apply to every webhook integration: verify the delivery, and apply it without double-processing or applying stale state. Here is the same discipline for chain events.
1. Verify the signature before anything else
Anyone who finds your URL can POST to it. Without verification, an attacker can send a fake “250 USDC received” and walk away with your product. Reject unsigned or badly signed requests with a 401 and do not parse the body further.
Chaingateway signs requests with HMAC. You compute the signature over the raw request body with your shared secret and compare it using a constant-time comparison. Use the raw bytes, not a re-serialized JSON object, because re-serialization changes whitespace and key order and breaks the match. Our post on a new feature to enhance webhook security explains the verification options in detail.
For the wider picture of protecting keys, endpoints and operational processes around digital assets, this overview of digital asset security and risk management is a useful read for the non-code side of the problem.
2. Make processing idempotent
Assume at-least-once delivery. A timeout on your side makes the sender retry, and a retry can arrive after you already processed the first copy. Store a unique key per event, ideally the transaction hash plus log index, or the event ID the provider supplies. Put a unique constraint on it in your database:
INSERT INTO processed_events (event_key, received_at)VALUES ($1, now())ON CONFLICT (event_key) DO NOTHING;If the insert affects zero rows, you have seen this event. Return 200 and stop. Do the insert and the balance update in the same database transaction so a crash cannot leave one without the other.
3. Acknowledge fast, work later
Return a 2xx as soon as the event is verified and safely stored. Do the slow work, such as emailing the customer, updating ledgers and calling other services, from a queue. If your handler takes thirty seconds, the sender will time out and retry, and you will be debugging duplicates.
4. Do not trust order
Two events about the same payment can arrive in either order, for example a confirmation update before the original detection. Compare block numbers or sequence fields and ignore anything older than the state you already hold. Never let a late “detected” event overwrite a “final” record.
5. Validate what the payload claims
Check that the recipient is an address you issued, that the token contract is one you accept, and that the amount matches the invoice. This matters on Polygon more than people expect, because anyone can deploy a token named “USDC” and send it to your address. Compare contract addresses, never symbols.
6. Plan for failure
Your server will be down at some point. Decide in advance how you recover:
- Use a provider that retries failed deliveries.
- Run a reconciliation job, for example every few minutes, that checks balances or recent transfers for your addresses and flags anything your webhook log never saw.
- Alert when no events arrive for an unusually long time. On a busy system, silence is a signal.
Webhooks are your fast path. Reconciliation is your safety net. Run both.
Tokens and edge cases on Polygon
USDC and USDT. Stablecoin payments are the main reason developers set up Polygon webhooks, because fees are low and settlement is quick. Make sure you know which contract each stablecoin uses on Polygon and whitelist those addresses, as described above.
Native POL. Native transfers do not emit token logs, so a listener built only on Transfer events will miss them. Confirm your provider reports native coin movements too if you plan to accept POL.
Contract-to-address payments. A payment may come from a smart contract wallet or a multisig, not a plain account. Do not assume the sender is the customer. Link payments to customers by the receiving address you generated for them, not by the sender.
Failed and reverted transactions. A reverted transaction consumes gas but moves nothing. Only act on events that represent successful transfers.
Dust and spam tokens. Unsolicited tokens regularly show up in addresses. Ignore contracts you did not whitelist.

Build it yourself or use a unified API
There are three realistic routes to Polygon event notifications:
- Run your own node and listener. Maximum control, but you own node upgrades, storage growth, log decoding, reorg handling and uptime. Sensible when chain infrastructure is your product.
- Use a general-purpose node or data provider and write the filtering yourself. Less operational burden, but you still build subscriptions, retries, decoding and the signature layer.
- Use a payments-focused API that delivers decoded, signed events. You write the endpoint and the business logic, nothing else.
For a team that wants to accept or send crypto in its product, the third route usually reaches production fastest. We compare the options in more depth in Blockchain APIs compared: 6 types and when to use each.
Our perspective: webhooks are a ledger problem, not a notification problem
Most integration bugs we see are not about receiving the HTTP request. They are about what happens after. Teams treat a webhook as a trigger (“payment arrived, ship it”) when it is really one input to a ledger that has to stay correct under retries, reorgs and restarts.

That shapes how we build Chaingateway. We deliver pre-decoded events, so your code reads an amount and a token, not hex-encoded log topics. We sign every request with HMAC so your endpoint can reject forgeries. And we cover Polygon next to Ethereum, Tron, Bitcoin, Solana, BNB Chain and Arbitrum through one REST API, so your handler logic stays the same when you add a second chain.
Our advice: write your idempotency and reconciliation code first, before the happy path. If you can replay the same event ten times and shuffle three events and end up with the right balance, the rest is easy. Our write-up on processing deposits automatically with webhooks walks through that flow end to end.
— Bitblade
Getting Polygon webhooks with Chaingateway
With Chaingateway Webhooks you create wallets or register addresses through the API, subscribe to payment events and receive signed notifications at your endpoint. The Polygon API page covers sending and receiving USDC and USDT on Polygon, and the Blockchain API covers wallets, transfers, decoded transaction data and gas estimation across supported chains.
Plans are published on the pricing page:
| Plan | Monthly | Yearly |
|---|---|---|
| Plus | €49 per month | €490 per year |
| Pro | €99 per month | €990 per year |
| Premium | €249 per month | €2,490 per year |
| Enterprise | €499 per month | €4,990 per year |
Paid access starts after a free trial, so you can test the full flow, including signature checks and duplicate handling, before you commit.
A launch checklist
Before you point production traffic at your endpoint, run through this:
- HTTPS only, with a valid certificate.
- Signature verified on the raw body, constant-time comparison.
- Unique constraint on the event key.
- 2xx returned within a couple of seconds, work moved to a queue.
- Contract addresses whitelisted, amounts and recipients validated.
- Status model with pending and final states, and a documented confirmation threshold.
- Reconciliation job and an alert for missing events.
- Secrets stored outside the repo and rotatable without downtime.
- A replay test: send the same event several times, and out of order, in staging.
Sources
Recommended
Frequently asked questions
It depends on the provider. Token transfers emit logs that are easy to track, while native transfers need transaction-level monitoring. Check that your provider lists native coin events before you rely on it for POL payments.
There is no single rule. Some exchange-style setups wait for 128 blocks, about 4 to 5 minutes, while small payments are often credited much sooner as pending. Match the threshold to the amount at risk and re-check it against current Polygon documentation.
You need two layers: a provider that retries failed deliveries, and your own reconciliation job that compares your records with the chain. Together they close the gaps even after a long outage.
Yes, assume it will. Retries after timeouts are the usual cause. Store a unique event key with a database constraint and return 200 for events you have already processed.
Ready to build this yourself? Get your API key — 7-day trial, no card required — or see the Polygon API for the full endpoint reference.