Calculators Converters Developer Tools Finance Tools
Blog About Contact
Dev ToolsJune 8, 20267 min read

How to Convert a String to JSON in Python (loads & dumps)

How to Convert a String to JSON in Python (loads & dumps)

You have JSON data sitting in a Python string - maybe it came from an API response, a config file, or a database field - and you need to work with it as a real Python object. Or you have the reverse problem: a Python dictionary you need to turn into a JSON string to send somewhere. Converting between strings and JSON in Python takes one function call once you know the difference between the four core methods. This guide shows you exactly how to convert a string to JSON, how to go back the other way, and how to avoid the single most common error that trips up beginners.

String to JSON in Python: What's Actually Happening

In Python, "converting a string to JSON" means parsing a text string that contains JSON-formatted data into a native Python object - usually a dictionary or a list. This process is called deserialization. The reverse, turning a Python object back into a JSON string, is called serialization.

The key thing to understand is that JSON maps directly to Python types: a JSON object becomes a Python dict, a JSON array becomes a list, strings become str, numbers become int or float, true/false become True/False, and null becomes None. The built-in json module handles all of this automatically - and because it ships with Python, there is nothing to install. You just need to remember which of its four functions to use, which depends on whether you are working with a string or a file, and which direction you are converting.

How to Convert a String to JSON in Python - Step by Step

The json module gives you four functions. The naming follows a simple rule: functions ending in "s" work with strings, functions without the "s" work with files.

Step 1 - Import the json module

import json

No installation needed - json is part of Python's standard library in every version since Python 2.6.

Step 2 - Use json.loads() to convert a string to JSON

To parse a JSON string into a Python object, use json.loads() - the "s" stands for "string":

json_string = '{"name": "Alice", "age": 30, "active": true}' data = json.loads(json_string) print(data["name"]) # Alice print(data["age"]) # 30 print(type(data)) # <class 'dict'>

The string becomes a Python dictionary you can access with normal key lookups. Notice that JSON's true automatically became Python's True.

Step 3 - Use json.dumps() to convert JSON back to a string

To go the other way - turning a Python object into a JSON string - use json.dumps() (dump-string):

data = {"name": "Alice", "age": 30, "active": True} json_string = json.dumps(data) print(json_string) # {"name": "Alice", "age": 30, "active": true}

For readable, indented output (pretty-printing), add the indent argument:

json_string = json.dumps(data, indent=4)

→ Want to check that your JSON string is valid before parsing it? Paste it into our free JSON Formatter and Validator at GlobalUtilityHub to spot errors instantly - no sign-up needed.

Step 4 - Know the file versions: load() and dump()

When working with files instead of strings, drop the "s":

# Read JSON from a file into a Python object with open("data.json") as f: data = json.load(f) # Write a Python object to a JSON file with open("output.json", "w") as f: json.dump(data, f, indent=4)

Worked Example: Parsing an API Response String

Imagine you called an API and received this response as a string:

response = ''' { "user": "jdoe", "roles": ["editor", "admin"], "settings": {"theme": "dark", "notifications": true}, "last_login": null } '''

Convert it to a usable Python object and access the nested data:

import json data = json.loads(response) print(data["user"]) # jdoe print(data["roles"][1]) # admin print(data["settings"]["theme"]) # dark print(data["last_login"]) # None

Everything just works: the array became a list you can index, the nested object became a nested dictionary, and JSON's null became Python's None. This direct mapping is what makes the json module so convenient - you parse once and then use normal Python syntax.

The Four json Functions at a Glance

This table is the single most useful reference for working with JSON in Python. The "s" suffix is the whole trick.

FunctionDirectionWorks withExample use
json.loads()String → Python objectStringParse an API response string
json.dumps()Python object → StringStringBuild a request body
json.load()File → Python objectFileRead a config.json file
json.dump()Python object → FileFileSave data to a .json file

Common Mistakes to Avoid

Confusing loads() with load(). This is the number one error. Use loads() (with the "s") for strings and load() for file objects. Calling json.load() on a string raises AttributeError: 'str' object has no attribute 'read'. Remember: "s" = string.
Using single quotes in the JSON string. JSON requires double quotes around keys and string values. A string like "{'name': 'Alice'}" with single quotes is not valid JSON and will raise json.JSONDecodeError. Use double quotes inside the JSON, and wrap the whole thing in single quotes in your Python code: '{"name": "Alice"}'.
Forgetting that Python's True becomes JSON's true. When you convert with dumps(), Python's True, False, and None become JSON's true, false, and null (lowercase). This is correct behavior, but it surprises people checking the output string.
Not handling JSONDecodeError. If the string is malformed, json.loads() raises an exception that crashes your program if uncaught. Wrap parsing in a try/except json.JSONDecodeError block when the input might be invalid, such as data from an external source.
Trying to serialize objects json doesn't understand. dumps() handles dicts, lists, strings, numbers, booleans, and None - but not datetime objects, sets, or custom classes. These raise TypeError. Convert them to supported types first, or pass a custom default function.

