← back to blog

Mini apps inside Telegram and the data they receive

Open almost any bot menu in Telegram these days and you’ll find a button that launches a mini app: a game, a shop, a wallet dashboard, a staking tracker. It opens inside Telegram, looks native, and feels like part of the client. It isn’t. It’s a website, loaded in a WebView, with a small bridge of JavaScript that lets it talk to Telegram. Understanding where that bridge starts and stops is the whole question of mini app privacy, and it’s a question I get from people running their own bots and wondering what they’re exposing when they add one.

What a mini app actually is

A Telegram mini app is a regular web page, hosted on a regular server, that you point Telegram at through BotFather. When a user taps the button, Telegram opens that URL in an embedded browser and injects the Telegram Web App JavaScript SDK into the page. That SDK is the only channel the mini app has back to Telegram itself. Everything else about the page, its layout, its own backend calls, its cookies, works exactly like it would on the open web, because it is the open web, just wrapped in Telegram’s chrome.

This matters because people tend to assume Telegram is mediating everything the mini app does, the way it mediates a message or a file transfer through its own protocol. It isn’t. Telegram hands the page a small, defined packet of information on launch, and after that, the page’s own server is on its own.

The identity data Telegram hands over automatically

On launch, Telegram passes the page a field called initData. It’s a query-string-formatted blob containing the launch context: the user’s Telegram ID, first and last name, username if set, language code, whether they have Telegram Premium, and a few flags about the chat the app was opened from if it was opened inline. It also includes a hash and an auth_date.

That’s it for identity. No phone number, no email, no message history, no contact list, no chat content. The mini app knows who you are in Telegram’s numeric-ID sense and roughly how you’re set up, and nothing more, unless it asks for more explicitly.

Verifying that data is real

The hash field exists because a mini app’s own backend can’t just trust a JSON blob a browser handed it, anyone could forge one. Telegram computes that hash by taking the launch data, sorting it, and running HMAC-SHA-256 over it using a key derived from the bot’s own token. The mini app’s backend, which already holds that bot token because it’s the same bot, recomputes the same HMAC and checks it matches. If it does, the backend knows this really came from Telegram’s servers for this specific bot, not a spoofed request from someone’s browser console.

This is the part that actually deserves attention if you’re the one running the bot and the mini app: the bot token is the secret that makes this verification meaningful. If that token leaks, anyone can forge valid-looking initData for any user ID they want and your backend will accept it as genuine. I’ve flagged bot token exposure before as a rotation-worthy incident for exactly this reason, and mini app auth is one more place a leaked token turns into a real problem, not just an inconvenience.

Permissions the app has to ask for separately

Beyond the automatic identity packet, the Web App SDK exposes a handful of methods that request more, but each one requires an explicit user action, usually a native Telegram confirmation dialog, not a silent grab:

  • requestContact asks Telegram to share the user’s phone number and name as a contact card, with a visible prompt.
  • requestWriteAccess asks permission for the bot to message the user outside the mini app session.
  • Location access, where supported, goes through Telegram’s own location manager rather than the browser’s raw geolocation API, so the user sees a Telegram-branded prompt.
  • Biometric methods let the app trigger device fingerprint or face unlock for local confirmation, but the biometric data itself never leaves the device; the app only gets a yes or no.
  • CloudStorage gives the mini app a small bot-scoped key-value store that Telegram hosts, useful for saving app state without the mini app running its own database, and it’s genuinely scoped to that bot, not shared across apps.

None of these are hidden. Each one produces a native dialog the user has to act on. The privacy risk isn’t that Telegram is quietly forwarding your contacts; it’s that these prompts look routine enough that people tap through them without registering what they just handed over, especially inside a flashy game or an “airdrop checker” that’s designed to feel low-stakes.

Where your proxy stops helping

This is the part that’s easy to miss if you’re used to thinking about Telegram traffic in terms of MTProto proxies. A proxy in front of Telegram protects the Telegram protocol connection, the messages, the calls, the sync traffic between the client and Telegram’s servers. A mini app is not that. Once the WebView loads the mini app’s URL, that’s a normal HTTPS request from the device, over the device’s normal network path, straight to the mini app’s own server. It does not route through your MTProto proxy, because it was never Telegram protocol traffic to begin with.

So if someone is running Telegram through a proxy specifically to mask their network origin from Telegram’s own infrastructure, that setup does nothing for the mini apps they open. The mini app’s server sees the device’s real IP, standard HTTP headers, and whatever else a normal web request exposes, on top of the Telegram identity data from initData. If you’re advising anyone on operational separation between a Telegram identity and a browsing identity, the mini app layer is the seam where that separation breaks unless it’s handled at the network level, not the Telegram client level.

What the mini app’s own server can see beyond Telegram

Because the mini app is just a web page, everything you’d expect a web page to collect, it can collect. Analytics scripts, third-party pixels, session cookies, browser fingerprinting, all of it works the same as on any other site, and none of it requires a Telegram permission dialog because Telegram’s SDK has no say over what the page itself embeds. A mini app can, for instance, run a standard ad tracker on the same page that also reads your Telegram username through initData, and now those two things are linked in whatever backend receives them.

This is normal for the web and unremarkable on its own, but it’s a different trust model than the one people bring to Telegram. Inside a chat, Telegram controls the client and the protocol end to end. Inside a mini app, Telegram controls the launch handshake and nothing about what the destination server does with the page after that.

Practical habits if you’re running or evaluating one

If you operate a bot with a mini app attached, verify initData server-side on every request, not just once at launch, and treat the bot token backing that verification with the same care as any other production secret. If you’re a user deciding whether to open one, the honest heuristic is the same one that applies to any website: check who’s asking before you tap through a contact-share or write-access prompt, and remember that a slick interface inside Telegram doesn’t mean Telegram vetted the server on the other end. Mini apps tied to wallets or token claims are the ones worth the most caution, since a convincing UI and a real Telegram identity handshake can sit in front of a backend with no accountability at all.

If you’re setting up hosting, proxy configuration, or account safety for Telegram-based projects and want to talk through where mini apps or bots fit into that, the rest of what we cover is on the homepage.

Get new guides and videos first — join the Telegram channel.

need infra for this today?