How to Export ChatGPT Conversations and Read conversations.json
TL;DR: Request a ChatGPT data export from Settings → Data controls; conversations.json stores each chat as a tree of messages, so read it by following the current branch rather than as a flat list.
ChatGPT’s data export gives you a ZIP with every conversation in a file called conversations.json. The file is not a simple list of messages — it is a tree. This guide shows how to request the export and how to read that tree correctly.
Open conversations.json in the viewer →All guides
Request the export
OpenAI’s help center describes two routes. The usual one is inside ChatGPT:
- Sign in at chatgpt.com.
- Open your profile menu and select Settings.
- Select Data controls.
- Under Export data, select Export, then Confirm export.
ChatGPT then sends an email (or an SMS for phone-only accounts) with a Download data export link. OpenAI says exports can take up to 7 days to arrive, the link expires 24 hours after you receive it, and you must download while signed in to the account that requested it. If you cannot sign in, the second route is the Privacy Portal: Make a Privacy Request → I have a consumer ChatGPT account → Download my data.
Availability: self-service export works for ChatGPT Free, Go, Plus, Pro and eligible Edu workspaces. It is not available in Business, Enterprise or ChatGPT for Healthcare workspaces — contact your workspace owner there. An export cannot bring back chats you already deleted.
Why conversations.json is a tree
When you edit a prompt or regenerate an answer, ChatGPT keeps the old branch. So each conversation stores its messages as nodes in a mapping object, each node pointing to its parent and children, plus a current_node that marks the last message of the branch you were viewing. OpenAI does not document this format, so treat field names as observed, not guaranteed. A trimmed example:
{
"title": "Regex for phone numbers",
"create_time": 1791800000.1,
"current_node": "c",
"mapping": {
"root": { "id": "root", "parent": null, "children": ["a"], "message": null },
"a": { "id": "a", "parent": "root", "children": ["b"],
"message": { "author": { "role": "user" }, "create_time": 1791800000.1,
"content": { "content_type": "text", "parts": ["Write a regex…"] } } },
"b": { "id": "b", "parent": "a", "children": ["c"],
"message": { "author": { "role": "assistant" },
"content": { "content_type": "text", "parts": ["A common pattern is…"] } } },
"c": { "id": "c", "parent": "b", "children": [], "message": { … } }
}
}
- Times are Unix seconds (with a fraction), not ISO strings.
author.rolecan beuser,assistant,systemortool; most readers skip system and tool messages.content.partsis a list; text parts are strings, while images appear as objects (for example withcontent_typeimage_asset_pointer).
Read the branch you actually saw
Do not iterate over mapping in key order — you will mix branches. Instead, start at current_node, follow parent links back to the root, and reverse:
import json
convs = json.load(open("conversations.json", encoding="utf-8"))
def visible_messages(conv):
chain, node = [], conv.get("current_node")
while node:
n = conv["mapping"][node]
chain.append(n)
node = n.get("parent")
for n in reversed(chain):
m = n.get("message")
if not m or m["author"]["role"] not in ("user", "assistant"):
continue
parts = m.get("content", {}).get("parts") or []
text = "\n\n".join(p for p in parts if isinstance(p, str)).strip()
if text:
yield m["author"]["role"], text
for c in convs[:3]:
print("#", c.get("title"))
for role, text in visible_messages(c):
print(f"[{role}] {text[:80]}")
Quick inspections with jq work too, for example listing every title: jq -r '.[].title' conversations.json.
To write every conversation to its own Markdown file, reuse visible_messages() from above:
import pathlib, re, datetime
out = pathlib.Path("chatgpt-md"); out.mkdir(exist_ok=True)
for c in convs:
title = c.get("title") or "Untitled"
day = datetime.datetime.fromtimestamp(c.get("create_time") or 0).date()
body = [f"# {title}", f"_{day}_", ""]
for role, text in visible_messages(c):
body += [f"**{'You' if role == 'user' else 'ChatGPT'}:**", "", text, ""]
name = f"{day}-" + (re.sub(r"[^\w-]+", "-", title).strip("-")[:50] or "chat")
(out / f"{name}.md").write_text("\n".join(body), encoding="utf-8")
No code? Use the viewer
Drop the export ZIP or conversations.json onto our AI Chat Export viewer. It follows current_node the same way as the script above, skips hidden reasoning summaries, shows images as placeholders, and saves any chat as Markdown, Word or PDF. Everything runs in your browser tab; nothing is sent to a server.
What about the other branches?
The current_node walk gives you the version of the conversation you last looked at. If you edited a prompt three times, the other two attempts are still in mapping as sibling nodes — they share a parent but are not on your chain. To keep everything, walk the tree from the root instead and emit each branch separately, or simply list nodes whose children array has more than one entry to see where you branched.
Troubleshooting the export
- Nothing arrived: exports can take up to 7 days. Check inbox, spam and promotions for the account’s email address, or SMS if your account uses only a phone number. After 7 days, contact OpenAI support.
- “Export already requested”: wait for the existing request to finish before submitting another.
- Link will not open: make sure you are signed in to the same account that requested it; if it has expired, request a new export.
- Cannot sign in at all: use the Privacy Portal route instead of Settings.
Tips
- Large accounts produce large files. If a text editor struggles, use the viewer’s search or a streaming JSON tool rather than opening the whole file.
- Before merging a personal workspace into a Business or Enterprise one, OpenAI recommends downloading and checking your export first — afterwards an older export link may stop working.
- The export may contain sensitive data. Keep it local and delete copies you no longer need.
Also see exporting Claude chats and saving Gemini chats.
Sources
Vendor features and prices were checked against these official pages on 2026-10-18. Products change; if something here no longer matches, the official page is right.
- OpenAI Help Center — Exporting your ChatGPT history and data
https://help.openai.com/en/articles/7260999-how-do-i-export-my-chatgpt-history-and-data - OpenAI Privacy Portal
https://privacy.openai.com/