Skip to content

pplx-export

pplx-export is the archiver CLI: it pulls conversation indexes from Perplexity, exports threads into the local archive, and maintains the derived views (space index, cron snippet). This page covers the capture-side subcommands — index, space-index, export, batch, spaces, sync-space, schedule. The backfill/repair subcommands live in maintenance-commands.md; the query CLI is covered in pplx-ask.md.

Common options

Every subcommand accepts these flags (defined once in pplx_export/commands/common.py):

Flag Meaning Default
--account NAME Target account. When the cookie's email doesn't match the registered email, per-account browser session tokens are enumerated to switch automatically default_account from the user-level config
--config PATH User-level config file (account registry). Priority: --config > env PPLX_EXPORT_CONFIG > ~/.config/pplx-export/config.toml default lookup chain
--site NAME Site adapter perplexity
--out DIR Archive output root ./web_archive
--cookies-from BROWSER Import cookies from a browser (edge/chrome/firefox/safari/brave…)
--cookies FILE Netscape cookie file or JSON cookie file
--transport MODE cookie = cookie-direct requests; webbridge = fetch inside the browser page context cookie
-v, --verbose DEBUG output (request traces, internal decisions); repeatable off
--log-file [PATH] Write the full log to disk; without a value, auto path <out>/index/logs/<cmd>-<timestamp>.log off
  • --cookies-from / --cookies are mutually exclusive with --transport webbridge — the bridge runs in the page context and already carries the browser's cookies.
  • pplx-export --version prints the package version and exits (top-level only, not a subcommand flag).
  • Account registration, cookie sources and multi-account switching: configuration.md. Where everything lands on disk: archive-layout.md.

index

Fetch the account's full conversation list (GraphQL) and write the master index index/library_<account>.json — the baseline every other command diffs against.

Flag Meaning Default
(common options only)

Key behaviors:

  • Preserves the search_mode enrichment written by search-mode-backfill: index rows don't carry it natively, so on refresh it is merged back from the old index by entryUUID.
  • Run it before batch, sync-space and sync-deleted — their diffs are only as fresh as this index.
pplx-export index --account alice

space-index

Extract one space's "All" conversation list — including threads shared by other members — into index/space_<slug>.json.

Flag Meaning Default
SPACE_URL (positional) Space page URL required
--transport webbridge Use the legacy browser-rendering path instead of REST cookie (REST direct)

Key behaviors:

  • Default path is REST direct: list_collection_threads over the cookie transport with offset pagination; rows include context_uuid and answer_preview.
  • With --transport webbridge it falls back to scrolling the rendered space page and scraping row props — a backup in case the REST structure changes.
  • Rows are written newest-first by lastUpdated.
pplx-export space-index "https://www.perplexity.ai/spaces/<space-slug>" --account alice

export

Export a single thread (URL or bare UUID) into its archive directory <out>/<account-folder>/<mode>/<thread-dir>/.

Flag Meaning Default
THREAD (positional) Thread URL or UUID required
--force Re-export even when lastUpdated is unchanged off

Key behaviors:

  • If the archived copy is already up to date, the export is skipped with no writes; --force overrides the check.
  • lastUpdated is taken from the local library index when the thread is listed there (same semantics and format as batch), falling back to the platform value otherwise.
  • Terminal states are registered gracefully, without a traceback: ENTRY_DELETED marks deleted in batch_state.json, ENTRY_EXPIRED marks expired — the existing local archive is kept untouched either way.
  • A successful export writes ok into index/batch_state.json, so the incremental plan counts the thread as "exported and unchanged".
  • What lands in the thread directory: archive-layout.md; the export pipeline itself: ../design/export-pipeline.md.
pplx-export export "https://www.perplexity.ai/search/<thread-uuid>" --account alice

batch

Bulk-export an account's threads — the daily driver, with incremental early stop and resumable checkpoints.

Flag Meaning Default
--force Re-export all threads (terminal states excluded) off
--full Full scan: unchanged threads are still skipped, but no early stop off
--limit N Process only the first N rows of the list (newest first) all
--mode MODE Export only search / deep-research / computer / council / study threads all modes
--delay-min SEC Lower bound of the random interval between threads 10
--delay-max SEC Upper bound of the random interval between threads 20

Key behaviors:

  • Requires index/library_<account>.json — run index first.
  • Default incremental early stop: the list is sorted newest-first and the trailing run of "exported and unchanged" threads is trimmed wholesale; gaps left by interrupted runs (error/never-exported) sit above that suffix and are still repaired. --full disables early stop (periodic backstop, or when archive gaps are suspected); --force re-exports everything except terminal states, which are never retried. Full semantics: incremental-sync.md.
  • --mode filtering: rows carrying search_mode (the platform-authoritative field enriched by search-mode-backfill) match exactly via SEARCH_MODE_MAP — on that path --mode search no longer pulls in deep-research/council/study threads. Rows without search_mode fall back to index heuristics: computer = mode COMPUTER; deep-research = displayModel pplx_alpha; council = pplx_agentic_research; study = pplx_study; search = the remaining mode-SEARCH rows (including those three kinds — filter them out precisely by exporting the specific modes separately).
  • State is saved to index/batch_state.json after every thread — interrupt and rerun freely.
  • Auth fail-fast: 3 consecutive 401/403 responses abort the run (an expired cookie cannot self-heal, and spinning on would fail hundreds of threads one by one).
  • Pacing: a random --delay-min--delay-max pause between threads; 429/5xx are backed off by the transport layer. Details: rate-limiting.md.
  • Threads hitting rewritten-answer variants are registered in index/answer_variants_log.jsonl with a warning to handle them manually as soon as possible (see ../design/api-responses-errors.md).
pplx-export batch --account bob --mode deep-research --limit 50

spaces

Rebuild the space-view index — one Markdown page per space plus a spaces.json registry — from the local library indexes.

Flag Meaning Default
--fetch-meta Refresh owner/member metadata before rebuilding off

Key behaviors:

  • Without --fetch-meta the command is purely local (zero network): it aggregates threads per space slug across all library_*.json files, with participating-account stats and backlinks to the exported thread directories.
  • Output goes to ./spaces/ relative to the current working directory — run it from the directory containing web_archive/ so the backlinks in the space pages resolve.
  • --fetch-meta first refreshes each space's owner/member cache via get_collection (1 request per space, 3s interval) into index/space_meta.json; when the current account cannot see a space, an account that can is retried automatically (cookies switch on their own).
pplx-export spaces --fetch-meta --account alice

sync-space

Sync the space field of already-archived thread.json files with the current index — purely local, zero network.

Flag Meaning Default
(common options only; only --out matters)

Key behaviors:

  • Prerequisite: run index first — the refreshed library_*.json is the source of truth for current space ownership.
  • Compares space slugs per thread and patches thread.json in place on divergence; the first 30 changes are logged.
  • After any change, the spaces/ index is rebuilt automatically alongside.
pplx-export index --account alice && pplx-export sync-space

schedule

Compute this round's incremental export plan and write a cron snippet the system cron can call directly.

Flag Meaning Default
(common options only)

Key behaviors:

  • Fetches a live index and reports the plan as total/new/updated counts, using the same early-stop pure function (plan_incremental) as batch — see incremental-sync.md.
  • Writes <out>/index/cron_snippet.txt containing one 17 3 * * * line of the form cd '<archive-parent>' && '<abs-path-to-pplx-export>' batch --account '<account>' --out '<abs-archive-root>' — paths are absolute and quoted because cron's cwd and PATH are unpredictable. The executable path is resolved via shutil.which; when that fails the snippet falls back to the bare pplx-export name.
  • Scheduled runs are incremental-only by design; run batch --full manually as a periodic backstop.
pplx-export schedule --account alice