Rohan Pandey

Rohan Pandey

Full Stack & Cross Platform Developer

All Blogs

How I Connected Tally Live to Mobile Using a Custom VPS Tunnel

Tally has no public API. Here is how I reached it from a mobile app anyway.

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."
Full Request Path — Mobile to Tally
Client

📱 Mobile App (Flutter)

User triggers a Tally data request

HTTPS + JWT Auth
Step 1

☁️ Backend API

Validates JWT, fetches tunnel URL from DB

Internal Proxy
Step 2

🌐 VPS — Reverse Proxy Tunnel

Routes request through the persistent outbound channel

Persistent Outbound Connection
Step 3

🖥️ Connector (Desktop App)

Runs on the same Windows machine as Tally

XML over localhost
Target

📊 Tally ERP

Processes the XML request and returns live data

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.

Hidden Tunnel URL

The tunnel identifier is stored server-side in the database. No client ever sees it.

JWT Authentication

Every request must carry a valid token. Even knowing the tunnel URL is not enough.

Outbound-Only Connection

The office machine initiates the connection. No inbound ports are opened on the local network.

Self-Hosted Infrastructure

No third-party tunneling service sits in the data path. Full control over the entire chain.

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.

Feature Ngrok (Free) Ngrok (Paid) Custom VPS Tunnel
URL Stability Changes on restart Stable subdomain Stable while running
Rate Limits 40 connections/min Higher, but capped No limits
Data Path Control Third-party sees all traffic Third-party sees all traffic Fully self-hosted
Cost Free ~$20/month VPS cost only (~$5/mo)
Custom Security No Limited Full control

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.