# Watermarks Remover > Inspect and clean text for invisible characters, steganographic carriers and AI provenance > marks. The character scan, the reveal view, the style score and the clean all run in the > browser, free, with no account. An optional model lane explains the findings or rewrites the > highest-signal paragraphs. Live at https://watermarks-remover.skillsafe.ai/ Answer-ready sections on that page: - https://watermarks-remover.skillsafe.ai/#howtoCard — how to remove invisible characters, in five steps - https://watermarks-remover.skillsafe.ai/#referenceCard — the eight classes it detects, by codepoint - https://watermarks-remover.skillsafe.ai/#faqCard — cost, privacy, file formats, emoji safety, what it cannot do - https://watermarks-remover.skillsafe.ai/api.html — HTTP API, eight languages ## Attribution The method implemented here is derived from **github.com/guillaumemeyer/watermarks-remover** (MIT, Guillaume Meyer) — specifically the text layers of that project. The layer split, the preservation rules for load-bearing invisible characters, the stylometric measures and the honesty discipline are all from it. This app is an independent browser re-implementation, not a port or a redistribution of its code. Image, PDF metadata, C2PA and the external research harnesses in the upstream project are out of scope here. ## What it actually does **Layer A — deterministic, exact, in your browser.** Enumerates every invisible, format, private-use and homoglyph codepoint in the text and reports each one with its Unicode codepoint, name, general category, class, count and character offsets. Classes: zero-width family (U+200B, U+200C, U+200D, U+2060, U+FEFF, U+180E), bidirectional controls, tag characters (U+E0001–U+E007F), variation selectors (including VS17–VS256), private-use planes, homoglyph spaces, Latin confusables, and other format controls. **The part that makes it different from a zero-width stripper.** Many invisible characters are load-bearing, and removing them corrupts real text. This app reports them and then keeps them: - emoji joiners and presentation selectors after an emoji base - zero-width joiners and non-joiners inside Arabic, Indic, Khmer and Mongolian words - every tag character inside a *complete* regional-flag sequence (an incomplete run stays contraband) - Mongolian free variation selectors after a Mongolian letter, Khmer inherent vowels after a Khmer consonant, Hangul jamo fillers in a partial syllable - CJK and Mongolian variation selectors after their base - right-to-left and left-to-right marks, and complete LRE/RLE…PDF embedding pairs - orthographic Arabic, Syriac and Kaithi format marks Directional *overrides* (U+202D, U+202E) are not preserved: they can reverse how a filename or a line of code displays, which is the Trojan Source technique. **Layer A-prime — style score, no model.** Sentence-length coefficient of variation, moving-average type-token ratio over a 50-word window, and the weighted density of 24 formulaic phrases. Composite = 0.45 × burstiness + 0.45 × phrase density + 0.10 × lexical uniformity, damped below 100 words and not computed at all below 30. Reported as CLEAN / LOW / MEDIUM / HIGH. Also computed per paragraph, which is what selects the rewrite set. **Batching.** The rewrite lane splits the selected paragraphs into batches of roughly 600 characters and runs one job per batch, rendering each as it lands. This is what lets a long document be rewritten at all: a run is killed at sixty seconds, which on this model allows on the order of 700 characters of output, and an overrun loses the whole reply. Each batch is attempted up to three times — a failed run refunds its hold, so only time is spent. A batch that still fails costs one batch, not the document. The run can be stopped between batches and keeps what has already landed. **Model lane.** Two tasks against `gemma-fast`: `explain` turns the deterministic findings into an account of what each carrier is and what is worth acting on; `rewrite` rewords the highest-signal paragraphs and leaves everything else untouched. ## What it does not do - It does not detect or remove provider text watermarks. Those are statistical — the signal is spread across word choice at generation time — and no character scan can see one. The rewrite lane is the only lever that touches them, it is best-effort, and it cannot be certified against any detector. - It does not read file-level provenance: signed content credentials, embedded metadata, pixel or audio watermarks. A clean text scan says nothing about any of them. - A removed character does not mean the content was not AI-assisted, and the app never claims a text is human-written. - The style score is evidence about cadence, not about authorship. Heavily edited human prose scores high. ## Input Paste, or drop a file. Text formats (`.txt .md .html .json .csv .srt .yaml .py .js` and many more) are read in the browser with `FileReader`, byte for byte, so nothing is normalized before the scan sees it. PDF and `.docx` go through the platform's document converter, which requires a signed-in account and rebuilds text rather than copying it — carriers can be lost in that step, and the UI labels such input as converted. Cleaning operates on codepoints, so the file's format survives untouched: Markdown stays Markdown, HTML stays HTML, code stays code. ## Output contract `task: "explain"` returns three sections: `## VERDICT`, `## RISK`, `## NEXT`. The model is deliberately not asked to list the carriers — the browser table already shows every codepoint, name, class, count and offset exactly, and asking for that enumeration as well pushes the reply past what the sixty-second run limit allows. `task: "rewrite"` returns `[[BLOCK ]]` for each paragraph id in that batch, then `[[NOTES]]`. Block ids are the paragraph indices supplied in the request. Anything the model omits is shown unchanged and reported as unrewritten. Both lanes are reconciled against the free scan: a codepoint the model names that the scan did not find is flagged as invented, and a block that does not come back is named rather than quietly replaced with the original. ## Pricing Free to run. The publisher sponsors usage within a daily budget, so guests can run the model lanes without signing in. When the daily allowance is used up, signed-in users fall back to their own credits (a few credits per run on `gemma-fast`) and guests are asked to sign in. The scan, the reveal view, the style score, the clean and the bundled example never cost anything. ## API `https://api.skillsafe.ai/v1/app-api` — see https://watermarks-remover.skillsafe.ai/api.html for a worked example per lane in cURL, Python, JavaScript, Go, Java, Ruby, PHP and C#. ## Use it honestly Clean content you own or are authorized to process. Removing a mark is not a claim about who wrote something, and it is not a way to defeat a disclosure requirement.