The Problem
Tally ERP runs as a desktop application on a local Windows computer inside an office. It has no REST API, no public URL, and no way to reach it from the internet. The machine sits behind a router with a dynamic IP — completely invisible from outside.
I needed a mobile app to send a request to Tally and get a live response. Not a sync later — right now.
The Solution
I built a small desktop application called the Connector that runs on the same machine as Tally. When it starts, it establishes a persistent outbound connection to my VPS using a reverse proxy tunneling tool running on the server side. Outbound — so it works behind any router or firewall with zero network configuration or port forwarding on the client side.
This connection exposes Tally's local port as a unique URL on the VPS. That URL is automatically saved to the database — it never appears in the app, never goes to the client, and is only used internally by the backend. When a request arrives from the mobile app, the backend fetches that URL from the database and proxies the request through it. The Connector receives it, sends it to Tally as an XML request over localhost, and the response travels back the same way.
"The machine calls out to the VPS once. That creates a live public URL for Tally's localhost — stored in the database, invisible to the outside world."
The full path looks like this:
Mobile App
│
▼ (HTTPS + JWT)
Backend API
│
▼ (fetch tunnel URL from DB)
VPS ── Reverse Proxy Tunnel
│
▼ (persistent outbound connection)
Connector (on Tally's machine)
│
▼ (XML over localhost)
Tally ERP
Security
The tunnel identifier is never sent to any client — it only exists inside the backend. On top of that, every request requires a valid JWT token. Two layers: the tunnel is hidden, and even if someone found it, they still cannot use it without authentication.
Why Not Ngrok
Ngrok and similar hosted tunneling services work fine for demos. For production, free tier URLs change on every restart, paid plans have rate limits, and you are entirely dependent on their infrastructure staying up. Running the tunnel server on a VPS I control means the URLs are stable for as long as the Connector is running, the security is exactly what I designed, and there is no third-party in the middle of the data path.
The Key Insight
Reaching a machine behind NAT from the outside is hard. But letting that machine initiate the connection outward — and then keeping that channel alive to serve inbound requests through it — is straightforward and reliable. Once the Connector is running, Tally's localhost effectively has a public address. The backend just reads it from the database and uses it like any other URL.