Privacy

What the app sends, field by field

Last updated 2026-09-02 · applies to v2.8.2 and later

Filthy Net Deck works completely with no account, and in that state it uploads nothing about you or your matches. Everything below is opt-in, off until you switch it on, and reversible.

This page lists the fields in full rather than describing them, because the list is short enough to publish and a summary you cannot check is worth very little. The tables match the source exactly — src/services/cloud/healthPing.ts, src/services/cloud/matchSync.ts and src/services/cloud/backupSync.ts in the public repo.

Two rules hold no matter which toggles you turn on.

1. Another player's identity never leaves your machine. Your opponent's Arena name and the specific cards they revealed to you are never uploaded — not hashed, not "anonymised". Your app works out what deck they were on locally, and only that label is sent. An Arena handle identifies a real person who agreed to nothing.

2. The payload is an allowlist, not an exclusion list. Uploads are built by naming each field explicitly, never by serialising an internal object. A field added to the tracker later cannot start uploading itself by accident, and an automated test asserts the exact set of keys.

1 · Parser health ping

Default: off. Settings → Data & privacy. Sends at most one record per day, on launch. It exists so that when an Arena update breaks log parsing — which it can do without notice — that shows up as a spike across many installs within hours, instead of arriving as a bad review a week later.

FieldExampleWhy
installIdrandom UUIDCounts unique installs rather than launches
appVersion2.8.2Which build is affected
parserVersion1Attributes a fault to a specific parser
oswindowsPlatform only — never the build number
logFoundtrueDid the app locate Arena's log
detailedLogstrueIs Arena's Detailed Logs setting on
parseErrors0The actual early-warning signal
matchesLast24h7Detects recording stopping population-wide

Being straight about the tradeoff: installId is a persistent random identifier for a machine, so it is pseudonymous, not anonymous — it makes "this install has been active 60 days" knowable. That is precisely what makes counting installs possible at all. It is tied to no account, no name, and no IP-derived location. Switching the ping off deletes the identifier locally; switching it back on mints a brand new one.

2 · Match sharing and cloud sync

Default: off. Requires a free account and the single "Sync & community data" toggle. This is what makes community matchup rates possible: they are built from players who chose to contribute, which is why the app can show real ladder winrates instead of scraped tournament results.

FieldExampleNotes
client_hashsha256 digestA dedupe key. Arena's own match id is hashed and never sent
started_at / ended_attimestampsWhen the match ran
formatstandardStandard or Pioneer
best_of1Bo1 or Bo3
rankedtrueLadder event or not
rankDiamond 1Your rank at match start
season_ordinal42Which Arena season
my_deck_hashdigestGroups your own matches by list
my_archetypestandard-azorius-controlYour deck's archetype label
opp_archetypestandard-mono-redA label, worked out on your PC
opp_confidence0.82Lets thin reads be down-weighted or rejected
resultwinWin, loss or draw
games[{onPlay, won}]Play/draw and result per game

Decklists

Decklists ride the same single toggle — one switch, by design, and the consent line in Settings says so out loud, because a backup you did not know you turned on is not consent. A deck row is deck_hash, name, format, and the Arena card ids for main and sideboard. It is worth having because Arena's logs rotate: once they do, the 75 cards a deck was are gone from your PC and Arena will not hand them back.

Changed in v3.2.0 — two corrections worth stating plainly. Until now the app worked out a match's format by looking for "ladder" in Arena's queue id. Historic_Ladder contains "ladder", and so do the Alchemy and Timeless queues, so games from formats this app does not cover were being uploaded to the community matchup data labelled Standard, and decks from those queues were backed up and published with a "standard" chip. Both are fixed:

Exporting your decklists to a folder on your own PC — Export decklists in My Stats — uploads nothing and needs no account. It reads the same local history the app already has and writes files.

Your match history (new in v3.4.0)

