How to Escape Double Quotes in JSON with Python
JSON requires double quotes for all string values and keys. When your data contains double quotes as part of the actual text, those quotes must be escaped with a backslash (\") to produce valid JSON. Python's built-in json module handles this escaping automatically, and understanding how it works helps you avoid common pitfalls when building or parsing JSON data.
In this guide, you will learn how Python's json module escapes double quotes and other special characters automatically, how to handle manual JSON strings when necessary, and why you should almost always let json.dumps() do the work for you.
Letting Python Handle Escaping Automatically
The json.dumps() function automatically escapes all special characters, including double quotes, when serializing Python objects to JSON strings:
import json
data = {"message": 'He said "Hello!"'}
json_string = json.dumps(data)
print(json_string)
Output:
{"message": "He said \"Hello!\""}
The double quotes around Hello! in the original Python string are automatically escaped as \" in the JSON output, producing perfectly valid JSON without any manual intervention.
Handling Multiple Special Characters
The json module escapes all characters that have special meaning in JSON, not just double quotes:
import json
data = {
"quote": 'She replied: "It\'s working!"',
"path": "C:\\Users\\name",
"multiline": "Line 1\nLine 2",
"tab": "Column1\tColumn2"
}
print(json.dumps(data, indent=2))
Output:
{
"quote": "She replied: \"It's working!\"",
"path": "C:\\Users\\name",
"multiline": "Line 1\nLine 2",
"tab": "Column1\tColumn2"
}
Single quotes do not need escaping in JSON because JSON uses double quotes as string delimiters. The json module leaves single quotes as they are.
Escaping in Nested Structures
Complex nested data containing quotes throughout is handled seamlessly:
import json
dialog = {
"conversation": [
{"speaker": "Alice", "text": 'What does "API" mean?'},
{"speaker": "Bob", "text": 'It stands for "Application Programming Interface"'},
]
}
print(json.dumps(dialog, indent=2))
Output:
{
"conversation": [
{
"speaker": "Alice",
"text": "What does \"API\" mean?"
},
{
"speaker": "Bob",
"text": "It stands for \"Application Programming Interface\""
}
]
}
No matter how deeply nested your data is, json.dumps() correctly escapes every double quote in every string value.
Reading Escaped JSON Back
When loading JSON with json.loads(), escaped quotes are automatically converted back to regular double quote characters:
import json
json_string = '{"title": "The \\"Matrix\\""}'
data = json.loads(json_string)
print(data["title"])
print(type(data["title"]))
Output:
The "Matrix"
<class 'str'>
The round trip is seamless: json.dumps() escapes quotes for serialization, and json.loads() unescapes them during parsing.
Writing JSON Strings Manually (And Why to Avoid It)
Occasionally you may encounter situations where JSON is written as a raw Python string literal. When this is unavoidable, use single quotes for the Python string so that the double quotes inside do not conflict:
import json
# Single-quoted Python string containing JSON with escaped quotes
raw_json = '{"name": "John \\"The Pro\\" Doe"}'
parsed = json.loads(raw_json)
print(parsed["name"])
Output:
John "The Pro" Doe
For multiline JSON, triple quotes work similarly:
import json
raw_json = """
{
"title": "The \\"Great\\" Gatsby",
"author": "F. Scott Fitzgerald"
}
"""
data = json.loads(raw_json)
print(data["title"])
Output:
The "Great" Gatsby
Manual escaping is error-prone. The backslash must itself be escaped in Python string literals, leading to confusing \\" sequences where \\ produces a literal backslash and " is the quote character. Always prefer building a Python dictionary and calling json.dumps() over writing JSON strings by hand.
A Common Mistake: Using Raw Strings for JSON
A frequent misconception is that Python raw strings (r"...") simplify JSON escaping. They do not, because JSON requires the specific escape sequence \", not literal backslash characters:
import json
# Confusing: raw string contains literal backslash characters
raw = r'{"msg": "Say \"Hi\""}'
print(raw)
Output:
{"msg": "Say \"Hi\""}
While this happens to parse correctly, it is confusing and fragile. The clean approach is to avoid manual string construction entirely:
import json
# Clear and correct
data = {"msg": 'Say "Hi"'}
json_string = json.dumps(data)
print(json_string)
Output:
{"msg": "Say \"Hi\""}
The result is identical, but the intent is much clearer and there is no risk of escaping errors.
Ensuring json.dumps() Output Is Correct
You can verify that json.dumps() produces valid JSON by immediately parsing it back and comparing:
import json
original = {
"dialogue": 'She whispered "run" and he ran',
"path": "C:\\Program Files\\App",
"note": "First line\nSecond line"
}
# Serialize
json_string = json.dumps(original)
# Parse back
restored = json.loads(json_string)
# Verify round-trip integrity
print(original == restored)
Output:
True
The data survives the round trip perfectly, confirming that all escaping and unescaping is handled correctly.
JSON Escape Sequences Reference
| Character | JSON Escape | Handled by json.dumps() |
|---|---|---|
" (double quote) | \" | Automatic |
\ (backslash) | \\ | Automatic |
| Newline | \n | Automatic |
| Tab | \t | Automatic |
| Carriage return | \r | Automatic |
| Backspace | \b | Automatic |
| Form feed | \f | Automatic |
| Unicode characters | \uXXXX | Automatic (when ensure_ascii=True) |
Approach Comparison
| Method | Safety | Readability | Best For |
|---|---|---|---|
json.dumps() | High | Clean | All production code |
| Single-quoted Python string | Risky | Confusing | Quick tests only |
| Triple-quoted Python string | Risky | Moderate | Static config templates |
Conclusion
Always use json.dumps() to create JSON strings from Python data. It handles double quotes, backslashes, newlines, and all other special characters correctly and automatically.
Manual escaping with \\" sequences in Python string literals is error-prone, hard to read, and unnecessary in almost every situation. Build your data as normal Python dictionaries and lists, then let the json module serialize them into properly escaped, valid JSON.