Home ยป How to Export and Archive Your AI Chat History
How to Export and Archive Your AI Chat History

How to Export and Archive Your AI Chat History

Figures on this page were verified 31 August 2026 against the providers' own documentation. Pricing, context windows and rate limits change without notice, so confirm any number against the provider before you rely on it. Tell us if something here is out of date.

Your chat history is the least portable thing you own, and the moment you need it is usually the moment you cannot get it. Every major provider offers a data export, and the reliable pattern is the same everywhere: request an export, receive a JSON archive, then convert it into something searchable that you actually control.

Why bother

  • Search that works. Built-in search is usually title-based. Grep over an archive is not.
  • Account risk. A suspended or lapsed account can take the history with it.
  • Portability. Moving providers should not mean abandoning a year of working notes.
  • Reuse. Prompts you refined over months are worth extracting into a library.
  • Compliance. If work conversations contain client information, someone will eventually ask what you hold.

The general pattern

Provider interfaces move, so rather than click-paths, know the shape of the process. It is consistent across vendors.

  1. Request the export from account or privacy settings. It is asynchronous, not an instant download.
  2. Wait for an email with a link. Links usually expire within days, so collect it promptly.
  3. Download an archive, typically a zip containing JSON, sometimes with an HTML viewer.
  4. Convert it into your own format immediately, because raw exports are not readable at scale.

The fourth step is the one people skip, and it is the one that determines whether the export is ever useful. A 40 MB JSON file in a downloads folder is not an archive.

Convert to Markdown you can grep

import json, re, pathlib, datetime

def slug(text, n=60):
    s = re.sub(r"[^a-z0-9]+", "-", (text or "untitled").lower()).strip("-")
    return s[:n] or "untitled"

def export(path, out_dir="archive"):
    data = json.loads(pathlib.Path(path).read_text(encoding="utf-8"))
    out = pathlib.Path(out_dir); out.mkdir(exist_ok=True)
    for convo in data:
        title = convo.get("title") or "untitled"
        ts = convo.get("create_time") or 0
        date = datetime.date.fromtimestamp(ts) if ts else "undated"
        lines = [f"# {title}", f"_Exported {date}_", ""]
        for msg in convo.get("messages", []):
            role = msg.get("role", "?")
            text = msg.get("content", "")
            lines += [f"## {role}", text, ""]
        (out / f"{date}-{slug(title)}.md").write_text(
            "n".join(lines), encoding="utf-8")

# Field names vary between providers. Print one record first
# and adjust the keys rather than assuming this schema fits.

One file per conversation, named by date and title, means grep -ri "postgres migration" archive/ answers in a second. That is the whole point.

Treat the archive as sensitive

An export is a concentrated record of everything you have discussed, which frequently includes pasted configuration, error output and occasionally credentials. It deserves more care than the conversations did individually.

  • Store it encrypted, not in a synced folder shared with a team.
  • Scan for credentials before committing anything anywhere. The patterns in keeping secrets out of prompts work here too.
  • Add the archive directory to .gitignore before you write the first file, not after.
  • Delete old download links and the original zip once converted.

Make it a habit

Exports are point-in-time, so a single one ages immediately. A quarterly reminder is enough, and the conversion script means each round costs a few minutes. The alternative is discovering the gap at exactly the moment the history matters.

Frequently asked questions

How do chat exports work?

The pattern is the same across providers: request the export from account settings, wait for an emailed link that expires within days, download a zip of JSON, then convert it immediately. That last step is the one people skip and the one that decides whether the export is ever useful.

What format should I convert to?

One Markdown file per conversation, named by date and title. That makes a plain grep across the archive answer in a second, which built-in search usually cannot do because it only matches titles.

How should I store the archive?

As sensitive data. An export is a concentrated record of everything you have discussed, frequently including pasted configuration, error output and occasionally credentials. Encrypt it, scan for secrets, and add the directory to gitignore before writing the first file.

Chirag Darji

Chirag Darji is the founder of VGraple and the editor of It's About You. He writes about the LLM APIs and developer tooling he works with, and every figure published here is checked against the provider's own documentation before it goes live, with the date it was verified shown on the page.

More Reading

Post navigation