#Perplexity#Automation#Privacy#Scripts#Hacking

How to Delete All Perplexity AI History (UPD SEP26)

November 28, 2025 (9 months ago)
Updated September 11, 2026 (1 day ago)
5 min read
csmit195

/bin/scripts/purge_perplexity.js

Updated September 11, 2026: Perplexity changed the internals this tool relies on, and the old version stopped working. The source code and bookmarklet below are working again. Sorry for the delay in getting this fixed.

I love Perplexity. It has effectively replaced Google for me. But my history is a graveyard of half-baked thoughts, random debugging queries, and "how to center a div" searches that I don't need to see again. So I created a bookmarklet that deletes your saved Perplexity session history—including pinned sessions. Copy the updated code below, or read on to learn how it works.

The Tool

Fast, one‑click cleanup once it's set up.

  1. Log in to perplexity.ai and click Copy Bookmarklet Code.
  2. Create a new bookmark and paste the code into the URL field.
  3. Name it (for example Clear Perplexity) and click it while on perplexity.ai.

Option 2: The Source Code

For those who prefer to see everything. You get the full, unminified script that the bookmarklet runs.

  1. Open your browser's developer console (F12).
  2. Click Copy Source Code to copy the script.
  3. Paste it into the console and press Enter.
  4. Follow the on‑screen prompts.

Both options contain the same updated cleaner. If your browser strips the javascript: prefix from the bookmark, use Copy Source Code and run it directly in the console instead.

The Discovery

The cleaner uses the same authenticated internal endpoints as Perplexity's web app. The 2026 update now warms the logged-in session, discovers both regular and pinned sessions, deduplicates them, and supports both entry and context UUIDs before deleting anything.

The modal still shows the total first and asks for confirmation. Deletions run in measured batches, report partial failures instead of pretending everything succeeded, and refresh the page when the cleanup completes.

Under the Hood

For the developers out there, here is how it works.

The Constants & Setup

Perplexity includes an API version in its own network requests. The updated script discovers that version from the browser's resource timing entries and falls back to 2.18 when none is available. Scanning and deletion use separate batch sizes so each can be tuned safely.

javascript
const API_VERSION = (() => {
  const patterns = [
    "/rest/user/info",
    "/rest/thread/list_ask_threads",
    "/rest/thread/list_pinned_ask_threads",
    "/rest/sidebar",
  ];

  for (const entry of performance.getEntriesByType("resource")) {
    if (!patterns.some((pattern) => entry.name.includes(pattern))) continue;
    const version = new URL(entry.name).searchParams.get("version");
    if (version) return version;
  }

  return "2.18";
})();

const PAGE_SIZE = 50;
const DELETE_BATCH_SIZE = 64;
const DELETE_DELAY_MS = 800;
const SCAN_RETRIES = 3;

The UI Injection

Since we're running in the console context, we can't rely on React or the existing page structure. We have to inject our own UI. I created a self-contained overlay using standard DOM APIs and injected a style block to make it match the site's dark theme.

javascript
function createOverlay() {
  // ... removal of existing overlay ...
  
  overlay = document.createElement('div');
  overlay.id = 'perplexity-cleaner-overlay';
  // ... innerHTML construction for modal ...

  const style = document.createElement('style');
  style.textContent = `#perplexity-cleaner-overlay { ... }`; // CSS styles
  document.head.appendChild(style);
  document.body.appendChild(overlay);
  
  // ... grabbing references to elements ...
}

The API Client

This is the heavy lifter. Requests are built against the current page origin, include the logged-in browser's credentials, and send the app/version headers Perplexity expects. The updated version also parses useful API error details instead of reducing every failure to a status code.

javascript
async function apiCall(path, method, body, reason) {
  const url = new URL(path, location.origin);
  url.searchParams.set("version", API_VERSION);
  url.searchParams.set("source", "default");

  const response = await fetch(url, {
    method,
    credentials: "include",
    headers: {
      "Content-Type": "application/json",
      "X-App-ApiClient": "default",
      "X-App-ApiVersion": API_VERSION,
      "X-Perplexity-Request-Endpoint": url.toString(),
      "X-Perplexity-Request-Reason": reason,
    },
    body: body == null ? undefined : JSON.stringify(body),
  });

  // Parse the response and surface any useful error details.
  // See the full source for the complete implementation.
}

The Discovery Loop

Perplexity paginates regular sessions and exposes pinned sessions separately. The cleaner warms the authentication session, fetches both lists, retries an initially empty response, then deduplicates records by uuid or context_uuid.

javascript
async function fetchAllThreads() {
  await warmSession();
  const [regular, pinned] = await Promise.all([
    fetchRegularThreads(),
    fetchPinnedThreads(),
  ]);

  const merged = [];
  const seen = new Set();

  for (const thread of [...pinned, ...regular]) {
    const key = thread.uuid || thread.context_uuid;
    if (!key || seen.has(key)) continue;
    seen.add(key);
    merged.push(thread);
  }

  return merged;
}

The Deletion Logic

Once we have the identifiers, we convert them into deletion targets and batch them into groups of 64. Each request can include both entry_uuids and context_uuids. An 800ms pause between batches avoids hammering the endpoint, while per-item failure accounting keeps the final result honest.

javascript
async function deleteThreads(targets) {
  let deleted = 0;
  let failed = 0;

  for (let i = 0; i < targets.length; i += DELETE_BATCH_SIZE) {
    const batch = targets.slice(i, i + DELETE_BATCH_SIZE);
    const result = await deleteThreadBatch(batch);
    const batchFailures = countBatchFailures(result, batch);
    failed += batchFailures;
    deleted += batch.length - batchFailures;

    if (i + DELETE_BATCH_SIZE < targets.length) {
      await wait(DELETE_DELAY_MS);
    }
  }
}

I will be publishing more useful tools like this in the future, hope this helps someone.

Warning

This script is a blunt instrument. It does not ask "are you sure?" for individual threads. Once you confirm the total count, it deletes everything. There is no undo button, no trash can, and no recovery.

Use it wisely.

<terminate_session />

END_OF_TRANSMISSION

< READY_TO_COLLABORATE />

Currently accepting contracts for Automation Architecture, Security Research, and AI Implementations.

SYS_TIME:
MEM: 120MB

© 2026 csmit195. All systems nominal.

now on svelte-kit!