DRAFT — for review. Not yet in force. Effective date: [DATE — SET AT LAUNCH] KDC Solutions — [email protected]
This is the single, canonical privacy policy for Vaultix. It is published at https://kdcsolutions.app/vaultix/privacy, and that one string is also what the in-app policy link opens and what the Play Store listing field carries. There is no second copy to drift out of step with this one.
Card recognition runs entirely on your phone. When you scan a card, the camera image is read and matched on-device, and that photo never leaves your phone unless you choose to flag a misread. There is no server in the loop doing the recognizing.
Once the App knows *which* card you are holding, it does fetch two things about that card from the internet: its picture and its price. That means the card databases and image servers listed in item 7 can see that a device asked about that card.
Your collection and binders are stored on your device. If your phone's own backup is turned on, your collection list rides that backup so it survives a lost or broken phone — on Android that is Android Auto Backup to your Google account, and on an iPhone it is your device's own iCloud backup. Either way the backup belongs to your Google or Apple account, is encrypted, and we never receive it.
The two platforms work in opposite directions, so the App's share of the backup is not identical on both and we will not round it off. On Android the App opts exactly one file in — your collection list — so nothing else of the App's is backed up at all. On an iPhone, iCloud takes an app's documents folder by default and an app opts things out, one item at a time; the App opts out the photos from flagged misreads and its game recognition packs, so an iPhone backup can carry more of the App's own working files than an Android one does. Flagged photos are in neither backup on either platform.
The App has no accounts, no ads, and no ad networks. There is no analytics or tracking SDK that watches what you do in the App and reports it.
One library does report on itself. The component that reads the text off a card is Google's, it runs on your phone, and it sends Google diagnostics about its own performance — always, not on a switch, and we cannot turn it off. It carries no card image and no card name; what it does carry about your device — its make, model and build, and an identifier Google generates for this installation — is item 13 below, written out in full, because "no analytics SDKs" said flatly would be a tidier sentence than the truth.
It has one optional, off-by-default statistics upload, described in full as item 12 below: counts of how often the scanner had to ASK you which printing you were holding, and how often its own guess was not the one you picked. It is numbers only, it is separate from misread reports, and it sends nothing at all unless you switch it on. This paragraph used to say "and no telemetry" flatly; that sentence would stop being true the day the switch shipped, so it was changed in the same commit that added it rather than after someone noticed.
A small number of things *do* leave your device, each for a specific reason, and this policy lists every one of them. If it isn't listed below, it doesn't leave your phone.
1. Misread flags — only if you choose to send one. If a card is recognized wrong, you can flag it. Flagging is opt-in for each individual flag; nothing is ever submitted automatically. Before anything is sent, the App shows you the exact image that will be submitted. That image is cropped to the card outline you line the card up with, plus a small margin, so a little of whatever is behind the card — the edge of a table, a hand holding it — can appear around it. It is not a photograph of your room, and the preview shows you exactly what will be sent. The image is re-encoded with all EXIF and location metadata removed. We use flagged images solely to improve card recognition. Your per-flag consent is recorded with the submission. We never use flagged images for advertising, never sell them, and never share them with third parties.
Each submission also carries a diagnostic trace: a few hundred lines of the App's own log, describing which recognition steps ran and what text they read. It exists so a report says *why* a scan went wrong rather than only *that* it did. Two things about it are worth stating plainly. It is held in your phone's memory only — nothing is written to storage — and it is written down for the first time at the moment you tap Send, never before. And it is bounded by a number of lines rather than by one card, so on a fast scan it reaches back over the last few cards: it can contain the text read from those cards as well as the one you are reporting. It carries no images, no location, and nothing you type.
Each submission also carries a random install identifier — the same kind described in item 3, generated on your device, tied to no name, email, or account. It is what groups the reports from one phone so a repeated misread can be recognized as one problem rather than five, what rate-limits submissions, and what lets us find a submission again if you ask us to delete it. The App shows you that identifier on every flag preview, above the Send button.
2. Recognition-accuracy counters attached to those flags. When you send a flag, the App attaches anonymous on-device accuracy counters: numbers (for example, how many scans locked on the first try), plus — for the scans where the camera's suggestion and your answer disagreed — the catalog identifiers of the two printings involved, so we can see what it got wrong. These counters never include images beyond the flagged image you approved, never include card names, and are never a list of what you own.
A SEPARATE and independently switched upload covers how often the scanner had to ask you to choose a printing — see item 12. Turning misread reports on does not turn that on, and turning it on does not send misreads.
3. Feature-request form — only if you choose to submit it. The optional feature-request form sends exactly what you put in it: the text you type, plus your multiple-choice answers (how you engage with card games, and roughly how many cards you handle in a month), plus a random install identifier used for rate limiting. It is anonymous by design: there are no name or email fields. Please do not put personal information in the free-text boxes — because submissions are anonymous, we cannot find "your" submission later to retrieve or delete it.
4. Subscription and quota state — nothing today, and here is what will change. This version of the App has nothing to buy. The Google Play billing library is not part of the build, scan quotas are counted by the App on your phone, and no purchase state, quota count, or device identifier is sent to our server — not periodically, not at startup, not at all. The device identifier described in items 1 and 3 leaves your phone only inside those two flows, both of which you start yourself.
When paid subscriptions ship, that changes, and this paragraph is the advance copy of how: purchases will be processed by Google Play Billing (we never see your payment details), and to grant your tier and enforce scan quotas the App will periodically check in with our server, exchanging your purchase state, entitlement tier, scan balances, and a device identifier — subscription bookkeeping, numbers and tokens, never images or collection contents. If a referral program is active and you redeem a code, the redemption will be recorded the same way, to credit both sides and prevent abuse. Under "Changes to this policy", none of that starts silently: the effective date changes and the App gives notice before the first check-in is made.
5. Graded-slab price lookups — automatic, no button. When you scan a graded slab, the App asks our server for the listings currently offered for that card so it can show comparable prices — asking prices, which is what the App labels them on screen ("listed"), not sold prices. This one happens as part of the scan: the moment the label reads well enough to name a card, the lookup goes out. You do not press anything, and it is a different flow from the "Sold comps" button in item 10, which opens a marketplace in your browser only when you tap it.
The request carries words the App read off the slab's own label, and nothing else: the card's name; variant wording the label prints ("1ST EDITION", "ALTERNATE ART", "ALT ART", "PARALLEL", "MANGA", "SHADOWLESS"); the set name, or the printed set/card code where the label carries one; the card's number where the label prints one of 100 or higher; the language when the label is not English; and the grade. Those label words are capped at ten, with the language and the grade always added after the cap. It carries no image, no identifier of any kind, nothing about the rest of your collection, and nothing you typed.
Our server forwards the query to a marketplace's public search, using credentials that live on the server — so your phone never talks to the marketplace and the marketplace never sees your device. The answer is cached against the query itself and shared with everyone who scans the same card, and nothing on our side records who asked: no identifier arrives with the request, and we keep no log of the queries, only a daily count of how many were made in total. If you would rather this never leave the phone, don't use slab mode — a slab's whole point is its market price, and the App cannot know that price without asking.
6. Pack downloads and price refreshes. Downloading a game's recognition pack or refreshing prices is an ordinary HTTPS download of public data — the same as any app fetching a file. A pack is one file covering a whole game, so the request says nothing about which cards you own or scanned, and carries no account or identity. Like every internet request from any device, it necessarily exposes your IP address to the server that fulfills it; we do not use IP addresses to identify or profile you.
7. Card pictures and card details, fetched from the card databases. This one is not optional and is not something you press a button for, so please read it.
The App does not ship pictures of millions of cards inside the download. When a card picture appears on your screen — in a scan result, in the printing picker, in your binder grid, on a card's detail page — the App fetches that picture from the public card database that hosts it, at the moment it is displayed. Those hosts are third parties, not us.
Which host depends on the game. Below is the complete list, and it is complete in a checkable sense rather than a promised one: the App's card data is what decides which host is contacted, so this list is read back out of that data by a script (`tools/census_image_hosts.py`), and a test in the build fails if the data ever names a host this list does not.
Separately, for Magic only, when you scan a card from a set newer than the data already on your phone, the App asks Scryfall's public API (`api.scryfall.com`) about that one card, by set code and collector number, to name and price it. Cards your phone can already identify locally are answered locally and ask nobody.
What this means, stated plainly: those third parties can see your IP address and which card was asked about, at the time it was asked. Over a long binder-scrolling session that is a meaningful slice of what you own. They do not receive your name, your email, an account, a device identifier we mint, or a list of your collection — there is no such list to send, and we send them nothing about you. Each request looks to them like any other web request for a public card image. Pictures are cached on your device after the first fetch, so scrolling the same binder again does not re-ask. Their handling of that request is governed by their own privacy policies, not this one.
8. Checking for a new version of the App. When you open the update row, the App asks our server for the current version number and compares it with yours; the request carries the version you are running. If you choose to install an update, tapping the button hands the download URL to your browser, and Android's own download manager and installer take it from there. No collection data, scan data, or identity is involved. (Builds installed from Google Play update through Play instead, and this flow is not used.)
9. Sending your collection to a collection site or a store — only when you open that screen. Two flows share one screen and one paragraph, because they are the same mechanism pointed at different sites. Send to a collection site is an in-app browser pointed at `www.moxfield.com` or `www.archidekt.com`. Sell this binder is the same in-app browser pointed at the store you pick from the sell menu — `sellyourcards.starcitygames.com` (Star City Games) or `www.cardkingdom.com` (Card Kingdom) — carrying a sell list built from that binder; Price-check on TCGplayer is that browser pointed at `www.tcgplayer.com` (TCGplayer Mass Entry, their shopping-cart list tool) carrying a price-check list, not a sale — TCGplayer closed its buylist on July 17, 2024. Either list carries at most the card names, set names or codes, collector numbers, languages, finishes and quantities the binder holds, and no prices of ours. From the moment you open it, your phone is talking to that site the way any browser would: their pages load from their servers, signing in happens on their pages (your password goes to that site, never to us), and the export you hand over — the CSV file or the pasted list — goes to that site and is governed by its privacy policy from then on. The App's part is mechanical and visible: at your tap it fills the site's import box, or answers the site's "choose file" dialog with your CSV. Nothing loads and nothing is handed over until you open the screen and act. Every one of these files is also written to your own Downloads folder, which is your phone and not a transfer to anyone.
10. The "Sold comps" button on a graded slab — an eBay search in your browser. Item 5 is our server answering with summary numbers. This is the other half: tapping Sold comps hands your browser an ordinary eBay search (`www.ebay.com`) for that card at that grade. The search terms name the card, its set, and its grade — nothing else — and from there you are on eBay, which sees the request the way it sees any search made from your browser and applies its own policies to it. Nothing is sent until you tap.
11. The "Verify at …" button on a graded slab — the grading company's own cert page, in your browser. A slab prints its grader's certification number, and verifying it only means something when the answer comes from the grader. Tapping Verify opens the grading company's public cert-lookup page in your browser with that cert number in the address: `www.psacard.com` (PSA), `www.cgccards.com` (CGC), `www.beckett.com` (BGS), `gosgc.com` (SGC), `my.taggrading.com` (TAG), or `www.acegrading.com` (ACE). A cert number identifies one specific slab, so the grader can see that someone asked about that slab from your IP when you tapped. Nothing is sent until you tap.
12. Picker statistics — only if you switch them on, and they are off until you do. When the scanner cannot tell two printings apart it asks you which one you are holding. How often it has to ask, and how often the option it guessed was not the one you picked, is the measurement that lets it stop asking.
If you turn on Settings → Picker stats, the App sends counts and nothing else. Specifically, for each kind of question and each game: how many times it asked, how many times you closed the question without choosing, how many options it showed, how far down the list the option you tapped was, and whether that option was the one it had guessed.
What it does not send: no card names, no images, no free text, nothing you typed, and no list of what you own. Those are not omissions of practice but of structure — the upload has no field capable of carrying any of them, and the server rejects anything that is not one of the counters named above. A card you scanned is never identifiable from this data, and neither is your collection.
It goes at most once each time you open the App, carrying the same random install identifier your misread reports use. It is off by default and is a different switch from misread reports (item 1): each one is asked separately and neither turns the other on.
The App counts these questions on your phone whether or not the switch is on — that is how the Diagnostics screen can show you the numbers before you decide. Nothing is sent while the switch is off, but the first send after you turn it on carries the counts already on the phone, including ones from before you turned it on. Turning it back off stops all sending.
13. The card reader's own diagnostics, sent to Google — always on. Like item 7, this is not optional and you do not press a button for it. Unlike item 7, we cannot switch it off either, so please read it.
The text on a card is read by Google's ML Kit, a recognition library built into the App. The reading itself happens on your phone. Google's own documentation is explicit that the processing "fully happens on-device", and that ML Kit does not send the image or the text it recognized to Google's servers. So the photo of your card, and the words read off it, never leave the phone. That is the promise the rest of this policy makes about scanning, and it holds.
The library does, however, report on itself. It sends Google metrics about its own operation: your device's manufacturer, model and operating-system build, and which ML hardware accelerators it offers; the App's package name and version; an identifier Google generates for this installation of the App — a different one from the identifier in item 1, which is ours and is not in this; the image format and resolution the App asked it to read; how big the input and the output were; how long the work took; the version of the recognition feature itself, which is not the App's version; and event types and error codes. Google describes this as diagnostics and usage analytics for the library, and states that it does not pass this data on to third parties.
Google also says the library contacts its servers from time to time to pick up bug fixes and information about which hardware accelerators your phone offers — not to fetch a model, because the App ships the bundled recognizer and the model is compiled into it.
Three things to be plain about. We never see any of it — it goes from the library to Google, not through us, and no copy comes back to our server. There is no setting, in the App or in the library, that turns it off; it is the price of a reader that works without a server in the loop, and we would rather name it here than have you find it in a packet capture. And it says nothing about your cards: no card name, no card image, no collection contents, nothing you typed. It describes how the reader performed, not what it read. Google's own privacy policy governs what happens to it from there, and Google requires us to tell you that it happens.
14. Opening this policy, the Terms, or the license notices from inside the App. Settings carries a row for the privacy policy and one for the Terms of Service. Tapping either hands your browser an address on `kdcsolutions.app` — this page, or the Terms beside it. From that point it is an ordinary web request: whoever serves the page can see that an IP address asked for it, the way any website can. The App sends nothing else with it — no card, no collection, no identifier — and nothing about the visit comes back to the App. Nothing is sent until you tap.
The third row, Open-source licenses, opens nothing at all. Both sets of notices — the Flutter and Dart packages the App is built from, and the open-source libraries inside the card reader of item 13 — are files carried inside the App itself and read from your phone. No request is made to anyone to show them.
Vaultix is a general-audience app. It is not directed to children, and by design it collects no personal details — no names, emails, or locations — from any user of any age. The data flows above are the complete list, and the only image flow (misread flags) is opt-in per submission with the exact image shown first. If you believe a child has submitted something they should not have, email [email protected] and we will delete it.
All transmissions use HTTPS/TLS. Flagged images are stored only for processing and deleted per the retention schedule above. No system is perfectly secure, but our best protection is structural: the data we never receive is data that cannot be breached.
We sell nothing, we rent nothing, and we never hand anyone a copy of your collection. No flow in this list exists to advertise to you or to build a profile of you. One of them does go to a third party for their own purposes: the card reader's diagnostics about itself, which go to Google for Google's analytics of its own library. That is the ML Kit bullet below, and item 13 above writes it out in full. Nothing else here is in that position — everyone else is either working on our behalf, or being asked for a public card picture the way a browser would ask.
The services involved in operating Vaultix are:
If we change what data leaves the device, we will update this policy, change the effective date, and give in-app notice before the new flows take effect. We will never retroactively expand what happens to data you already submitted.
KDC Solutions Email: [email protected]
*Draft for internal review. A licensed attorney must review this policy and the Terms of Service before commercial launch.*
This is the same document that ships inside the app — one source of truth, no drift. © 2026 KDC Solutions™