Testing a third-party API usually starts with a proxy — the outbound route gets configured fast. Then a webhook arrives from the same provider, a callback saying an order was paid, and the data simply never shows up. Here is why the proxy has nothing to do with it, where the break comes from, and how to build callback delivery that does not depend on the outbound channel.
A proxy changes the outbound route, not the inbound one
A proxy sits between your client and a remote API only on the outbound leg: you initiate the connection, and it swaps the IP the request appears to come from. A webhook works the other way: the provider is the initiator. It opens a new connection to the URL registered in advance, unrelated to the channel you used to call the provider's API.
Hence a common mix-up: teams switch their outbound channel and assume callbacks will travel differently too. In reality, an inbound request's route depends only on where the receiver URL points and whether that address is reachable from outside.
Why a callback fails to arrive
A missing webhook has few real causes, all on the receiving side. The machine sits behind a home or office NAT router with no forwarded port, so its address does not exist from outside. A local dev address cannot be resolved from the internet. The registered URL points to an internal host visible only inside a corporate network. A TLS certificate has expired or was issued for the wrong domain, so the handshake fails before the body arrives. The server answers with something other than 2xx, and most providers stop retrying after a few failed attempts.
A separate cause is the provider's own allowlist: infrastructure changed, the record was never updated, and calls die quietly with no clear error.
How to receive callbacks correctly
A callback receiver has to be a publicly reachable address with an open port and a valid TLS certificate — a domain or IP the provider can reach directly, with no proxy or tunnel needed on your end. That requirement has nothing to do with which channel you use for outbound calls to the same API.
A sound receiving setup separates two jobs: confirming receipt fast and processing data at leisure. A lightweight handler stores the raw body in a queue and answers 200 immediately, without waiting for business logic; processing runs asynchronously, out of the queue, in a separate process. That protects against provider-side timeouts — a synchronous handler will eventually start dropping events under load once processing outruns the response window.
If a public address is off the table — a closed network, a test bench — switch to polling instead of push: most such APIs expose a parallel endpoint for status or events. Poll it on a schedule. Latency grows from seconds to your polling interval, but public reachability is no longer required.
Verifying delivery
Verification runs against two independent logs. The provider's delivery log shows attempts, response codes, timing. Your own receiver's log proves the request reached your code rather than a load balancer or CDN that answered 200 on its own. A "delivered" status with no matching entry in your queue signals a break in the middle, not a working integration.
Also check the signature: if it's signed with an HMAC key and the stored secret went stale after a rotation, the server will silently reject valid events as forged — from outside that looks exactly like "nothing arrives".
Where a proxy still matters here
A proxy stays useful on the outbound leg of this setup. Once you switch to polling, every poll is an outbound request, distributed like any other traffic to a third-party server: by geography, by frequency, with rotation when a rate limit hits. It also helps to check what a platform shows from the right country when a callback depends on geo-specific logic.
Frequently Asked Questions
Can webhooks be received through a proxy server?
The provider needs to reach your receiver directly; the channel used for outbound requests plays no part in that chain. To hide the server's real address, put a reverse proxy in front of it — a different role, not to be confused with an outbound proxy for calls to a third-party API.
Why does the dashboard say "delivered" when there is no data?
"Delivered" means the provider got a 2xx response from your address — a load balancer, CDN, or another service on the same domain could have answered without passing the body to the queue. Cross-check the provider's log against your own receiver's log rather than trusting a status shown in someone else's dashboard.
What if a public address is simply not an option?
Switch to polling: query the status endpoint on a schedule instead of waiting for a push notification. Latency grows, but the requirement for public reachability disappears entirely.
For the outbound leg of this setup — polling a provider's API or checking how a callback behaves from a specific country — a dedicated or rotating channel from the proxy catalogue fits well. Setup is in IP rotation via API, channel metrics in how to check proxy quality.