Perplexity → OpenWebUI JSON Converter
Convert a Perplexity GDPR export into an OpenWebUI-importable JSON file.
| What it does | How it works | Output |
|---|---|---|
Reads conversations-*.json (required) and optionally user-data-*.xlsx (for collection metadata). |
Parses the export, optionally filters by date, optionally prefixes/appends collection info to chat titles, builds a model name, and writes a JSON file that OpenWebUI can import as chats. | A single JSON file (perplexity-openwebui-import.json by default) containing an array of OpenWebUI chat objects. |
⚠️ Note – A lot of vibecoding involved in the creation of the script. Use the--verboseflag for diagnostics.
- Auto-detects export files in the current directory.
- Optional collection metadata from the XLSX export (
--input-xlsx). - Optional collection-name prefix/append on chat titles.
- Date-range filtering (
--start-date,--end-date). - Customizable model name (
--model) with optional Perplexity mode (--model-type) and suffix (--model-type-end). - Preview of first/last matching chats before writing;
-y/--yesskips the prompt. - Verbose diagnostics (
--verbose).
| Requirement | Version / Note |
|---|---|
| Python | ≥ 3.10 |
uv (optional, recommended) |
https://github.com/astral-sh/uv |
If you don’t have uv, the script can be run with plain python.
| File pattern | Required? | Use |
|---|---|---|
conversations-*.json |
Yes | Main conversation data. |
user-data-*.xlsx |
No | Maps collection UUIDs to collection names. |
Example:
conversations-20260521_055174-71d2830a.json
user-data-20260521_055174-71d2830a.xlsx
If the files reside in the current directory the script will locate them automatically.
# Using uv (recommended)
uv run main.py --verbose # auto-detects files, shows preview, asks for confirmation
# Or with plain Python
python main.py --verboseSpecify a JSON file explicitly if auto-detect fails:
uv run main.py ./conversations-20260521_055174-71d2830a.jsoninput_json – Path to the Perplexity conversations-*.json.
Optional when the file can be auto-detected.
| Option | Alias | Description | Default |
|---|---|---|---|
-o --output |
– | Destination JSON file for OpenWebUI import. | perplexity-openwebui-import.json |
--input-xlsx |
– | Path to the user-data-*.xlsx export (for collection data). |
auto-detect |
--model |
– | Base model string stored in OpenWebUI. | Perplexity |
--model-type |
– | Append the Perplexity conversation mode (e.g. Copilot) to --model. |
disabled |
--model-type-end |
– | Custom suffix added only when --model-type is active (e.g. )). |
empty |
--title-prefix-collection |
– | Prefix chat titles with collection name or UUID. | off |
--title-append-collection |
– | Append collection name or UUID to chat titles. | off |
--start-date |
– | Import only conversations created on/after this date (YYYY-MM-DD). |
none |
--end-date |
– | Import only conversations created on/before this date (YYYY-MM-DD). |
none |
-y --yes |
– | Skip the preview/confirmation step. | off |
--verbose |
– | Print diagnostic information to stderr. |
off |
-h --help |
– | Show help. | – |
| Command | Resulting model name |
|---|---|
--model "Perplexity - " |
Perplexity - |
--model "Perplexity - " --model-type |
Perplexity - Copilot |
--model "Perplexity (" --model-type --model-type-end ")" |
Perplexity (Copilot) |
--model "Perplexity (" --model-type --model-type-end " )" |
Perplexity (Copilot ) (spaces preserved) |
Why
--model-type-endis ignored without--model-type– it prevents accidental stray characters when you only want a simple base model name.
| Command | Resulting title |
|---|---|
--title-prefix-collection |
[Collection Name] My chat title |
--title-append-collection |
My chat title [Collection Name] |
If a collection name is not available but a collection UUID exists, the UUID is used instead.
Filtering occurs at the conversation level using the created_at timestamp from the Perplexity export. If a conversation falls inside the range, the whole conversation is imported; individual messages are never trimmed.
{
"chat": {
"title": "...",
"models": "...",
"history": {
"currentId": "...",
"messages": [...]
}
"options": {}
},
"meta": { ... },
"created_at": "...",
"updated_at": "..."
}Assistant messages include "model" and "done": true fields.
When collection data is available, the converter also stores:
meta.perplexity_collection_uuidmeta.perplexity_collection_name
These fields are preserved in the output JSON even though title modification is optional.
- Missing required JSON file.
- Explicit XLSX path does not exist.
- Invalid JSON syntax or unexpected top-level structure.
conversationskey missing or not a list.- Date arguments not in
YYYY-MM-DDformat or--start-date>--end-date.
Malformed conversation entries are skipped, not fatal.
| Goal | Command |
|---|---|
| Import everything (default output, with preview) | uv run main.py --verbose |
| Import only a date window | uv run main.py --start-date 2025-01-01 --end-date 2025-12-31 |
| Custom model name, include mode, skip confirmation | uv run main.py --model "Perplexity - " --model-type -y |
| Prefix titles with collection names and write to custom file | uv run main.py -o my-import.json --title-prefix-collection |
| Append titles with collection names and write to custom file | uv run main.py -o my-import.json --title-append-collection |
| Use an explicit XLSX file | uv run main.py --input-xlsx ./user-data-20260521_055174-71d2830a.xlsx |
# With uv (recommended)
uv run main.py --verbose
# Without uv
python3 main.py --verbose
# Make the script directly executable
chmod +x main.py
./main.py -h # shows helpContributions are very welcome!
This repository makes use of Git LFS, to contribute and add media be sure to have it installed.
If this program helped you, please consider supporting my open-source work 🙏
- ☕ Ko‑Fi: ko-fi.com/frayoshi
- 💸 PayPal: paypal.me/FrancescoGobbo
- 🪢 GitHub: github.com/sponsors/FraYoshi or click on the
♥️ heart-shaped sponsor icon. - 🔗 More Ways to Support: furayoshi.com/support
- 🌐 Homepage: furayoshi.com
- 🗨️ Discord: furayoshi.com/discord
