How Guard checks whether a user is real
How Guard verifies a Telegram user, the signals it scores on, and why we shipped the scoring pipeline empty on purpose.
Guard answers one question for a Telegram Mini App: is this user a real person, or part of a bot farm?
The API is small on purpose. On a moment that matters, like a signup or a points claim, the app’s backend sends a POST to /api/v1/score with the user’s Telegram initData and wallet. It gets back a score from 0 to 100 and a verdict of clean, suspicious, or sybil. The app decides what to do with that.
The first thing Guard does is prove the request is genuine. Telegram signs the initData it hands to a Mini App with an HMAC over your bot token. Guard recomputes that signature and rejects anything that does not match. We wrote this part first and covered it with tests before anything else, because a fraud API that trusts forged input is worse than no API at all.
After verification, the request flows through collectors and rules. Collectors gather signals: how old the Telegram account is, whether it has premium or a username, the phone country, the device fingerprint, and how the TON wallet was funded on chain. Rules read those signals and vote. A weighted sum turns the votes into a score, with a hard block reserved for cases that should never pass no matter what the rest of the signals say.
Now the honest part. Today that pipeline runs end to end, but the collectors return nothing and the rule set is empty, so every real call comes back with a score of 0 and a clean verdict. That is deliberate. We built the boring half first: authentication, storage, the request record, the verdict math, and the tests around all of it. Signals and rules are the work happening now, not a foundation we still have to pour.
The reason any of this is worth doing is the graph. EVM tools like Trusta do not help when identity lives in Telegram initData and a TON wallet instead of an Ethereum address. And because scores are shared across projects, a wallet cluster caught farming one client raises a flag for the next one. A sybil is cheap to create once and expensive to hide everywhere.
Guard is in private beta. If you run a Mini App and watch real allocation bleed into farms, that is exactly the feedback we want while the rules land.