Skip to content

Game statistics sources

Wesley edited this page Aug 9, 2026 · 1 revision

Game statistics sources

Where each number on an account row comes from, what it sends over the network, and why one may be blank. For the GameStats.json file format, see Game statistics guide.

The source chain

A game definition has one primary source and an optional list of fallbacks. On refresh the app tries them in order and keeps the first that returns at least one metric. The source that worked is remembered per account, so the next refresh starts there instead of retrying one that failed; if it fails, the rest of the chain is still tried.

If every source in the chain answers 404 or 410, the account's stats row is removed instead of left empty.

A source that names a collector is always tried first, whatever the account last used, because it reads a local file instead of making a request.

Counter-Strike 2

Order Source Request
1 steam-cs2-gcpd collector None. Reads CS2Ranks.json on disk
2 Leetify https://api-public.cs-prod.leetify.com/v2/profiles/{SteamID64}
3 CSRep, through TcNo's API https://api.tcno.co/sw/csrepStats?steamid={SteamID64}

Leetify and CSRep supply Premier rating and competitive rank. Wingman comes only from Steam. The stats modal credits Leetify and CSRep; the Steam source is marked hidden and is not credited.

Source 1 only answers while CS2 Rank is on. With it off the chain starts at Leetify. See Settings.

Other games

Game Source
Apex Legends https://api.tcno.co/sw/apexStats?player={EA username}
Overwatch https://playoverwatch.com/en-us/career/pc/{BattleTag}, read as HTML

Neither has a fallback source.

Refresh timing

Stats refresh in the background once they are older than the game's TTL: 3 hours by default, or 30 minutes for the account currently signed in while that game's process is running (cs2.exe, r5apex_dx12.exe, overwatch.exe). The running-process list is re-read every 5 minutes.

Results are cached in {UserData}/StatsCache/{game}.json. Offline mode stops every refresh, including the Steam checks below.

CS2 statistics read from Steam

For an account signed in under Steam Guard/Auth, the app reads that account's own Game Personal Data page rather than a third-party API:

https://steamcommunity.com/profiles/{SteamID64}/gcpd/730?tab=matchmaking

The request carries that account's session cookie and pins Steam_Language=english, because the parser locates the cooldown table by its English header. One response yields the competitive matchmaking cooldown, the Premier rating and wins, the Wingman rank and wins, and the competitive skill group. Valve shows a cooldown to nobody but the account itself, so no public API has it.

A page the parser does not recognise, or Steam's sign-in page, writes nothing. Existing stored values are kept rather than cleared.

Prime status

Prime is not on that page. With CS2 Prime Status on, an account with any Premier match on record is marked Prime without a second request, because Premier is Prime-gated. Every other account costs one more request:

https://store.steampowered.com/app/730/CounterStrike_2/

Fetched with the account's session, the store page marks the Prime Status Upgrade package as owned or not. CS2 Prime is a certain verdict. CS2 Non-Prime is a guess: accounts that reached rank 21 before 2019 were granted Prime without ever holding the package, and the store page shows them as not owning it. Accounts Steam holds no CS2 records for get neither tag.

Both are applied as tags, so the account list can be filtered by them. Turning the setting off removes both from every account.

When the check runs

It runs when the Steam Guard vault is unlocked, and every 6 hours while it stays unlocked. Under the default lease the vault relocks after five minutes, so the unlock is the trigger for most users; the 6-hour timer matters if you chose to remember the password for the session.

The check waits 2 seconds between accounts and will not re-check the same account inside 90 seconds. If Steam rate-limits the app, the sweep stops at that point rather than walking the rest of the list into the same wall, and the next unlock retries.

What is stored, and for how long

File Holds Lifetime
{UserData}/LoginCache/Steam/CS2Cooldowns.json Cooldown expiry, or a permanent flag Until the expiry passes. The tile hides an expired one
{UserData}/LoginCache/Steam/CS2Ranks.json Premier, Wingman, competitive rank, Prime verdict 14 days, then ignored

Both survive the vault relocking and survive removing the account from the vault. Reading them needs no credentials, so a rank drawn from Steam still renders on a locked vault; only the refresh stops.

A stored rank older than 14 days is ignored and the chain falls through to Leetify, then CSRep. The same happens when the stored entry has no Premier rating or no competitive rank, so an incomplete first-party answer never costs you the metrics a public API would have shown.

Ranks appear even on accounts with no CS2 stats row configured, as long as CS2 Rank is on. Where you have configured game stats, the configured row is what renders, and the same toggle gates that too: with CS2 Rank off, source 1 declines and the row falls through to Leetify and CSRep.

