AI Watermark Checker
Paste text from a chat, a doc or a web page. This checker finds zero-width spaces, the U+202F narrow space, smart quotes and other invisible Unicode, then lets you copy plain text. Free, in your browser, and the text is not uploaded.
- Free, no signup
- Text stays in this tab
- Works after the page loads
These are typography and formatting characters, not a cryptographic watermark. Cleaning them does not make a piece of writing undetectable, and it does not remove statistical watermarks such as SynthID-Text.
What to clean
Emoji sequences are kept. Turn off special spaces for French text, and turn off invisible characters for Arabic, Hebrew, Persian or Hindi.
Your text
Paste text to check it.
Clean text
How to check text for hidden characters
The report updates as you paste. The text is not sent to a server.
1
Paste the text
Copy from a chat window, Word, a CMS or a source file. The example contains a zero-width space, a narrow space, curly quotes, a soft hyphen and an emoji, if you want to see the report before using your own text.
2
Read the report
Hidden characters are counted by type, with the Unicode code point beside the name. Reveal hidden characters to put a label where an invisible or ambiguous character sits. Quotes and dashes are listed separately, because you can see them.
3
Copy the plain text
The second box is the cleaned version. Copy it or download a .txt file. Untick a group first if you want to keep those characters — French spacing, an em dash, or Markdown you still need.
Why pasted text picks up hidden characters
In April 2025, people reading ChatGPT o3 and o4-mini answers noticed narrow no-break spaces (U+202F) scattered through long replies. The character looks like an ordinary space. The finding spread under the name “ChatGPT watermark.” OpenAI described it as a side effect of training, not a mark they had planted, and that particular pattern stopped appearing soon after. The searches stayed, because the practical problem is older than that story.
Text copied from a chat, a word processor or a web page often contains characters the writer did not choose. Curly quotes, em dashes, non-breaking spaces, Markdown asterisks and, less often, genuinely invisible Unicode — zero-width spaces, joiners, byte order marks, direction overrides — all survive a copy and paste. None of that is a cryptographic watermark. A character checker can see all of it. Some of it also breaks code, spreadsheets, search-and-replace and content systems in ways that look like a file is haunted.
On 2 August 2026, Article 50 of the EU AI Act started requiring providers of generative systems to mark synthetic content in a machine-readable way. Whatever form that mark takes across products, people are already pasting drafts into checkers and asking what is in the clipboard. A character checker answers the clipboard question. It cannot see a statistical watermark such as Google SynthID-Text, which is encoded in which words a model picked, and it cannot rewrite a paragraph so that a style-based detector changes its score.
That limit is the product. The page lists each special character, shows where the invisible ones sit, and hands back plain text. The sentences stay the sentences. Every group of rules can be switched off, so a French draft can keep its narrow spaces, and a bilingual document can keep its direction marks.
Characters this checker detects
This is the checklist the cleaner runs. If a character is in the table, the checker looks for it. The toggles above the text boxes turn whole groups on or off. Line endings are always normalized.
| Code point | Name | What the cleaner does | Controlled by | Why it matters |
|---|---|---|---|---|
U+200B | Zero-width space | Removed | Remove invisible characters | Takes no width, so it can split a word that still looks like one word on screen. |
U+200C | Zero-width non-joiner | Removed | Remove invisible characters | Invisible in English. It is meaningful in Persian and Hindi, so turn invisible-character removal off for those languages. |
U+200D | Zero-width joiner | Removed | Remove invisible characters | Glues emoji into one glyph. Joiners inside emoji are kept; a joiner in ordinary text is removed. |
U+2060 | Word joiner | Removed | Remove invisible characters | Invisible glue that stops a line from breaking, without showing a space. |
U+FEFF | Byte order mark | Removed | Remove invisible characters | A hidden marker some editors put at the start of a file. In the middle of text, it breaks parsers. |
U+00AD | Soft hyphen | Removed | Remove invisible characters | Stays invisible until a line wraps there, then appears as a hyphen nobody typed. |
U+034F | Combining grapheme joiner | Removed | Remove invisible characters | An invisible control that almost never belongs in prose pasted from a chat window. |
U+200E, U+200F, U+061C, U+202A–U+202E, U+2066–U+2069 | Direction marks and overrides | Removed | Remove invisible characters | Can show characters in a different order from the order they are stored. Needed for Arabic and Hebrew, and also used in Trojan Source attacks. Turn this off for real bidirectional text. |
U+180B–U+180E | Mongolian separators | Removed | Remove invisible characters | Mongolian variation selectors and the vowel separator. They are invisible in Latin or CJK text. |
U+2061–U+2064 | Invisible math operators | Removed | Remove invisible characters | Invisible times, plus, separator and function-apply characters left by math layout. |
U+206A–U+206F | Deprecated shaping controls | Removed | Remove invisible characters | Old Unicode controls for Arabic letter shaping. Current text does not need them. |
U+115F, U+1160, U+3164, U+FFA0 | Hangul fillers | Removed | Remove invisible characters | Hangul and halfwidth fillers that render as a blank and are used to fake an empty string. |
U+17B4, U+17B5 | Khmer inherent vowels | Removed | Remove invisible characters | Deprecated Khmer vowel signs that take no visible space. |
U+FFF9–U+FFFC | Annotation and object marks | Removed | Remove invisible characters | Interlinear annotation controls, plus the object-replacement character. |
U+FE00–U+FE0F | Variation selectors | Removed | Remove invisible characters | Invisible switches between text style and emoji style. Selectors that belong to an emoji are kept. |
U+E0100–U+E01EF | Ideographic variation selectors | Removed | Remove invisible characters | Choose a glyph for a CJK character. Kept when they follow an ideograph, removed when they do not. |
U+E0000–U+E007F | Invisible tag characters | Removed | Remove invisible characters | A hidden alphabet. It can carry a message the reader never sees. |
U+0000–U+0008, U+000B, U+000C, U+000E–U+001F, U+007F, U+0080–U+0084, U+0086–U+009F | Control characters | Removed | Remove invisible characters | C0 and C1 controls other than tab and line feed. They do not belong in pasted prose. |
U+202F | Narrow no-break space | Replaced with a normal space | Normalize special spaces | U+202F. This is the character widely called the ChatGPT watermark in April 2025. It is also correct French spacing before ; : ! ? %. |
U+00A0 | No-break space | Replaced with a normal space | Normalize special spaces | Looks like a space and will not wrap. Very common in text copied from the web or from Word. |
U+2000–U+200A | Typographic spaces | Replaced with a normal space | Normalize special spaces | En, em, thin, hair and the other fixed-width spaces from U+2000 through U+200A. |
U+205F | Medium mathematical space | Replaced with a normal space | Normalize special spaces | A math-typesetting space that is easy to mistake for a normal one. |
U+1680 | Ogham space mark | Replaced with a normal space | Normalize special spaces | The space from Ogham, an early Irish script. Some fonts draw it like a dash. |
U+3000 | Ideographic space | Replaced with a normal space | Normalize special spaces | U+3000, the full-width space used in Chinese, Japanese and Korean. Turn special-space normalization off to keep it. |
U+2800 | Braille blank | Replaced with a normal space | Normalize special spaces | The empty braille cell. It looks like a space and slips past filters that only know U+0020. |
U+000D | Carriage return | Normalized to a line break | Always on | The Windows half of a CRLF line ending. A CRLF pair becomes one line feed. |
U+0085 | Next line | Normalized to a line break | Always on | U+0085, a legacy line break from older mainframe systems. |
U+2028, U+2029 | Line and paragraph separators | Normalized to a line break | Always on | U+2028 and U+2029. They break JavaScript string literals and some JSON parsers. |
U+201C, U+201D, U+201E, U+00AB, U+00BB, U+2033 | Smart double quotes | Replaced with a straight double quote | Straighten smart quotes | Curly quotes, low-9 quotes and guillemets, replaced with a straight quotation mark. |
U+2018, U+2019, U+201A, U+2039, U+203A, U+2032 | Smart single quotes | Replaced with a straight apostrophe | Straighten smart quotes | Curly apostrophes and primes, replaced with a straight apostrophe. |
U+2010, U+2011, U+2012, U+2013, U+2014, U+2015, U+2212 | Em and en dashes | Replaced with a hyphen | Turn dashes into hyphens | Em dashes, en dashes, minus signs and non-breaking hyphens become a plain hyphen. An em dash is a writing choice, not proof that a model wrote the sentence. |
U+2026 | Horizontal ellipsis | Replaced with three dots | Ellipsis to three dots | The single ellipsis character becomes three periods. |
- U+202F is correct French typography before ; : ! ? %. If the text is French, untick “Normalize special spaces.”
- Direction marks are legitimate in Arabic and Hebrew, and they are also the characters used in Trojan Source attacks. Untick “Remove invisible characters” for real bidirectional text.
- U+3000 is the standard full-width space in Chinese, Japanese and Korean. U+200C, the zero-width non-joiner, matters in Persian and Hindi. Both can be kept with the toggles above.
- Emoji are protected. Joiners and variation selectors that belong to an emoji, including family sequences and skin tones, are not removed. The same characters outside an emoji are removed.
What you can do with it
A live character report
Matches are counted as you type, grouped by character, with the Unicode code point next to the name.
Plain text in one click
Invisible characters are deleted, special spaces become normal spaces, and curly punctuation becomes straight punctuation. The words are not rewritten.
Stays in this tab
Checking and cleaning run in your browser. The text you paste is not uploaded to mihoyonb.
Emoji stay intact
Family emoji, skin tones and variation selectors inside an emoji are left alone. A joiner floating in ordinary text is still removed.
When people paste text in here
Drafts copied from a chat
Editors who paste a model draft into a CMS, an email or a doc and want the invisible leftovers gone before anyone else opens the file.
Code and config that will not parse
A zero-width space in an identifier, a byte order mark at the top of a config file, or a non-breaking space in a command. The line looks right, and the tool still rejects it.
Spreadsheets and duplicate checks
Two cells that look identical and fail an equality check, because one of them contains U+00A0 or U+202F instead of a normal space.
French, Arabic and CJK text
The same characters are correct typography in some languages. The toggles let you clean an English draft without flattening French spacing, full-width spaces or bidirectional text.
Frequently asked questions
What does an AI watermark checker look for?
In the way people use the phrase, an AI watermark checker looks for hidden and special characters that show up in text copied from chatbots and word processors: zero-width spaces, the narrow no-break space U+202F, no-break spaces, curly quotes, em dashes and other invisible Unicode. This page does that check in your browser and can remove the characters. It does not detect statistical watermarks that live in word choice.
Did ChatGPT watermark its text with a hidden space?
In April 2025, readers found narrow no-break spaces (U+202F) spread through answers from the o3 and o4-mini models, and the character was widely called a watermark. OpenAI said it was a training artifact, not a watermark, and that particular pattern disappeared soon after. What is still true is more ordinary: copied text often contains curly quotes, dashes, odd spaces and sometimes invisible Unicode. This checker shows those characters. It does not prove that a model wrote the paragraph.
Will cleaning change my wording?
No. The cleaner never rephrases, summarizes or rewrites a draft. It deletes invisible characters, turns special spaces into normal spaces, straightens quotes and dashes when those options are on, and can strip Markdown marks. Every rule can be turned off, and the report lists what it found before you copy.
Is the text I paste uploaded?
No. Checking and cleaning run in your browser tab. mihoyonb does not receive the text you paste, and there is no account. The page may still load the site’s ordinary ads and analytics scripts; those scripts do not receive the contents of the text box.
Will this make AI-written text pass a detector?
No. Removing hidden characters does not defeat a detector that scores writing style, and it does not remove a statistical watermark such as SynthID-Text. A character cleaner cannot do either of those things.
Is an em dash proof that a text was generated?
No. The em dash is a normal punctuation mark, and it is also common in model output, which is why some editors treat a stack of them as a hint. The dash option is there if you want hyphens instead. Leaving the option off keeps the em dash.
Why do invisible characters break code, spreadsheets and CMSs?
A zero-width space inside a name, a byte order mark at the start of a file, or a no-break space in a command looks identical to the character you expected and compares as a different value. Compilers, search, deduplication and databases then fail in ways that are hard to see. Cleaning the paste fixes that class of bug whether or not you care where the text came from.
Which characters can I keep?
Turn off “Normalize special spaces” to keep U+202F, including French spacing, and the full-width CJK space U+3000. Turn off “Remove invisible characters” to keep direction marks in Arabic or Hebrew and the zero-width non-joiner used in Persian and Hindi. Emoji are kept by default. The table on this page is the full list the checker uses.