Last updated: 10 September 2026 · Applies to the Blot iOS app and the Blot backend service.
Blot is operated by StarNova ("we", "us"). Blot finds sensitive text in a screenshot — email addresses, API keys and tokens, credit card numbers, phone numbers and IP addresses — and covers it with a black bar, a blur, a pixel block or decoy text before you share the image. For any privacy question or request, contact us at vdnhan97@gmail.com.
Blot has no user accounts and no sign-in. On first launch the app asks our server for an anonymous visitor token — a random string that is stored on your device in Capacitor Preferences (Keychain-backed storage on iOS) and sent with every request. Everything the service knows about you hangs off that token and nothing else. We never collect your name, email address, phone number, postal address, date of birth or contacts.
The app also generates a per-install fingerprint: the literal string blot- followed by 32 random hexadecimal characters, produced on device by the system random number generator and stored alongside the token. It is not derived from your hardware, your browser or anything about you — it is simply a random label. The server uses it so that clearing the app's storage and registering again lands on the same identity and the same monthly scan allowance, rather than handing out a fresh free allowance every time.
Whichever path runs, the app first reads the image you selected and downscales it on your device (longest edge 1600 pixels, re-encoded as JPEG). What happens next depends on whether your device can do the scan itself. On iPhone and iPad it can, and that is the path Blot takes.
Blot hands the downscaled image to Apple's own text recognition, which runs inside the app on your phone, and then matches each recognised word against patterns for emails, API keys and tokens, credit card numbers, phone numbers and IP addresses. The list of rectangles it produces stays on the phone. You review that list, choose a cover style, and the covers are drawn onto the image on the phone too. The screenshot, the text read out of it and the cleaned copy never leave your device on this path.
Our server is still involved, because it owns your monthly scan allowance, but all it receives is the scan's metadata: a SHA-256 hash of the downscaled image, how many sensitive items were found and which kinds they were (email, API key, card, phone, IP). It does not receive the image, the rectangles, the character counts or any matched text. Against that hash it stores only a marker saying a scan happened and whether anything was found, so that re-scanning the same screenshot within 24 hours does not spend your allowance twice.
On-device recognition is not available everywhere: the web version has no such plugin, older builds of the app did not ship one, and a device's text recognition can fail on a given image. In those cases Blot falls back to the original pipeline: the downscaled image is sent to the Blot backend over HTTPS, the backend forwards it to our screenshot engine, the engine runs Google Cloud Vision optical character recognition over it, classifies the recognised words the same way, and renders the covers onto the image server-side, returning a PNG.
There is one narrower fallback as well. If your device swept the screenshot but then fails to draw the covers on it, only the drawing moves to the server: the image and the rectangles you confirmed are sent so the covers can be rendered, and the image is discarded when that request ends, exactly as above. The scan itself has already happened on your device and nothing more about it is sent.
Even on that path the image itself is not stored. It exists in server memory for the duration of the request and is discarded when the request ends. It is never written to a database, a disk or an object store, and it is never given a URL. What is kept on this path is the detection result described below — read that carefully, because "we do not store the image" is not the same as "we keep nothing".
The cleaned image is kept on your phone, in the app's own storage, which is what lets the Archive reopen it. The server never receives it on either path, so deleting a cleaned copy in the app deletes it everywhere it existed.
sk_live_… in your screenshot, the most that is ever written down is its rectangle, the label api_key and its length — never the key, and on the on-device path not even that much reaches us. Decoy covers are built from the type and the length, which is enough to produce a fake of the same shape without anything worth stealing having to survive the sweep. Earlier builds of Blot did store the matched string, and this section used to say so; it no longer does because the behaviour changed, not the wording.| Data | Why | Kept |
|---|---|---|
| Anonymous visitor token (random string) | Identifies your scan history, allowance and entitlement without an account | Until you ask us to delete it |
Per-install fingerprint (blot- + random hex) | Keeps one install on one monthly allowance so clearing storage does not mint a fresh one | Until you ask us to delete it |
| The screenshot you pick | Scanned for sensitive text and rendered with covers | On-device path: we never receive it. Fallback path: not stored — held in server memory for the request only |
| SHA-256 hash of the downscaled image, computed on your device | Recognises the exact same image so re-scanning it is free and does not spend your allowance. On the on-device path this is the only thing about the image we ever see | 24 hours, then deleted automatically |
| Fallback path only — detection result for that hash: the rectangles found, the type of each (email, API key, card, phone, IP) and the number of characters each covered, never the text itself. On the on-device path we store a marker instead: that a scan ran and whether anything was found | Serves a repeat scan of the same image from cache without charging you again, and sizes decoy text | 24 hours, then deleted automatically; or when you ask us to delete it, whichever comes first |
| Case record: case number, how many items were found, which types, and the timestamp | The Archive list in the app | Until you ask us to delete it. On Free only the last 7 days are shown to you |
| Monthly scan counter | Enforces the plan's monthly scan allowance | One row per calendar month |
| Hourly request counters | Abuse prevention (a ceiling on scans and renders per hour) | Old windows are deleted automatically |
| IP address | Rate limiting and abuse prevention only — it caps how many brand-new identities one connection can create. The most recently seen address is stored on the visitor record. | Until you ask us to delete it; also present in short-lived server logs |
| Time zone offset (minutes from UTC) | Decides when your billing month rolls over. Pinned the first time we see it so it cannot be rotated to farm a second allowance. | Until you ask us to delete it |
| Analytics events and identifiers: the events listed in section 6, keyed to your visitor token, plus the Firebase app instance id and the vendor identifier (IDFV) | Tells us which screens are used, whether scans succeed and where people stop. Counts, type names and fixed labels only — never a screenshot, a matched string or any text you typed. | Google Analytics data retention (section 8) |
| Subscription and credit status | Unlocks Plus or Pro and tops up scans. We receive the entitlement status, never your card details. | While the entitlement is active plus records required for accounting |
Blot does not collect your contacts, your location, health data, advertising identifiers (IDFA), browsing history or your photo library as a whole. We never receive your photo library, and on iPhone and iPad we do not receive the individual screenshots you scan either — only on the fallback path described in section 3 does an image reach us at all, and then only the one you chose, for the length of one request.
Blot declares three permission strings in its iOS app:
Blot uses Google Analytics for Firebase (the app side of Google Analytics 4) to understand how the app is used. On iOS the events go through the Firebase Analytics SDK; the SDK is built without advertising-identifier support, which is a deliberate choice and not a default. There is no third-party attribution SDK and no crash-reporting SDK in the app.
The analytics user is your anonymous visitor token — the same random string described in section 2. It is pseudonymous: it is not your name, email, phone number or any identifier Google or anyone else can resolve to a person. Firebase additionally generates an app instance id and reads Apple's vendor identifier (IDFV), which is scoped to apps from us alone and resets when you delete the app.
We send counts, type names and fixed labels, and nothing else. A scan event carries how many sensitive items were found, which categories they fell into (email, API key, card, phone, IP), whether the result came from cache, and whether the sweep ran on your device or on our server. It does not carry the screenshot, any thumbnail of it, any matched string, any file name or any text you typed. This is a rule in the code, not a promise about intent: the analytics module is documented as counts-and-enums-only precisely because a screenshot redaction tool leaking a matched string into an analytics parameter would defeat the entire product.
The full list of what we send is: screens opened, a screenshot being picked and from where, a scan finishing (with the counts above) or failing (with a fixed reason code), a cover style being chosen, a cleaned copy being shared or saved, the scan allowance being reached, the paywall being shown and why, a purchase completing (tier and billing period, never a price or a card), a restore completing, and a setting being changed (which setting, and its new on/off or cover value).
Blot does not use the advertising identifier (IDFA), does not show the App Tracking Transparency prompt, does not build advertising profiles, does not run remarketing or Google Signals, and does not track you across other companies' apps or websites. We do not use analytics data for advertising and we do not share it with advertising networks.
Analytics is also build-gated: if the app is built without a Google Analytics measurement id configured, the analytics code never loads and nothing is sent at all.
Separately from analytics, what the backend records is operational rather than behavioural: the counters and case records listed in section 4. Those never travel to Google Analytics.
We share data only with the service providers needed to run the app:
blot-) so its caches and rate limits follow the right user.Data is processed on servers we operate and on the infrastructure of the providers above. We do not sell your data, we do not share it with data brokers, and we do not use it for advertising.
All traffic between the app, our backend and our providers runs over HTTPS. The backend database is not publicly reachable and access is restricted to the systems and people needed to operate the service. Purchases never expose card details to us. No system is perfectly secure, which is why we keep as little as the product allows and offer deletion on request — and why, on iPhone and iPad, the screenshot and everything read out of it stay on your device in the first place.
Blot is not directed at children under 13, and we do not knowingly collect data from them. If you believe a child has used the app and provided data, email us and we will delete it.
If this policy changes materially we will update this page and change the date at the top. Continuing to use Blot after a change means you accept the updated policy.