Created
May 14, 2026 02:37
-
-
Save drscotthawley/130adba1999c2da7b6415c0d37e6ba27 to your computer and use it in GitHub Desktop.
Download Claude Convos -- Paste into Browser JS Console
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| (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); | |
| })(); |
Author
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
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.