Perplexity WebUI Scraper
Python scraper to extract AI responses from Perplexity's web interface.
Documentation: perplexity-webui-scraper.readthedocs.io
About
This unofficial library uses undocumented Perplexity WebUI endpoints with a browser session token. It supports conversations, file uploads, and streaming; optional extras provide the MCP server and OpenAI-compatible REST API.
A Perplexity account and its browser session token are required. Free accounts support text prompts; paid tiers are required for Pro/Max models and file uploads.
Python 3.11 through 3.15 are supported. Python 3.15 is the primary runtime for direct end-user installations, API/MCP containers, and the local .python-version pin. CI quality, documentation, and package build jobs use Python 3.14. The unit-test matrix covers Python 3.11 through 3.15 across Linux, macOS, and Windows.
Community
Installation
The package is published to PyPI. API and MCP container images are published to GHCR. GitHub Releases include the wheel and source distribution; the project does not publish standalone executables.
Core library
Install the core Python library without optional features.
uv add perplexity-webui-scraper
CLI and server extras
Install only the features you need. Use the token, api, and mcp extras individually or together.
# Install from PyPI
uv add 'perplexity-webui-scraper[token]' # Email token generator
uv add 'perplexity-webui-scraper[api]' # REST API server
uv add 'perplexity-webui-scraper[mcp]' # MCP server
uv add 'perplexity-webui-scraper[all]' # All optional features
Quick Start
1. Get your session token
The base install does not include token-generation dependencies. Install the token extra first:
uv add 'perplexity-webui-scraper[token]'
uv run perplexity-webui-scraper token --email [email protected]
The token command accepts an optional --email argument and prompts for an address when omitted. You can also retrieve __Secure-next-auth.session-token manually from your browser cookies on perplexity.ai.
2. Basic usage
from perplexity_webui_scraper import Perplexity
client = Perplexity(session_token="YOUR_TOKEN")
conversation = client.create_conversation()
print(client.get_account_profile().account_tier)
conversation.ask("What is quantum computing?")
print(conversation.answer)
# Follow-ups preserve context automatically
conversation.ask("Explain it simpler")
print(conversation.answer)
Before each prompt, the library checks /api/auth/session and raises ModelAccessError if an available model requires a higher tier than the authenticated account. When the session payload does not expose enough subscription data, it falls back to /rest/user/settings. Models use one of three statuses: available (confirmed working normally), unknown (not yet verified, including custom identifiers), or unavailable (confirmed not working). is_official separately records whether a model is listed in Perplexity's official WebUI. last_tested_at records the last test in ISO 8601 UTC and is null for untested models. Any non-available status requires allow_risky_model=True; after acknowledgement, the backend makes the final entitlement decision. Free accounts can use text prompts, but file attachments raise FileAccessError.
perplexity/best adapts to the account tier: free accounts use Perplexity's internal turbo preference, while Pro/Max accounts use pplx_pro_upgraded; both use copilot mode.
3. Streaming
printed = ""
for response in conversation.ask("Explain AI", stream=True):
current = response.answer or "".join(response.chunks)
if current.startswith(printed):
delta = current[len(printed) :]
print(delta, end="", flush=True)
printed = current
elif current:
printed = current
print(f"\r{printed}", end="", flush=True)
4. Choose a model
from perplexity_webui_scraper import ConversationConfig
conversation = client.create_conversation(ConversationConfig(model="perplexity/best"))
conversation.ask("Solve this step by step: ...")
print(conversation.answer)
5. List registered models
from perplexity_webui_scraper import MODELS
for model in MODELS.list_all():
print(f"{model.id:40} {model.name}")
CLI commands
Use -h or --help with the root command or any subcommand. The token command accepts -e or --email.
OpenAI-compatible API
Run a local server that accepts the supported subset of OpenAI Responses and legacy Chat Completions requests. Both routes use the same Perplexity conversation core. The Responses route accepts text and base64 data-URL images, supports streaming and process-local previous_response_id continuation, and rejects unsupported request fields. Tool execution, durable response retrieval, and remote image fetching are not implemented.
# Start with clients supplying their Perplexity token per request
perplexity-webui-scraper api
# Optional server-default upstream token, protected by a separate gateway key
PERPLEXITY_SESSION_TOKEN="$PPLX_TOKEN" PERPLEXITY_API_KEY="$GATEWAY_KEY" perplexity-webui-scraper api
# Custom host and port
perplexity-webui-scraper api --host 0.0.0.0 --port 8080
# Development mode with auto-reload
perplexity-webui-scraper api --reload
Container deployment with Podman
# Pull the published multi-arch API image
podman pull ghcr.io/henrique-coder/perplexity-webui-scraper:latest
# Run the server (exposing port 8000)
podman run --rm -p 8000:8000 ghcr.io/henrique-coder/perplexity-webui-scraper:latest
Optional MCP image for containerized stdio setups:
# Pull the published multi-arch MCP image
podman pull ghcr.io/henrique-coder/perplexity-webui-scraper:mcp
# Run MCP server (requires token)
podman run --rm -e PERPLEXITY_SESSION_TOKEN=your_token ghcr.io/henrique-coder/perplexity-webui-scraper:mcp
For local development, you can still build the provided container files:
# API image: installs the `api` extra, exposes port 8000, and starts the REST server.
podman build -t perplexity-api -f Containerfile .
podman run --rm -it -p 8000:8000 perplexity-api
# MCP image: installs the `mcp` extra and starts the stdio MCP server. It does not expose an HTTP port.
podman build -t perplexity-mcp -f Containerfile.mcp .
podman run --rm -it -e PERPLEXITY_SESSION_TOKEN=your_token perplexity-mcp
CLI options
Authentication
Without a server-default token, send your Perplexity token as Authorization: Bearer $PERPLEXITY_SESSION_TOKEN. When PERPLEXITY_SESSION_TOKEN is configured on the server, requests may omit Authorization but must include the separate gateway key in X-API-Key. A caller Bearer token overrides the server default, but gateway authentication is still required.
# curl
export PERPLEXITY_SESSION_TOKEN='your_session_token'
curl http://localhost:8000/v1/chat/completions \
-H 'Authorization: Bearer $PERPLEXITY_SESSION_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"model": "perplexity/best", "messages": [{"role": "user", "content": "Hello!"}]}'
# Streaming
curl -N http://localhost:8000/v1/chat/completions \
-H 'Authorization: Bearer $PERPLEXITY_SESSION_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"model": "perplexity/best", "messages": [{"role": "user", "content": "Hello!"}], "stream": true}'
from openai import OpenAI
client = OpenAI(
base_url="http://localhost:8000/v1",
api_key="YOUR_SESSION_TOKEN", # sent as Authorization: Bearer automatically
)
response = client.chat.completions.create(
model="perplexity/best",
messages=[{"role": "user", "content": "Hello!"}],
)
print(response.choices[0].message.content)
Responses API request with server-configured upstream credentials:
curl http://localhost:8000/v1/responses \
-H 'X-API-Key: $GATEWAY_KEY' \
-H 'Content-Type: application/json' \
-d '{"model":"perplexity/best","input":"Hello!"}'
API endpoints
Chat Completions accepts and ignores some unsupported OpenAI fields. Responses rejects unknown request fields. Neither route implements the full OpenAI API.
POST /v1/responses
The Responses route accepts model, input, instructions, stream, previous_response_id, and the perplexity extension object. It accepts a string input or supported text and base64 image items. Unknown request fields and unsupported input item types return 422. Tool execution, durable response retrieval, and token-usage accounting are not implemented. Continuation IDs map to an in-memory conversation thread and expire with the process-local cache.
MCP server
Expose every Perplexity model as a separate tool for AI agents (Claude Desktop, Antigravity, etc.):
{
"mcpServers": {
"perplexity-webui-scraper": {
"command": "uvx",
"args": [
"--from",
"perplexity-webui-scraper[mcp]",
"perplexity-webui-scraper",
"mcp"
],
"env": { "PERPLEXITY_SESSION_TOKEN": "your_token_here" }
}
}
}
See the MCP documentation for tools and configuration.
Disclaimer
This is an unofficial library. It uses internal APIs that may change without notice. Use at your own risk. By using this library, you agree to Perplexity AI's Terms of Service.