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/--cookiesare mutually exclusive with--transport webbridge— the bridge runs in the page context and already carries the browser's cookies.pplx-export --versionprints 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_modeenrichment written bysearch-mode-backfill: index rows don't carry it natively, so on refresh it is merged back from the old index byentryUUID. - Run it before
batch,sync-spaceandsync-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_threadsover the cookie transport with offset pagination; rows includecontext_uuidandanswer_preview. - With
--transport webbridgeit 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;
--forceoverrides the check. lastUpdatedis taken from the local library index when the thread is listed there (same semantics and format asbatch), falling back to the platform value otherwise.- Terminal states are registered gracefully, without a traceback:
ENTRY_DELETEDmarksdeletedinbatch_state.json,ENTRY_EXPIREDmarksexpired— the existing local archive is kept untouched either way. - A successful export writes
okintoindex/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— runindexfirst. - 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.
--fulldisables early stop (periodic backstop, or when archive gaps are suspected);--forcere-exports everything except terminal states, which are never retried. Full semantics: incremental-sync.md. --modefiltering: rows carryingsearch_mode(the platform-authoritative field enriched bysearch-mode-backfill) match exactly viaSEARCH_MODE_MAP— on that path--mode searchno longer pulls in deep-research/council/study threads. Rows withoutsearch_modefall back to index heuristics:computer= modeCOMPUTER;deep-research= displayModelpplx_alpha;council=pplx_agentic_research;study=pplx_study;search= the remaining mode-SEARCHrows (including those three kinds — filter them out precisely by exporting the specific modes separately).- State is saved to
index/batch_state.jsonafter 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-maxpause 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.jsonlwith 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-metathe command is purely local (zero network): it aggregates threads per space slug across alllibrary_*.jsonfiles, 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 containingweb_archive/so the backlinks in the space pages resolve. --fetch-metafirst refreshes each space's owner/member cache viaget_collection(1 request per space, 3s interval) intoindex/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
indexfirst — the refreshedlibrary_*.jsonis the source of truth for current space ownership. - Compares space slugs per thread and patches
thread.jsonin 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) asbatch— see incremental-sync.md. - Writes
<out>/index/cron_snippet.txtcontaining one17 3 * * *line of the formcd '<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 viashutil.which; when that fails the snippet falls back to the barepplx-exportname. - Scheduled runs are incremental-only by design; run
batch --fullmanually as a periodic backstop.
pplx-export schedule --account alice