Polling is the simplest way to get a code: send a request, check the response, repeat in a few seconds if empty. The simplicity is deceptive — every extra call eats the API rate limit, and the delay stays unpredictable, since the code can appear right after a check and sit undelivered until the next cycle. A webhook works differently: the server reports the event the moment it happens. Here is what changes in practice, what to prepare on your side, how to spot a forged call, and when polling still wins.

Push versus polling: what a webhook actually gives you

With polling, the client hits the status endpoint every few seconds, and until the code arrives, almost every response means "nothing new." A dozen parallel activations means hundreds of wasted calls a minute, without closing the real gap between the code appearing and the app learning about it. What the code itself is and where it comes from is covered in what an OTP code is. A webhook flips the model: the sender's server opens the request to your address itself, the moment the event is ready. Delay shrinks to one request's delivery time, and the call count drops to one per activation instead of dozens of polls.

What you need to prepare on your side

First, a publicly reachable address. The receiver must answer from the outside over HTTPS — a domain or public IP, not a LAN address, with no proxy between the sender and your server. If the address does not resolve from the internet, the sender logs a connection error, not silence. Why a receiver ends up unreachable is covered in broken callback delivery.

Second, response speed. The handler must accept the body and immediately return a 2xx code, without waiting for the business logic — parsing text, pulling out the code, writing it to a database. That work moves into a queue and runs separately. Processed synchronously, any slowdown becomes a timeout, and the sender marks delivery failed even though the event arrived.

Request signature: confirming a webhook is genuine

A public receiver address is visible to anyone who finds it or spots it in intercepted traffic. Without an authenticity check the endpoint accepts any body — one POST request with a made-up "code" is enough, and the handler treats it as real.

A signature closes that gap: the sender hashes the body with a secret key and puts the result in a header; the receiver recomputes the hash and compares values. A match confirms both the source and an unaltered body. The key lives only on the server and never reaches client-side code; if it might have leaked, rotate it in the account panel and update the check at the same time.

Duplicate delivery is normal, not a failure

The sender can never be fully certain a 2xx response means "saved" rather than "replied, but processing crashed a second later." Most systems retry delivery on a schedule — a few seconds, then a minute, several times — until confirmation arrives or attempts run out. Result: the same code and event identifier can arrive twice, sometimes three times.

The handler must be idempotent: check whether a code with this activation or event identifier is already stored, and on a repeat just return 200 without creating anything new. This mirrors how you should retry your own calls to someone else's API — see API errors: how to handle and retry them. If the receiver was unreachable for the whole retry window, the event survives only if the sender keeps a queue of undelivered events you can pull manually.

When polling is still the right call

With no permanent public address — a test stand without a domain, a script behind NAT, a pilot switched off the next day — a webhook is not worth the effort. Polling every few seconds covers a one-off task without receiver infrastructure or signature checks.

The second case is a genuinely single request: one code, one activation, no stream of events, where the gain does not pay for a public address and a queue. With regular or parallel reception the balance flips: polling starts eating the API limit faster than it saves on integration.

Frequently Asked Questions

Can the same webhook address serve several services?

Yes, if the handler tells events apart by a service or activation identifier in the body. It is more practical to split sources across separate paths on one domain — logs stay easier to read, and a leaked signature can be rotated for one source only.

What if the provider does not support delivery retries?

Add parallel status polling as a safety net for the one moment the receiver was unreachable. Poll rarely — once every few minutes catches a missed event without it becoming the main channel.

How do I confirm the signature check works before going live?

Send a test event with a corrupted body or wrong signature header and confirm it gets rejected. Then resend with a valid signature and the same event identifier twice — the second call must return 200 without a duplicate.

Webhook event format, signature header, and retry parameters are in the API documentation.