Skip to content

Instantly share code, notes, and snippets.

@drscotthawley
Created May 14, 2026 02:37
Show Gist options
  • Select an option

  • Save drscotthawley/130adba1999c2da7b6415c0d37e6ba27 to your computer and use it in GitHub Desktop.

Select an option

Save drscotthawley/130adba1999c2da7b6415c0d37e6ba27 to your computer and use it in GitHub Desktop.
Download Claude Convos -- Paste into Browser JS Console
(async function exportClaude() {
const log = msg => console.log(`[Export] ${msg}`);
log('Starting...');
const orgsResp = await fetch('/api/organizations', {credentials: 'include'});
const orgs = await orgsResp.json();
const orgId = orgs?.[0]?.uuid || orgs?.[0]?.id;
if (!orgId) { log('ERROR: no org ID'); return; }
log('Org ID: ' + orgId);
const conversations = [];
const seenIds = new Set();
let offset = 0;
while (true) {
const url = `/api/organizations/${orgId}/chat_conversations?limit=100&offset=${offset}&sort_by=updated_at&order=desc`;
const r = await fetch(url, {credentials: 'include'});
const batch = await r.json();
const items = Array.isArray(batch) ? batch : (batch.conversations || batch.data || []);
if (!items.length) break;
let added = 0;
for (const item of items) {
const id = item.uuid || item.id;
if (!seenIds.has(id)) { seenIds.add(id); conversations.push(item); added++; }
}
log(`${conversations.length} conversations (${added} new)...`);
if (added === 0 || items.length < 100) break;
offset += 100;
await new Promise(r => setTimeout(r, 150));
}
log(`Fetching full content for ${conversations.length} conversations...`);
const full = [];
for (let i = 0; i < conversations.length; i++) {
const c = conversations[i];
const id = c.uuid || c.id;
if ((i + 1) % 25 === 0) log(`[${i+1}/${conversations.length}]`);
try {
const r = await fetch(`/api/organizations/${orgId}/chat_conversations/${id}`, {credentials: 'include'});
full.push(await r.json());
} catch(e) { full.push(c); }
await new Promise(r => setTimeout(r, 250));
}
window.__claudeExport = full;
log(`Done fetching. Click the red banner on the page to download.`);
const blob = new Blob([JSON.stringify(full, null, 2)], {type: 'application/json'});
const blobUrl = URL.createObjectURL(blob);
const banner = document.createElement('div');
banner.style.cssText = 'position:fixed;top:0;left:0;right:0;z-index:99999;background:#c0392b;padding:16px;text-align:center;';
const link = document.createElement('a');
link.href = blobUrl;
link.download = `claude_export_${new Date().toISOString().slice(0,10)}.json`;
link.style.cssText = 'color:white;font-weight:bold;font-size:20px;font-family:sans-serif;';
link.textContent = 'CLICK HERE TO DOWNLOAD YOUR CONVERSATIONS';
banner.appendChild(link);
document.body.appendChild(banner);
})();
@drscotthawley

Copy link
Copy Markdown
Author

Needed this because my old email address stopped working, and there's absolutely no way that Anthropic would let me download my data apart from sending a link to that old address.

This will slowly bundle up your conversations and then provide a download link in the main browser window that will download a massive JSON file. Better than nothing.

@drscotthawley

Copy link
Copy Markdown
Author

And here's a script for downloading Projects:

(async function exportProjects() {
  const log = msg => console.log(`[Projects] ${msg}`);
  const orgsResp = await fetch('/api/organizations', {credentials: 'include'});
  const orgs = await orgsResp.json();
  const orgId = orgs?.[0]?.uuid || orgs?.[0]?.id;
  log('Org ID: ' + orgId);

  const r = await fetch(
    `/api/organizations/${orgId}/projects?include_harmony_projects=true&limit=200&creator_filter=is_creator`,
    {credentials: 'include'}
  );
  const projects = await r.json();
  log(`Found ${projects.length} projects. Fetching details...`);

  const full = [];
  for (let i = 0; i < projects.length; i++) {
    const p = projects[i];
    const id = p.uuid || p.id;
    log(`[${i+1}/${projects.length}] ${p.name || id}`);
    try {
      const r2 = await fetch(`/api/organizations/${orgId}/projects/${id}`, {credentials: 'include'});
      full.push(await r2.json());
    } catch(e) { full.push(p); }
    await new Promise(r => setTimeout(r, 200));
  }

  window.__projectExport = full;
  log('Done fetching. Click the banner to download.');

  const blob = new Blob([JSON.stringify(full, null, 2)], {type: 'application/json'});
  const blobUrl = URL.createObjectURL(blob);
  const banner = document.createElement('div');
  banner.style.cssText = 'position:fixed;top:0;left:0;right:0;z-index:99999;background:#27ae60;padding:16px;text-align:center;';
  const link = document.createElement('a');
  link.href = blobUrl;
  link.download = `claude_projects_${new Date().toISOString().slice(0,10)}.json`;
  link.style.cssText = 'color:white;font-weight:bold;font-size:20px;font-family:sans-serif;';
  link.textContent = 'CLICK HERE TO DOWNLOAD YOUR PROJECTS';
  banner.appendChild(link);
  document.body.appendChild(banner);
})();

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment