I was cleaning up my Claude Code account and realized I had over 300 archived sessions sitting in the sidebar. The web UI at claude.ai/code lets you filter by status—Active, Archived, or All—but there’s no bulk delete. Just a tiny trash icon on each row.
I wasn’t going to click that 300 times.
The Script
Go to claude.ai/code, open the browser console (Cmd+Option+J on Mac, Ctrl+Shift+J on Windows), and paste this:
(async () => {
const headers = {
"anthropic-beta": "ccr-byoc-2025-07-29",
"anthropic-client-feature": "ccr",
"anthropic-client-platform": "web_claude_ai",
"anthropic-version": "2023-06-01",
"content-type": "application/json"
};
// Fetch all session IDs (handles pagination)
let allIds = [];
let url = '/v1/sessions';
while (url) {
const resp = await (await fetch(url, { headers })).json();
const sessions = resp.data || resp;
sessions.forEach(s => allIds.push(s.id));
url = resp.has_more && resp.last_id
? '/v1/sessions?after_id=' + resp.last_id
: null;
}
console.log(`Found ${allIds.length} sessions. Deleting...`);
// Delete in batches of 10
let deleted = 0, failed = 0;
for (let i = 0; i < allIds.length; i += 10) {
const batch = allIds.slice(i, i + 10);
await Promise.all(batch.map(id =>
fetch('/v1/sessions/' + id, { method: 'DELETE', headers, body: '{}' })
.then(r => r.ok ? deleted++ : failed++)
.catch(() => failed++)
));
console.log(`Progress: ${deleted + failed}/${allIds.length} (deleted=${deleted}, failed=${failed})`);
}
console.log(`Done! Deleted ${deleted}, failed ${failed}`);
location.reload();
})(); How It Works
The script calls GET /v1/sessions to fetch all your sessions, handling pagination automatically (the API returns 200 sessions per page). Then it fires DELETE /v1/sessions/{id} for each one, 10 at a time to avoid overwhelming the server.
No API keys or tokens needed—the script runs in the context of your already-authenticated browser session.
Why Not Click the UI?
I tried that first. The DOM-based approach—clicking the trash icon, confirming the dialog, repeating—has a few problems:
- JavaScript
.click()doesn’t reliably trigger React’s event handlers. The toast says “Session deleted” but the actual API call sometimes doesn’t fire. - The session list is paginated. The sidebar only renders 20-25 sessions at a time, but the API can return hundreds. You’d need to scroll, wait for lazy loading, and run the script again.
- It’s slow. Each delete cycle needs ~1.2 seconds for the UI animation. With 300 sessions, that’s 6 minutes of watching a progress bar. The API approach finishes in under 30 seconds.
The API approach skips all that and goes straight to the source.