Working with Deeply Nested JSON Strings

Real API responses are rarely flat. They nest objects inside objects and arrays inside those. The good news is that json.loads() handles any depth automatically - you just navigate the result with normal Python indexing.

Consider a string with several levels of nesting:

json_string = ''' { "company": "Acme", "departments": [ { "name": "Engineering", "lead": {"name": "Alice", "email": "alice@acme.com"}, "headcount": 12 }, { "name": "Sales", "lead": {"name": "Bob", "email": "bob@acme.com"}, "headcount": 8 } ] } ''' data = json.loads(json_string) # Navigate the nested structure print(data["departments"][0]["lead"]["name"]) # Alice print(data["departments"][1]["headcount"]) # 8

Each layer follows the same rule: objects become dictionaries you access by key, and arrays become lists you access by index. To safely access keys that might be missing, use the .get() method, which returns None (or a default you specify) instead of raising a KeyError:

email = data["departments"][0]["lead"].get("email", "no email")

This defensive pattern is essential when parsing data from external APIs, where a field you expect might occasionally be absent. Combining .get() with sensible defaults keeps your code from crashing on incomplete data.

Serializing Dates, Decimals, and Custom Objects

The json.dumps() function knows how to serialize strings, numbers, booleans, lists, dictionaries, and None - but it does not know what to do with a datetime, a Decimal, or your own custom class. Try to serialize one and you get TypeError: Object of type datetime is not JSON serializable.

The cleanest fix is to pass a default function that tells dumps() how to handle unknown types:

import json from datetime import datetime data = {"event": "launch", "timestamp": datetime.now()} json_string = json.dumps(data, default=str) # The datetime is converted to its string representation

Passing default=str converts any unrecognized object to its string form - quick and effective for dates. For more control, write a custom function that handles specific types:

from decimal import Decimal def custom_encoder(obj): if isinstance(obj, datetime): return obj.isoformat() if isinstance(obj, Decimal): return float(obj) raise TypeError(f"Cannot serialize {type(obj)}") json_string = json.dumps(data, default=custom_encoder)

This converts datetimes to clean ISO 8601 strings (like "2026-06-03T14:30:00") and Decimals to floats. The default function is called only for objects json cannot handle on its own, so your normal data passes through untouched. This pattern is how you serialize database query results, which frequently contain datetime and Decimal values.

Controlling the Output: Pretty-Printing, Sorting, and Compact JSON

When you convert a Python object back to a JSON string with json.dumps(), you have several options that control exactly how the output looks. Choosing the right one depends on whether a human or a machine will read the result.

For readable, indented output - ideal for config files, logs, or anything a person will inspect - use the indent parameter:

data = {"name": "Alice", "roles": ["editor", "admin"], "active": True} print(json.dumps(data, indent=2)) # { # "name": "Alice", # "roles": [ # "editor", # "admin" # ], # "active": true # }

To produce the most compact output - ideal for sending over a network or storing efficiently - remove the whitespace that dumps() adds by default after separators:

compact = json.dumps(data, separators=(",", ":")) # {"name":"Alice","roles":["editor","admin"],"active":true}

This strips every unnecessary space, which can meaningfully reduce payload size for large data. To sort keys alphabetically - useful for producing consistent, comparable output (for example, when diffing two JSON files or generating a stable hash) - add sort_keys=True:

print(json.dumps(data, indent=2, sort_keys=True))

One more useful option: when your data contains non-ASCII characters like accented letters or emoji, dumps() escapes them by default (é becomes é). To keep them human-readable in the output, pass ensure_ascii=False:

json.dumps({"city": "São Paulo"}, ensure_ascii=False) # {"city": "São Paulo"} instead of {"city": "São Paulo"}

These four parameters - indent, separators, sort_keys, and ensure_ascii - give you full control over the converted string, letting you tailor it for readability, size, consistency, or internationalization.

Frequently Asked Questions

How do I convert a string to JSON in Python?

Use json.loads() from the built-in json module. Import the module with import json, then call data = json.loads(your_string). This parses the JSON-formatted string into a Python dictionary or list that you can work with directly. The "s" in loads stands for "string" - this is the function for strings, as opposed to load() which is for files.

What is the difference between json.loads() and json.load()?

json.loads() (with an "s") parses a JSON string into a Python object. json.load() (no "s") reads JSON directly from a file object. Use loads() when you already have the JSON as a string in a variable, and load() when you have an open file. The same "s" rule applies to dumps() (to string) versus dump() (to file).

How do I convert JSON to a string in Python?

Use json.dumps() to serialize a Python object (dictionary or list) into a JSON string: json_string = json.dumps(your_object). For human-readable output with indentation, add the indent parameter: json.dumps(your_object, indent=4). This is the reverse of json.loads() and is commonly used when building API request bodies or preparing data to save.