Statistic, source, requirement

Statistic Source Needs
CS2 competitive cooldown Steam GCPD page Steam Guard/Auth sign-in, vault unlocked at least once
CS2 Premier rating Steam, else Leetify, else CSRep Steam Guard for Steam's own figure. Fallbacks need only a SteamID64
CS2 competitive rank Steam, else Leetify, else CSRep As above
CS2 Wingman rank Steam GCPD page Steam Guard/Auth
CS2 Prime / CS2 Non-Prime tag Premier history, else the CS2 store page Steam Guard/Auth, and CS2 Prime Status on
Apex ranked points and level api.tcno.co EA username entered on the account
Overwatch SR and level playoverwatch.com BattleTag entered on the account

What leaves your machine

  • The collector sends nothing. It reads CS2Ranks.json from disk.
  • The GCPD and store requests go to Steam from your machine, signed in as that account, with that account's own session cookie. No third party is involved.
  • Leetify receives your SteamID64 in the URL path, requested directly from your machine.
  • The CSRep fallback sends your SteamID64 to api.tcno.co.
  • Apex sends the EA username you entered to api.tcno.co. Overwatch sends your BattleTag to playoverwatch.com.
  • The Apex and Overwatch definitions each pull an image as well, from whatever host the answer points at rather than a host named here: Apex's rank badge from the rankImg in the JSON, Overwatch's player portrait from the src on the page. Both are cached on disk and only re-fetched once the cached copy goes stale.
  • Turning CS2 Rank off takes Steam's own ranks out of the chain, so CS2 rows that were answered from disk start going to Leetify, and to CSRep if Leetify has nothing.
  • Requests from the chain carry User-Agent: TcNo-Acc-Switcher and nothing else, apart from a cookie header where a definition declares one. The image fetches use their own: TcNo-Acc-Switcher/1.0 for the rank badge, TcNo Account Switcher for the portrait.

Steam session tokens never pass through GameStats.json. That file is user-editable and ends up in debug dumps, which is why the Steam source is a collector with an empty Url rather than a URL with credentials in it.

Settings

Steam -> Settings -> Steam Guard/Auth -> Show states:

Toggle Default Effect
CS2 Cooldown On Shows the cooldown on the account tile
CS2 Rank On Uses Steam's own ranks as the first CS2 source
CS2 Prime Status Off Applies the Prime tags. Costs one extra request per account with no Premier history

The three read the same page, so any one of them being on is enough for the check to run. Turning all three off stops it.

CS2 Cooldown only gates the display. It does not stop the read: while any of the three is on, the cooldown is still fetched, still written to CS2Cooldowns.json, and the CS2 Cooldown tag is still applied. Turning all three off is what stops the read.

CS2 Rank off means Steam's own ranks are not used at all: not on accounts with no CS2 stats row, and not as source 1 for a configured one. A configured row then falls through to Leetify, and to CSRep if Leetify has nothing, so an account that was answered from disk starts sending its SteamID64 to a third party.

Per-account statistics are configured from the stats icon on an account row, including which metrics to show. Disabling a game there drops that account's cached row.

Why a statistic is missing

  • The vault has not been unlocked. No unlock, no check. Nothing is read at startup.
  • The account's saved Steam session has expired. The check skips it and does not renew it, because renewing writes to the vault and would invalidate an open Steam Guard window. Open the account once under right-click -> Steam Guard; that renews the session from the stored refresh token without asking for a password.
  • The account is not in the Steam Guard vault. There is no first-party data for it, so CS2 falls through to Leetify and CSRep, and cooldown, Wingman and Prime stay blank.
  • Steam answered with something unreadable, such as a sign-in page. Nothing is written and the previous values stand.
  • The stored rank is over 14 days old. It is ignored, and the chain moves to the third-party sources.
  • Steam rate-limited the app. The check stopped part way. Lock and unlock the vault to retry.
  • The account has never played that mode. A zero rank is hidden rather than drawn.
  • Offline mode is on. No source in any chain is contacted.

One thing comes back rather than staying missing: turning CS2 Cooldown off clears the CS2 Cooldown tag once, but the sweep still runs while CS2 Rank or CS2 Prime Status is on, and it re-applies the tag to any account on cooldown. Turn all three off to keep it gone.

File reference

Item Path
Definitions {UserData}/GameStats.json
Custom definitions {UserData}/GameStats.custom.json
Stats cache {UserData}/StatsCache/{game}.json
CS2 cooldowns {UserData}/LoginCache/Steam/CS2Cooldowns.json
CS2 ranks and Prime {UserData}/LoginCache/Steam/CS2Ranks.json

Clone this wiki locally