ToolKitSphere IconToolKitSphere
JSON & Format Converters

JSON Escape Characters Explained

Online Tools Platform Team7 min read

"C:\Users\ada\config.json" looks like a file path. To a JSON parser it looks like a broken document, because \U is not a valid escape sequence and neither is \a or \c.

Escaping is where JSON's strictness produces its least intuitive errors. The rules are short — nine sequences, one edge case for astral characters — but nothing in the format's design hints at them, so people improvise and get parse failures. This post covers exactly what is allowed, what is not, and how to deal with the two situations that generate most escaping pain: pasted paths and doubly-encoded JSON. For the surrounding grammar, see The Complete Guide to JSON.

Where escaping applies

Only inside string values and string keys. JSON's structural characters — {, }, [, ], :, , — carry meaning outside strings and are just ordinary characters inside them. {"note": "use {braces} freely"} is valid; the braces inside the string need nothing done to them.

Two characters cannot appear literally inside a JSON string:

  • The double quote ", because it would terminate the string.
  • The backslash \, because it starts an escape sequence.

Plus one whole class: control characters below U+0020 — newline, tab, carriage return, null, and the rest — must be escaped. A literal line break inside a JSON string is a syntax error, which is why multi-line text has to be written with \n.

The complete list of valid escapes

There are nine, and this is all of them:

Escape Meaning
\" Double quote
\\ Backslash
\/ Forward slash (optional)
\b Backspace, U+0008
\f Form feed, U+000C
\n Line feed, U+000A
\r Carriage return, U+000D
\t Tab, U+0009
\uXXXX Any code point, four hex digits

Anything else following a backslash is invalid, no matter how familiar it looks from other languages. \x41, \', \0, \a, \e, and a backslash before a newline are all syntax errors in JSON. Many of them are legal in JavaScript string literals, which is precisely why they show up in hand-written JSON.

Here is a document exercising most of them:

{
  "quoted": "She said \"hello\" loudly",
  "windowsPath": "C:\\Users\\ada\\config.json",
  "multiline": "line one\nline two\nline three",
  "tabbed": "name\tvalue",
  "unicode": "caf\u00e9",
  "emoji": "\uD83D\uDE00",
  "scriptSafe": "<\/script>"
}

Every value there is a normal string once parsed. "caf\u00e9" and "café" are the same string — the escape is a transport-level choice, not a different value.

The forward slash question

\/ is the odd one out: it is permitted but never required. "https://example.com" is perfectly valid JSON with bare slashes.

It exists for one practical reason. If you embed JSON inside an HTML <script> element, the byte sequence </ can terminate the element early — an HTML parser looking for </script> does not know it is inside a JSON string. Escaping the slash as <\/script> avoids that, which is why some serialisers escape slashes by default. If you are wrangling content that has to survive both HTML and JSON encoding, an HTML entity encoder/decoder is useful for seeing which layer added which escapes.

Unicode and the surrogate pair trap

\uXXXX takes exactly four hexadecimal digits and encodes one UTF-16 code unit. That covers everything in the Basic Multilingual Plane: accented Latin, Greek, Cyrillic, CJK, and most punctuation.

It does not cover anything above U+FFFF — emoji, many historic scripts, mathematical alphanumerics. Those need a surrogate pair: two \u escapes that together encode one character. The grinning face emoji, U+1F600, is written \uD83D\uDE00. Writing \u1F600 does not work; the parser reads \u1F60 as a character and then a literal 0.

Two consequences worth internalising. First, do not hand-write astral escapes — let your language's serialiser do it, or embed the raw character, since JSON documents are Unicode text and a literal emoji in a UTF-8 file is entirely valid. Second, string length in JSON-adjacent code is usually measured in UTF-16 code units, so a single emoji counts as two. That is why naive truncation can split a surrogate pair and produce a replacement character.

If your JSON is arriving with everything above ASCII already escaped, that is a serialiser setting rather than a requirement. Python's json.dumps escapes non-ASCII by default; pass ensure_ascii=False to keep text readable.

Doubly-encoded JSON: the real-world nightmare