Match sharing sends a narrow slice of a match to the community data. That slice is not enough to give you your history back on a second machine — it is Standard and Pioneer only, and it drops the queue, the deck name and the per-game detail. So the same toggle now also keeps a private backup of your own history, in a separate table that nothing aggregate ever reads. It is what makes signing in on a new PC show the matches you played on the old one.

FieldExampleNotes
match_idsha256 digestSame hashing as above — Arena's own match id is still never sent
started_at / ended_attimestampsWhen the match ran
event_idBrawl_LadderArena's queue, so a Brawl game comes back as a Brawl game
best_of1Bo1 or Bo3
my_team_id1Which seat was yours — without it, won games restore as losses
games[{onPlay, mulligans, …}]Your own per-game detail: play/draw, mulligans, first land turn
result / result_reasonwinIncludes unfinished matches, so the count matches the PC it came from
deck_name / deck_id / deck_hashMy BrewYour own labels for your own deck
deck_main / deck_sideArena card idsThe list you registered for that match
my_rank / season_ordinalDiamond 1Your rank and which season

Your opponent is not in that table. Their name, the cards they revealed, their basic land types and their platform stay on the PC that saw them — the same rule as everywhere else on this page, and it is not relaxed just because these rows are private to you. The visible cost is stated in the app rather than hidden: a match restored onto another machine shows your side of it only. Your own Arena name is not sent either.

The backup is deleted along with everything else when you turn the toggle off. Deleting a single match, or clearing your history, removes it from the backup too — otherwise the next machine you signed in on would hand it straight back.

Public profile and friends

A profile page at /u/<handle> is published only when you choose to publish it, and it carries your handle, display name, and season record. Friend codes are private tokens you hand out yourself; a friendship is two account ids and a timestamp. All of it can be switched back off.

Changed in v3.1.8: publishing a deck to that page now also publishes the decklist, as Arena import text, at /u/<handle>/<deck> — so anyone with the link can copy it into Arena. That is the point of the feature, and it is a per-deck decision you make with the Publish decklist button on that deck. Before v3.1.8 a published deck showed only its name, format, size and last-played date; decks you published back then keep showing exactly that until you publish them again. Taking a deck down deletes the published list, and so does making your profile private. What is never published either way is the match history behind the deck, or anything about the opponents you played it into.

3 · Never uploaded, under any setting

4 · Turning it off, and deleting what is there

Every toggle is in Settings → Data & privacy and every one is reversible. Switching the health ping off removes the local install id. Switching cloud sync off stops uploads. Deleting your account removes your rows — matches, decks and profile — because they are foreign-keyed to it and cascade on delete.

Raw shared matches are dropped after 120 days. Being honest about the reason: that window is about storage cost and unbounded growth, not about protecting you. The anonymous aggregate counts computed from them are what stays.

5 · Third parties

Card names, text and images come from Scryfall, requested by your app as you browse cards. Deck data comes from MTGGoldfish, MTGO, magic.gg, Melee and Untapped, and is fetched by a build pipeline on a server — not by your PC. Accounts, storage and the community aggregates run on Supabase. The site and downloads are hosted on Netlify, whose analytics count page requests without cookies. The optional feedback form is posted to FormSubmit, which emails it to the maintainer. There is no advertising, no third-party tracker, and nothing is sold or shared with anyone.

6 · Checking any of this yourself

The app is open source under the MIT licence. You do not have to take this page's word for it — read the repo. The two files that build every upload are src/services/cloud/healthPing.ts and src/services/cloud/matchSync.ts, and both are short on purpose.

Questions, or want your data removed? Use the feedback form or open a GitHub issue.

7 · Feedback form (this website)

Separate from anything the app can upload. The Suggest / Report form on this site is optional and sends only what you type: whether it is a feature idea or a bug, the message, an optional contact, and (if you opened it from the app) the app version. FormSubmit receives that POST and emails it to the maintainer. It is never mixed into match uploads, and you do not need an account.

← Back to Filthy Net Deck