Inside a JSON string, a few characters can't appear as-is: they would end the string early or break the document. Escaping replaces them with a backslash sequence that parsers turn back into the original character. This guide lists every escape JSON supports, shows the mistakes that cause most "invalid JSON" errors, and explains how to let your language do it for you.
| Character | Escape | Why |
|---|---|---|
Double quote " | \" | Would end the string |
Backslash \ | \\ | Starts an escape sequence |
| Line feed (newline) | \n | Raw line breaks aren't allowed in strings |
| Carriage return | \r | Same as above |
| Tab | \t | Control characters must be escaped |
| Other control characters (U+0000 to U+001F) | \u0000 … \u001F | Not allowed raw |
JSON also allows \/ (an escaped forward slash), \b (backspace) and \f (form feed). Escaping / is optional, but some serializers do it so that </script> can't appear inside JSON embedded in HTML.
json{ "message": "Line1\nLine2", "path": "C:\\temp\\file.txt", "quote": "She said: \"hello\"" }
After parsing, message contains a real line break, path is C:\temp\file.txt, and quote contains literal double quotes.
Any character can be written as \u followed by four hexadecimal digits. "caf\u00e9" and "café" are the same string. Characters outside the Basic Multilingual Plane, such as most emoji, use a surrogate pair of two escapes: 😀 is "\ud83d\ude00".
You rarely need Unicode escapes. JSON is UTF-8 by default, so you can write "日本" directly. Some serializers escape everything non-ASCII by default (Python's json.dumps does); pass ensure_ascii=False to keep the text readable.
Escaping by hand is where bugs come from. Build a data structure and let your language serialize it:
javascriptconst body = JSON.stringify({ note: 'He said "hi"\nthen left' }); // {"note":"He said \"hi\"\nthen left"}
pythonimport json print(json.dumps({"path": r"C:\temp\file.txt"})) # {"path": "C:\\temp\\file.txt"}
The most common bug is building JSON with string concatenation or templates:
javascript// Breaks as soon as name contains a quote or a newline const body = '{"name": "' + name + '"}';
Use JSON.stringify({ name }) instead. The same applies in shell scripts: generate JSON with jq -n --arg name "$NAME" '{name: $name}' rather than with echo.
If you see \\n or \" in your parsed data, the string was escaped twice. This usually happens when a JSON document is stored as a string inside another JSON document:
json{"payload": "{\"id\": 1, \"note\": \"a\\nb\"}"}
Here payload is a string that itself contains JSON. To read it, parse twice: once for the outer document and once for payload. If you control the producer, send payload as a nested object instead of a string.
JSON escaping isn't the same as URL encoding (%22), HTML entities (") or Base64. If JSON travels inside a URL, a query parameter or an HTML attribute, apply that format's encoding on top of the JSON. See How Base64 encoding works for when Base64 is the right tool.
If a parser reports an error inside a long string, paste the document into the JSON Formatter. It highlights the position where the string broke. Look for an unescaped quote just before it, or a raw line break. For other causes, see Validate JSON.