ChatGPT to JSON – Export & Save Conversations as Structured Data (2026)
Key Takeaways
- JSON is the best format for programmatic use — parse it with Python, jq, or any language to analyze, transform, or automate your ChatGPT conversations.
- Three methods exist: ChatGPT Exporter (instant, clean JSON), OpenAI’s official data export (bulk, complex nested format), and browser DevTools (manual, raw API data).
- OpenAI’s native export uses a tree-based
mappingstructure with parent/child references that requires significant parsing — ChatGPT Exporter gives you a flat, script-ready format instead. - Unique data preserved: Deep Research citations, o1/o3 thinking process, web search sources, and Canvas artifacts — features no other JSON export tool captures.
1. Introduction
JSON (JavaScript Object Notation) is the standard format for structured data exchange — used by virtually every modern web API and supported natively by Python, JavaScript, Go, R, and every other major programming language.
If you want to analyze your ChatGPT conversation patterns, extract code blocks programmatically, build fine-tuning datasets, migrate data between tools, or create a complete backup of your chat history, JSON is the format that gives you full control.
This guide covers every method to export ChatGPT conversations to JSON in 2026. We compare three approaches — from one-click Chrome extensions to OpenAI’s official data export — with real code examples so you can start processing your data immediately. (Looking for a more human-readable format? See our ChatGPT to Markdown guide or ChatGPT to PDF guide.)
2. Why Export ChatGPT to JSON?
- Machine-readable — JSON can be parsed by any programming language with built-in libraries (
jsonin Python,JSON.parse()in JavaScript,encoding/jsonin Go). - Preserves complete data — Every message, role, timestamp, and metadata field is captured in structured form — unlike PDF or plain text, which flatten everything.
- Easy to transform — Convert JSON to CSV, Markdown, HTML, SQL, or any other format with a short script (examples below in Section 5).
- Ideal for data analysis — Load conversations into pandas, jq, or any data tool to analyze patterns, word counts, topics, and response lengths.
- Backup and migration — JSON is the most reliable format for creating complete, lossless backups. You can restore, search, or re-import the data years later.
- API-compatible — JSON is the native format of the OpenAI API. With a simple role mapping, your export can be converted directly to API message format.
- Automation-friendly — Feed JSON data into scripts, workflows, or pipelines (n8n, Make, Zapier) for automated processing.
- Version control — JSON files work with Git, making it easy to track changes and diff conversations over time.
3. Methods to Export ChatGPT to JSON
3.1 ChatGPT Exporter (Recommended)
ChatGPT Exporter is a Chrome extension that exports any ChatGPT conversation to JSON with one click.
How to use it:
- Install ChatGPT Exporter from the Chrome Web Store.
- Open any ChatGPT conversation (regular or group chat).
- Click the Select button to choose which messages to export (All, Questions only, Answers only, or manually check/uncheck individual messages).
- Click Export and select JSON as the format.
- Your
.jsonfile downloads instantly — clean, structured, and ready to use in scripts.
Alternatively, enable the Copy to clipboard option in settings to copy the JSON text directly instead of downloading a file — useful for quickly pasting into scripts or API tools.
What the exported JSON looks like:
The exported file has two top-level sections: metadata (conversation info) and messages (the actual conversation):
{
"metadata": {
"title": "How to Process CSV Files in Python",
"user": {
"name": "John Smith",
"email": "[email protected]"
},
"dates": {
"created": "2026/04/15 14:30:45",
"updated": "2026/04/15 15:22:10",
"exported": "2026/04/17 09:00:33"
},
"link": "https://chatgpt.com/c/abc123-def456"
},
"messages": [
{
"role": "Prompt",
"say": "How do I read a CSV file and filter specific columns in Python?",
"time": "2026/04/15 2:30:45 PM"
},
{
"role": "Response",
"say": "You can use the pandas library:\n\nimport pandas as pd\ndf = pd.read_csv('data.csv')\nresult = df[['name', 'age']]\n\nThis filters the name and age columns.",
"time": "2026/04/15 2:31:22 PM"
}
]
}Notice the clean, flat structure — a messages array you can iterate over directly, with no nested trees or parent/child pointers to traverse.
Metadata Fields
Every field in metadata is individually toggleable in settings:
| Field | Type | Description | Configurable |
|---|---|---|---|
title | string | Conversation title | On/off in settings |
user.name | string | Your display name | On/off independently |
user.email | string | Your email address | On/off independently |
dates.created | string | When the conversation started | Choose which dates to include |
dates.updated | string | Last message time | Choose which dates to include |
dates.exported | string | When the export was created | Choose which dates to include |
link | string | URL to the original conversation | On/off in settings |
Date and time formats are also configurable: choose MDY / DMY / YMD for dates, and hidden / 12-hour / 24-hour for times.
Message Fields
| Field | Type | Description |
|---|---|---|
role | string | "Prompt" (your message) or "Response" (ChatGPT’s reply). In group chats: "Human" and "ChatGPT" |
say | string | The message content as plain text. If a message was not selected for export, this is an empty string "" (the message still appears to preserve conversation structure) |
time | string | Message timestamp (requires “per-message timestamp” option enabled in settings) |
Content Processing
The say field is produced by a processing pipeline — DOM parsing, feature extraction (Deep Research, web search, reasoning), and formatted output — so code blocks, math formulas, and structured content are preserved accurately, not just a raw copy-paste from the browser.
AI-Specific Data Captured
| Feature | What’s included | Configurable |
|---|---|---|
| Deep Research reports | Full report with citation footnotes and source URLs | On/off |
| Web Search sources | Source list with titles and URLs | On/off |
| Thought Process (o1/o3) | Reasoning steps, search queries, thinking process | On/off |
| Code blocks | Complete code with language identifiers | Always included |
| Math formulas (KaTeX) | LaTeX notation preserved | Always included |
| Canvas artifacts | Code and document content from Canvas mode | Always included |
Output Format
- Encoding: UTF-8
- Formatting: 2-space indentation (human-readable)
- File naming:
{prefix}{conversation title}.json— prefix is customizable (default:ChatGPT-), filename is sanitized for OS compatibility and Unicode-normalized (NFC) - MIME type:
application/json
3.2 OpenAI Official Data Export
OpenAI provides a built-in way to export your data:
- Go to Settings → Data Controls → Export Data in ChatGPT.
- Wait for an email with a ZIP file (typically minutes, but can take up to 24 hours).
- Unzip and find
conversations.json.
This gives you a single large JSON file containing all your conversations. However, the structure is significantly more complex — it uses OpenAI’s internal tree-based format:
{
"title": "Conversation Title",
"create_time": 1713350400.0,
"update_time": 1713354000.0,
"mapping": {
"aaa-msg-id-1": {
"id": "aaa-msg-id-1",
"message": {
"author": { "role": "user" },
"content": {
"content_type": "text",
"parts": ["Your message here"]
},
"create_time": 1713350400.0
},
"parent": null,
"children": ["aaa-msg-id-2"]
},
"aaa-msg-id-2": {
"id": "aaa-msg-id-2",
"message": {
"author": { "role": "assistant" },
"content": {
"content_type": "text",
"parts": ["The AI response here"]
},
"create_time": 1713350415.0
},
"parent": "aaa-msg-id-1",
"children": []
}
}
}Why this format is painful to work with:
As discussed extensively in the OpenAI developer community, this tree structure requires you to:
- Traverse backwards through parent pointers to reconstruct conversation order.
- Handle branching — when you edit a prompt, ChatGPT creates a new branch in the tree, so a single conversation can have multiple paths.
- Extract text from nested arrays — message content is buried inside
content.parts[]arrays rather than being a simple string. - Convert Unix timestamps — times are stored as floats (e.g.,
1713350400.0) rather than human-readable formats. - Deal with format changes — community members report that the format has changed over time, and newer features like Canvas, web search, and image generation add additional complexity.
Pros: Complete history in one file; official export; no third-party tools needed.
Cons: Up to 24-hour wait; deeply nested tree structure requiring significant parsing; no selective export; exports everything including conversations you may not want; no real-time export.
3.3 Browser DevTools (Manual)
For technical users who want a quick grab of raw API data:
- Open DevTools (
F12) in your browser. - Go to the Network tab.
- Navigate to or refresh a ChatGPT conversation.
- Filter requests by
conversationorbackend-api. - Find the response containing the conversation data.
- Right-click → Copy response and paste into a
.jsonfile.
Pros: No tools needed; gets the raw API format; instant.
Cons: Requires technical knowledge; tedious for multiple conversations; format varies by API endpoint; no consistent structure across exports; easy to grab incomplete data.
4. Method Comparison
| Feature | ChatGPT Exporter | Official Data Export | Browser DevTools |
|---|---|---|---|
| Install difficulty | Low (Chrome extension) | None | None (technical) |
| Export speed | Instant (one click) | Minutes to 24 hours | Manual per request |
| JSON structure | Clean, flat array | Nested tree | Raw API format |
| Selective export | Yes (per message) | No (all conversations) | Per conversation |
| Per-conversation export | Yes | No (single bulk file) | Yes (manual) |
| Metadata included | Yes (customizable) | Yes | Yes (raw) |
| Deep Research citations | Yes | Partial | Yes (raw) |
| Thought process (o1/o3) | Yes | Partial | Varies |
| Web search sources | Yes | Partial | Varies |
| Canvas artifacts | Yes | No | Varies |
| Timestamp format | Configurable | Unix float | Varies |
| Copy to clipboard | Yes | No | Yes (manual) |
| Ready to use in scripts | Yes | Requires parsing | Requires parsing |
| Real-time export from UI | Yes | No | Yes |
5. What to Do with Exported JSON: 8 Practical Examples
All examples below use the ChatGPT Exporter JSON format (with role, say, and time fields). If you’re using OpenAI’s official export, you’ll need to extract messages from the mapping tree first.
5.1 Analyze Conversations with Python
Load your exported JSON into Python for quick analysis:
import json
from collections import Counter
with open("ChatGPT-my-conversation.json") as f:
data = json.load(f)
# Count messages by role
roles = Counter(msg["role"] for msg in data["messages"])
print(f"Your prompts: {roles.get('Prompt', 0)}")
print(f"AI responses: {roles.get('Response', 0)}")
# Find longest response (skip unselected messages with empty "say")
responses = [m for m in data["messages"] if m["role"] == "Response" and m["say"]]
longest = max(responses, key=lambda m: len(m["say"]))
print(f"Longest response: {len(longest['say'])} chars")
# Average response length
avg = sum(len(m["say"]) for m in responses) // len(responses)
print(f"Average response: {avg} chars")5.2 Extract All Code Blocks
Extract every code block from AI responses — useful for building a personal snippet library:
import json
import re
with open("ChatGPT-my-conversation.json") as f:
data = json.load(f)
for msg in data["messages"]:
if msg["role"] == "Response" and msg["say"]:
blocks = re.findall(r"```(\w+)?\n(.*?)```", msg["say"], re.DOTALL)
for lang, code in blocks:
print(f"--- {lang or 'text'} ---")
print(code)5.3 Convert to CSV for Spreadsheets
Transform JSON into CSV for analysis in Excel or Google Sheets:
import json
import csv
with open("ChatGPT-my-conversation.json") as f:
data = json.load(f)
with open("conversation.csv", "w", newline="", encoding="utf-8") as f:
writer = csv.writer(f)
writer.writerow(["Role", "Content", "Time", "Word Count"])
for msg in data["messages"]:
if msg["say"]: # skip unselected messages
writer.writerow([
msg["role"],
msg["say"],
msg.get("time", ""),
len(msg["say"].split())
])5.4 Build Fine-Tuning Datasets
Convert exported conversations into the OpenAI fine-tuning format (JSONL). The role values need mapping from ChatGPT Exporter format (Prompt/Response) to API format (user/assistant):
import json
ROLE_MAP = {"Prompt": "user", "Response": "assistant"}
with open("ChatGPT-my-conversation.json") as f:
data = json.load(f)
# Convert to OpenAI fine-tuning format
training_data = []
messages = [m for m in data["messages"] if m["say"]] # skip empty
for i in range(0, len(messages) - 1, 2):
if messages[i]["role"] == "Prompt" and messages[i+1]["role"] == "Response":
training_data.append({
"messages": [
{"role": "user", "content": messages[i]["say"]},
{"role": "assistant", "content": messages[i+1]["say"]}
]
})
with open("training.jsonl", "w") as f:
for item in training_data:
f.write(json.dumps(item) + "\n")
print(f"Created {len(training_data)} training examples")5.5 Process with jq (Command Line)
Use jq for instant command-line analysis without writing code:
# Count total messages
jq '.messages | length' ChatGPT-my-conversation.json
# Get all your prompts (non-empty only)
jq -r '.messages[] | select(.role == "Prompt" and .say != "") | .say' ChatGPT-my-conversation.json
# Show conversation title and message count
jq '{title: .metadata.title, messages: (.messages | length)}' ChatGPT-my-conversation.json
# Count messages by role
jq '[.messages[].role] | group_by(.) | map({(.[0]): length}) | add' ChatGPT-my-conversation.json
# Word count per AI response
jq '.messages[] | select(.role == "Response" and .say != "") | {words: (.say | split(" ") | length)}' ChatGPT-my-conversation.json5.6 Import into SQLite
Load conversation data into a SQLite database for SQL-based querying:
import json
import sqlite3
with open("ChatGPT-my-conversation.json") as f:
data = json.load(f)
conn = sqlite3.connect("chatgpt.db")
conn.execute("""
CREATE TABLE IF NOT EXISTS messages (
id INTEGER PRIMARY KEY,
role TEXT,
content TEXT,
time TEXT,
word_count INTEGER
)
""")
for msg in data["messages"]:
if msg["say"]: # skip unselected messages
conn.execute(
"INSERT INTO messages (role, content, time, word_count) VALUES (?, ?, ?, ?)",
(msg["role"], msg["say"], msg.get("time", ""), len(msg["say"].split()))
)
conn.commit()
print(f"Imported {sum(1 for m in data['messages'] if m['say'])} messages into chatgpt.db")Then query with SQL:
-- Message stats by role
SELECT role, COUNT(*) as count, AVG(word_count) as avg_words
FROM messages GROUP BY role;
-- Full-text search across all messages
SELECT role, content FROM messages WHERE content LIKE '%repository pattern%';5.7 Feed to Other AI Tools
Export a ChatGPT conversation as JSON and feed it to another AI for structured analysis:
- Load into Claude or Gemini for a different perspective on the same conversation.
- Use as input for AI-powered summarization, translation, or sentiment analysis pipelines.
- Import into LangChain or LlamaIndex for building retrieval-augmented generation (RAG) systems.
JSON preserves the exact structure and role labels, making it the ideal format for programmatic AI-to-AI workflows — unlike PDF, which loses structure when ingested.
5.8 Create Version-Controlled Backups
Store exported JSON files in a Git repository for version-controlled backups:
mkdir chatgpt-archive && cd chatgpt-archive
git init
# After each export, add and commit
git add ChatGPT-python-api-design.json
git commit -m "Export: Python API Design conversation"This gives you a full history of your exports with diffs, timestamps, and the ability to restore any version.
6. JSON vs Other Export Formats
| Feature | JSON | Markdown | TXT | CSV | |
|---|---|---|---|---|---|
| Machine-readable | Yes | Partial | No | No | Yes |
| Human-readable | Moderate | Yes | Yes | Yes | Yes |
| Preserves structure | Full (nested) | Partial | Visual only | No | Flat only |
| Preserves metadata | Yes | Optional | No | No | Optional |
| Editable after export | Yes | Yes | No | Yes | Yes |
| Programmable | Yes | Partial | No | No | Yes |
| Works with note-taking apps | No | Yes | Limited | Yes | No |
| File size | Medium | Small | Large | Small | Small |
| Version control friendly | Yes | Yes | No | Yes | Yes |
| Data analysis ready | Yes | No | No | No | Yes |
When to use each format:
- JSON — When you plan to analyze, transform, or programmatically process conversations. Best for developers, data analysts, and automation workflows.
- Markdown — When you want to read, edit, or integrate conversations into knowledge management tools (Obsidian, Notion, GitHub).
- PDF — When you need to share a formatted document with others who don’t use technical tools.
7. Tips for Better JSON Exports
7.1 Use Selective Export for Cleaner Data
Don’t export entire conversations when you only need specific exchanges. Use ChatGPT Exporter’s selection feature to pick only the relevant messages — unselected messages still appear in the JSON (to preserve conversation structure) but with an empty say field, making them easy to filter out in code: [m for m in data["messages"] if m["say"]].
7.2 Validate Your JSON
After exporting, confirm the file is well-formed before processing:
# Using jq (install: brew install jq / apt install jq)
jq . ChatGPT-my-conversation.json > /dev/null && echo "Valid JSON"
# Using Python (no install needed)
python3 -m json.tool ChatGPT-my-conversation.json > /dev/null && echo "Valid JSON"7.3 Use jq Before Writing Code
Before writing a full Python script, explore your data interactively with jq:
# Pretty-print to understand the structure
jq '.' ChatGPT-my-conversation.json | head -30
# Quick look at metadata
jq '.metadata' ChatGPT-my-conversation.json
# Count messages by role
jq '[.messages[].role] | group_by(.) | map({(.[0]): length}) | add' ChatGPT-my-conversation.json7.4 Combine Multiple Exports
If you export multiple conversations separately, merge them into a single dataset:
import json
import glob
all_conversations = []
for file in sorted(glob.glob("ChatGPT-*.json")):
with open(file) as f:
conv = json.load(f)
all_conversations.append({
"title": conv["metadata"]["title"],
"exported": conv["metadata"]["dates"]["exported"],
"messages": [m for m in conv["messages"] if m["say"]]
})
with open("all-conversations.json", "w") as f:
json.dump(all_conversations, f, indent=2, ensure_ascii=False)
print(f"Merged {len(all_conversations)} conversations")7.5 Keep Metadata Enabled
ChatGPT Exporter includes metadata (title, timestamps, user info, conversation link) in the JSON output. Keep these fields enabled — they’re essential for sorting, filtering, and organizing your exports when you accumulate dozens of files. The dates.exported field is particularly useful for tracking when each backup was taken.
8. Frequently Asked Questions
Q1: Can ChatGPT export to JSON natively?
Yes — but only via the bulk data export (Settings → Data Controls → Export Data), which exports all conversations in a single file with a complex nested structure. For per-conversation JSON export with a clean, flat structure, use ChatGPT Exporter.
Q2: What’s the difference between ChatGPT Exporter’s JSON and OpenAI’s official export?
ChatGPT Exporter produces a flat structure with metadata and messages — each message has role ("Prompt" / "Response") and say (the text content), ready to iterate in a loop. OpenAI’s export uses a tree-based mapping with parent/child references, content buried in parts[] arrays, and Unix float timestamps, requiring significant parsing. See Section 3 for a detailed comparison.
Q3: Can I convert the JSON export to other formats?
Yes — JSON is the most versatile starting point. You can convert it to CSV (Section 5.3), JSONL for fine-tuning (Section 5.4), SQL databases (Section 5.6), or any other format with a short script.
Q4: How large are the JSON export files?
A typical conversation (50-100 messages) produces a JSON file of 50-200 KB. Long conversations with code blocks can reach 500 KB or more. This is slightly larger than Markdown or TXT but much smaller than PDF.
Q5: Are Deep Research reports included in JSON exports?
Yes. ChatGPT Exporter captures the complete Deep Research report including citation footnotes with source URLs. This is exclusive to ChatGPT Exporter — OpenAI’s official export and other tools do not fully preserve Deep Research data.
Q6: Does it preserve code blocks in the JSON?
Yes. The content processing pipeline converts code blocks to plain text while preserving language identifiers and the complete code content. You can extract them programmatically using regex — see Section 5.2 for a working example.
Q7: Is the JSON export feature free?
Yes, JSON export is available in the free version of ChatGPT Exporter. No account or subscription required.
Q8: Can I export only the AI responses without my prompts?
Yes. Click Select and choose Answers to select only ChatGPT’s responses. You can also manually check/uncheck individual messages. Unselected messages still appear in the JSON for structural context, but with an empty say field — easy to filter out in code.
Q9: Can I use the exported JSON with the OpenAI API?
Yes, with a simple role mapping. ChatGPT Exporter uses "Prompt" and "Response" as role labels, while the API uses "user" and "assistant". Map them with a dictionary: {"Prompt": "user", "Response": "assistant"}. See Section 5.4 for a complete fine-tuning conversion example.
Q10: Does it work with group conversations?
Yes. For group chats (ChatGPT’s /gg/ paths), the role labels automatically switch to "Human" and "ChatGPT" instead of "Prompt" / "Response". All participants’ messages are preserved with the same metadata and settings.
9. Conclusion
JSON is the power-user format for ChatGPT exports. When you need to analyze conversation patterns, extract code blocks, build training datasets, or automate data workflows, JSON gives you the complete, structured data to do it — unlike PDF or plain text, which lock your data in human-readable-only formats.
While OpenAI’s official data export provides JSON, its complex nested structure and multi-hour wait time make it impractical for everyday use. ChatGPT Exporter gives you clean, well-structured JSON in a single click — with a flat metadata + messages format, selective export, configurable metadata, and AI-specific features (Deep Research citations, o1/o3 reasoning, web search sources) that no other tool captures.
Get started today: