Self-hosted REST API and Rust client for Perplexity's web app endpoints.
This workspace contains two crates:
perplexity-api-server: an Axum server that exposes a simple HTTP APIperplexity-web-client: a typed Rust client for the upstream Perplexity web flow
It uses Perplexity web session cookies. It does not use the official Perplexity API.
crates/
├── perplexity-api-server
└── perplexity-web-client
- Download this chrome web extension
- Open perplexity.com in your browser.
- Log in if needed, and ask a question to generate a conversation.
- Click the extension icon and select "Export cookies".
- Open the exported file and copy the values of
__Secure-next-auth.session-tokenandnext-auth.csrf-token.
Copy the example file and set your Perplexity cookies:
cp .env.example .envSet the following required values:
PERPLEXITY_SESSION_TOKENPERPLEXITY_CSRF_TOKEN
For the full environment reference, request fields, modes, and models, see crates/perplexity-api-server/README.md.
With Cargo:
cargo run -p perplexity-api-serverWith Docker Compose:
docker compose up -d --buildBy default the server listens on 127.0.0.1:3000. In Docker, Compose publishes the container port to the host port configured in compose.yaml.
The full API reference, including request fields, modes, models, and environment variables, lives in crates/perplexity-api-server/README.md.
Available endpoints:
GET /healthGET /v1/modelsPOST /v1/searchPOST /v1/search/streamPOST /v1/imagesPOST /v1/attachments
PERPLEXITY_API_KEY is optional. It is only used to provide an API key for the server you are going to run. If it is set, send:
Authorization: Bearer <your-api-key>If PERPLEXITY_API_KEY is unset, the API is open.
curl -sS http://127.0.0.1:3000/v1/models \
-H 'Authorization: Bearer YOUR_API_KEY'curl -sS -X POST http://127.0.0.1:3000/v1/search \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"query": "What is Rust?"
}'curl -sS -X POST http://127.0.0.1:3000/v1/search \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"query": "If all cats are animals and all animals are living things, are all cats living things?",
"mode": "reason",
"model": "claude-4.6-sonnet-thinking"
}'curl -sN -X POST 'http://127.0.0.1:3000/v1/search/stream?human=1' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"query": "Name 5 programming languages"
}'curl -sS -X POST http://127.0.0.1:3000/v1/images \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"prompt": "Generate an image of a cinematic red fox in neon rain",
"model": "sonar"
}'curl -sS -X POST http://127.0.0.1:3000/v1/attachments \
-H 'Authorization: Bearer YOUR_API_KEY' \
-F 'files=@/absolute/path/to/example.png'Pass the backend_uuid and attachments returned from the previous response:
curl -sS -X POST http://127.0.0.1:3000/v1/search \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"query": "Tell me more",
"follow_up": {
"backend_uuid": "your-backend-uuid",
"attachments": []
}
}'- server configuration and API reference: crates/perplexity-api-server/README.md
- Rust client usage: crates/perplexity-web-client/README.md