Skip to content

Local Proxy

Forward requests from your public catcher URL to localhost via ngrok or any tunnel. Debug webhooks directly on your local machine.

Uses a hosted service · How your data is handled

Requests are stored by the hosted Request Catcher, then forwarded to the configured URL when enabled. Bin IDs are shared with Request Catcher and saved in this browser. Changing forwarding settings requires an operator token; forwarding is restricted to approved HTTPS origins. No automatic retention cleanup is implemented. Use synthetic test data only.

Endpoint: https://rhqvqvkkrsdvcrmvlise.supabase.co/functions/v1/request-catcher

Proxy Inactive
Endpoint ID:
Loading...

This endpoint ID is shared with the Request Catcher. Requests sent to the URL above will be captured there and forwarded here.

Forward Target

Forwarding requires an operator access token and an HTTPS origin approved by the deployment. Method, path, query, body and Content-Type are forwarded; credentials and other incoming headers are removed.

Ask the operator to approve your tunnel or API origin before enabling forwarding.

Forwarding disabled
Expose Localhost via Tunnel

Our edge servers cannot reach your localhost. These free tools create a secure public tunnel to your local port. Run one, copy the public URL, and paste it in the Forward Target above.

1Install
brew install ngrok # or download from ngrok.com
2Start tunnel (replace 3000 with your port)
ngrok http 3000
3Copy the public HTTPS URL it prints
4Paste into Forward Target above and click Save Config

A free ngrok account is required. Sign up at ngrok.com and run: ngrok config add-authtoken <token>

5Send a test request to your catcher URL
curl -X POST "" \
-H "Content-Type: application/json" \
-d '{"test":"forwarded"}'

After sending, open the Request Catcher to see the captured request and its forward response.

About the Local Proxy

You are building a webhook handler. It runs on your laptop at localhost:3000. The provider that needs to call it lives on the internet and cannot see your laptop.

That gap is the single most tedious part of integration work, and it is what tunnelling solves: a public URL that forwards to a port on your machine.

This page manages the receiving end - a public endpoint you can point a provider at, with forwarding to an operator-approved HTTPS URL. Changing forwarding requires an operator access token. The actual tunnel from the internet to your laptop needs a tunnelling client such as ngrok, cloudflared or localtunnel running locally, because a web page cannot reach your loopback interface.

Why a browser cannot do this on its own

It is worth understanding the constraint rather than fighting it.

A page on a public site cannot make requests to localhost on your machine. Browsers block it, and increasingly so - private network access restrictions exist specifically to stop a public page probing the machine it runs on. That is a good protection and you would not want it removed.

There is also nothing to route to. Your laptop is behind NAT and a firewall; it has no address the internet can reach. Something has to open an outbound connection from your machine and hold it open, so traffic can come back down it.

That is exactly what a tunnelling client does. It runs locally, connects out to a relay, and the relay gives you a public URL. This page complements that rather than replacing it.

The three things that go wrong

The Host header. Your local server receives a request whose Host is the tunnel's domain, not localhost. Frameworks with host validation - Django's ALLOWED_HOSTS, Rails' host authorisation - reject it outright, and the error is usually a blunt refusal rather than an explanation. Most tunnelling clients have an option to rewrite the Host header, and turning it on is normally the fix.

HTTPS to HTTP. A tunnel may terminate HTTPS before forwarding to a local HTTP service. Configure the application to trust forwarded-protocol headers only from a proxy you control; an arbitrary caller can forge those headers.

The URL changing. Free tunnels usually issue a new random subdomain each time you restart, which means re-registering it with the provider every session. If you are doing this daily, a reserved subdomain is worth the cost purely in saved re-configuration.

  • Rewrite the Host header, or your framework will reject the request.
  • Configure trusted-proxy handling before relying on X-Forwarded-Proto.
  • Expect the public URL to change on restart unless you have a reserved one.

Securing a local webhook endpoint

For the duration of a test session, anything on the internet that knows the public URL can reach the service on that port - not just the webhook provider you set it up for.

Public development URLs can be discovered through certificate transparency logs faster than people expect, and a development server often has debug endpoints, verbose error pages, seeded test credentials and no rate limiting.

So: expose only the specific port you need, never point a forwarding URL at a database or an admin interface, use whatever authentication your tunnelling client offers, and close the session when you finish testing.

The sequence that works

Catcher first. Point the provider at a request catcher and confirm it is actually sending, and see what the payload looks like. That eliminates half the possible causes before you touch your own code.

Then tunnel. Once you know requests are being sent and you know their shape, forward them to your local handler and work on what your code does with them.

Doing it the other way round means debugging your handler against a provider that may not be sending anything, which is where the wasted afternoons come from.

Illustrative example

The Host header rejection

Input
Local server: Django on localhost:8000
Tunnel URL:   https://a3f9-2401-8c2.ngrok-free.app
Output
Request arrives at the local server:
  Host: a3f9-2401-8c2.ngrok-free.app
  X-Forwarded-Proto: https

Django response:
  400 Bad Request
  Invalid HTTP_HOST header. You may need to add
  'a3f9-2401-8c2.ngrok-free.app' to ALLOWED_HOSTS.

Fix: run the tunnel with host rewriting, or add the
host to ALLOWED_HOSTS for local development only.

This is the first thing that happens to almost everyone, and the error is at least self-explanatory - many frameworks are less helpful. The X-Forwarded-Proto header can help construct absolute URLs only when it comes from a proxy you control and your application is configured to trust that proxy.

What this tool will not do

  • This does not create the tunnel. Reaching a port on your own machine requires a tunnelling client running locally - ngrok, cloudflared, localtunnel or similar.
  • The endpoint, received requests and forwarding state live on a hosted server. Anyone with a bin ID can inspect or clear captured requests. Changing forwarding settings requires an operator access token, and approved-origin checks apply to every forwarded request. No automatic retention cleanup is implemented.
  • Only method, path, query, body and Content-Type are forwarded. Credentials and signature headers are removed, so test handlers requiring original webhook signatures will need a direct tunnel instead.
  • Only configure a public test destination that you control. This service is not an access-control boundary; do not rely on it to protect private services.
  • A tunnel exposes your local service to anyone who finds the URL. Point it at one port, authenticate it if you can, and close it when you finish.
  • Free tunnel subdomains typically change on every restart, which means re-registering the URL with the provider each session.

Frequently Asked Questions

What is Local Proxy?

Local Proxy configures forwarding from a hosted Request Catcher endpoint to a public URL, such as a tunnel to localhost. It is a debugging relay, not a transparent proxy: some headers are removed and callers receive the catcher response.

Why can't I just forward directly to localhost?

Our edge servers cannot reach your machine's localhost. You need a tunnel tool (ngrok, localtunnel, cloudflared) to create a public URL that routes to your local port.

Does it use the same endpoint as the Request Catcher?

Yes. Both tools share the same endpoint ID stored in your browser. Configure forwarding here, then visit the Request Catcher to watch requests arrive and see forward responses.

What happens if my local server is down?

The request is still captured by the Request Catcher. Forwarding will fail gracefully and log an error message visible in the Forward tab of each request.

Is there a request size or rate limit?

The forwarding request has a 15-second timeout. Stored forward responses are truncated after 10,000 characters. Some headers, including Authorization, are removed; forwarding can fail and hosting limits still apply.