This is the escaping problem you will actually spend time on. It looks like this:

{
  "eventId": "evt_991",
  "payload": "{\"user\":{\"id\":42,\"name\":\"Ada \\\"Countess\\\" Lovelace\"}}"
}

The payload field is not an object — it is a string that happens to contain JSON. This happens constantly: webhook envelopes carrying a provider's body verbatim, message queues with a string body, database columns storing serialised documents, log lines wrapping a request payload.

Each nesting level multiplies the backslashes. A quote inside the inner document is \". A quote inside a document nested two levels deep is \\\". Three levels and it stops being readable by any human.

The way out is to parse in layers, not to try to unescape by hand:

  1. Parse the outer document. payload comes back as a plain string with the escapes resolved.
  2. Parse that string as JSON in its own right.
  3. Repeat if there is another layer.

In JavaScript: JSON.parse(JSON.parse(text).payload). For a one-off debugging session, paste the outer document into the JSON Formatter, copy the unescaped inner string out of the result, and format that. Two passes, no backslash counting.

Worth asking why the double encoding exists at all. Sometimes it is unavoidable — a queue whose body is typed as a string, a provider that forwards raw bytes for signature verification. Often it is an accident: someone called JSON.stringify on a value that was already going to be serialised by the framework. If it is the second case, fix the producer, because every consumer downstream pays for it forever.

Debugging escape problems

The symptoms are recognisable once you have seen them a few times.

"Unexpected token" pointing at a word in the middle of a sentence means an unescaped quote closed a string early, and the parser is now reading prose as structure.

"Invalid escape" or "Bad escaped character" means a backslash is followed by something not in the list of nine. Windows paths and regular expression patterns are the usual sources — a regex like \d+\.\d+ needs every backslash doubled to survive a trip through JSON.

Text rendering as é instead of é is not an escaping bug at all; it is UTF-8 bytes being decoded as Latin-1 somewhere in the pipeline. No amount of escaping fixes an encoding mismatch.

For all of these, a JSON Validator narrows the location down in seconds, and because it runs client-side you can paste a payload containing real tokens or customer data without it leaving the browser.

The rule that prevents all of it

Never build JSON with string concatenation. '{"name": "' + name + '"}' is broken the moment name contains a quote, a backslash, or a newline — and in a user-facing system, it eventually will. Build a native object and call your language's serialiser, which knows all nine escapes and handles surrogate pairs correctly. Hand-write JSON only in fixture files and examples, and even then, run the result through a validator before committing it.

Frequently asked questions

What are the valid escape sequences in JSON?

There are exactly nine: \" for a double quote, \\ for a backslash, \/ for a forward slash, \b backspace, \f form feed, \n newline, \r carriage return, \t tab, and \uXXXX for any code point as four hex digits. Anything else after a backslash is a syntax error.

How do I escape a double quote in JSON?

Put a backslash in front of it: \". Writing {"q": "She said "hi""} ends the string at the second quote and breaks the parse, while {"q": "She said \"hi\""} is valid.

Why does my Windows file path break JSON?

Because a single backslash starts an escape sequence. "C:\Users" is invalid since \U is not a valid escape. Write "C:\\Users\\ada" with doubled backslashes, or use forward slashes, which Windows APIs accept.

Is \x41 valid in JSON?

No. JSON has no hex escape of that form. Use \u0041 instead — JSON only supports the four-hex-digit \uXXXX form for arbitrary code points.

How are emoji escaped in JSON?

Emoji sit outside the Basic Multilingual Plane, so \uXXXX cannot encode them in one escape. They need a UTF-16 surrogate pair — the grinning face is \uD83D\uDE00. You can also just include the raw emoji, since JSON text is Unicode.

Do I need to escape the forward slash in JSON?

No, \/ is optional and a bare / is perfectly valid. It exists so JSON can be embedded inside an HTML script tag without the sequence </ prematurely closing the element.

Why is my JSON full of backslashes before every quote?

It has been stringified twice — a JSON document stored as a string value inside another JSON document. Each nesting level adds a layer of escaping. Parse the outer document, then parse the inner string separately.

Try the related tools

Related articles