Why am I getting a JSONDecodeError?

A json.JSONDecodeError means the string is not valid JSON. The most common causes are single quotes instead of double quotes, trailing commas after the last item, unquoted keys, or the string being empty or truncated. JSON requires double quotes around all keys and string values. Paste the string into a JSON validator to find the exact problem, and wrap your parsing in a try/except block when the input might be invalid, such as data from an external source.

How do I convert a Python dictionary to a JSON string?

Pass the dictionary directly to json.dumps(): json.dumps(my_dict). Python dictionaries map naturally to JSON objects, so the conversion is direct. Keys become JSON object keys, and values are converted according to their types - strings stay strings, True becomes true, and None becomes null. Add indent=4 for readable, pretty-printed output.

Can I parse a JSON string with single quotes in Python?

Not directly with json.loads(), because JSON requires double quotes. If you have a string with single quotes, you have a Python dictionary literal, not JSON. For trusted internal data you could use ast.literal_eval() to parse it safely as a Python literal, but the correct fix is to ensure your data uses double quotes so it is valid JSON. Never use eval() on untrusted data, as it is a security risk.

How do I convert a string to JSON and keep the order of keys?

Key order is preserved automatically. Since Python 3.7, dictionaries maintain insertion order, and json.loads() returns a regular dictionary that keeps keys in the order they appear in the JSON string. When converting back with json.dumps(), the order is maintained. If you want alphabetical order in the output instead, pass sort_keys=True to dumps().

Is the json module fast enough for large data?

Python's built-in json module is written in C under the hood and is fast enough for most applications, handling megabytes of JSON quickly. For extremely large files or performance-critical applications, third-party libraries like orjson or ujson are significantly faster. For typical API responses and config files, the standard json module is more than sufficient and has the advantage of requiring no installation.

The Bottom Line

Converting a string to JSON in Python is one function call: json.loads() for parsing a string into a Python object, and json.dumps() for the reverse. The whole system clicks into place once you remember the "s" rule - functions with "s" work on strings, functions without it work on files. Watch for single quotes and unhandled decode errors, and the built-in json module will handle everything else.

Before parsing a JSON string, it helps to confirm it is valid. Our JSON Formatter and Validator catches syntax errors in under 30 seconds - try it free at /dev-tools/json-formatter/.

✍️ Written by <em>Written by the GlobalUtilityHub Editorial Team|📅 Last reviewed: June 2026|Fact-checked for accuracy</em>
Ready to try it yourself?

Use our free JSON Formatter to apply what you have learned.

Open JSON Formatter

Frequently Asked Questions

Use json.loads() from the built-in json module. Import the module with import json, then call data = json.loads(your_string). This parses the JSON-formatted string into a Python dictionary or list that you can work with directly. The "s" in loads stands for "string" - this is the function for strings, as opposed to load() which is for files.
json.loads() (with an "s") parses a JSON string into a Python object. json.load() (no "s") reads JSON directly from a file object. Use loads() when you already have the JSON as a string in a variable, and load() when you have an open file. The same "s" rule applies to dumps() (to string) versus dump() (to file).
Use json.dumps() to serialize a Python object (dictionary or list) into a JSON string: json_string = json.dumps(your_object). For human-readable output with indentation, add the indent parameter: json.dumps(your_object, indent=4). This is the reverse of json.loads() and is commonly used when building API request bodies or preparing data to save.
A json.JSONDecodeError means the string is not valid JSON. The most common causes are single quotes instead of double quotes, trailing commas after the last item, unquoted keys, or the string being empty or truncated. JSON requires double quotes around all keys and string values. Paste the string into a JSON validator to find the exact problem, and wrap your parsing in a try/except block when the input might be invalid, such as data from an external source.
Pass the dictionary directly to json.dumps(): json.dumps(my_dict). Python dictionaries map naturally to JSON objects, so the conversion is direct. Keys become JSON object keys, and values are converted according to their types - strings stay strings, True becomes true, and None becomes null. Add indent=4 for readable, pretty-printed output.
Not directly with json.loads(), because JSON requires double quotes. If you have a string with single quotes, you have a Python dictionary literal, not JSON. For trusted internal data you could use ast.literal_eval() to parse it safely as a Python literal, but the correct fix is to ensure your data uses double quotes so it is valid JSON. Never use eval() on untrusted data, as it is a security risk.
Key order is preserved automatically. Since Python 3.7, dictionaries maintain insertion order, and json.loads() returns a regular dictionary that keeps keys in the order they appear in the JSON string. When converting back with json.dumps(), the order is maintained. If you want alphabetical order in the output instead, pass sort_keys=True to dumps().
Python's built-in json module is written in C under the hood and is fast enough for most applications, handling megabytes of JSON quickly. For extremely large files or performance-critical applications, third-party libraries like orjson or ujson are significantly faster. For typical API responses and config files, the standard json module is more than sufficient and has the advantage of requiring no installation.