home / skills / itechmeat / llm-code / perplexity
npx playbooks add skill itechmeat/llm-code --skill perplexityReview the files below or copy the command above to add this skill to your agents.
---
name: perplexity
description: "Integrate Perplexity API for web-grounded AI responses and search. Covers Sonar models, Search API, SDK usage (Python/TypeScript), streaming, structured outputs, filters, media attachments, Pro Search, and prompting. Keywords: Perplexity, Sonar, sonar-pro, sonar-reasoning-pro, sonar-deep-research, web search API, grounded LLM, chat completions, perplexityai SDK, image attachments, PDF analysis."
version: "0.26.0"
release_date: "2026-01-24"
---
# Perplexity API
Build AI applications with real-time web search and grounded responses.
## Quick Navigation
- Models & pricing: `references/models.md`
- Search API patterns: `references/search-api.md`
- Chat completions guide: `references/chat-completions.md`
- Structured outputs: `references/structured-outputs.md`
- Filters (domain/language/date/location): `references/filters.md`
- Media (images/videos/attachments): `references/media.md`
- Pro Search: `references/pro-search.md`
- Prompting best practices: `references/prompting.md`
## When to Use
- Need AI responses grounded in current web data
- Building search-powered applications
- Research tools requiring citations
- Real-time Q&A with source verification
- Document/image analysis with web context
## Installation
```bash
# Python
pip install perplexityai
# TypeScript/JavaScript
npm install @perplexityai/perplexity
```
## Authentication
```bash
# macOS/Linux
export PERPLEXITY_API_KEY="your_api_key_here"
# Windows
setx PERPLEXITY_API_KEY "your_api_key_here"
```
SDK auto-reads `PERPLEXITY_API_KEY` environment variable.
## Quick Start — Chat Completion
```python
from perplexity import Perplexity
client = Perplexity()
completion = client.chat.completions.create(
model="sonar-pro",
messages=[{"role": "user", "content": "What is the latest news on AI?"}]
)
print(completion.choices[0].message.content)
```
## Quick Start — Search API
```python
from perplexity import Perplexity
client = Perplexity()
search = client.search.create(
query="artificial intelligence trends 2024",
max_results=5
)
for result in search.results:
print(f"{result.title}: {result.url}")
```
## Model Selection Guide
| Model | Use Case | Cost |
| --------------------- | ------------------------------ | ------- |
| `sonar` | Quick facts, simple Q&A | Lowest |
| `sonar-pro` | Complex queries, research | Medium |
| `sonar-reasoning-pro` | Multi-step reasoning, analysis | Medium |
| `sonar-deep-research` | Exhaustive research, reports | Highest |
## Key Patterns
### Streaming Responses
```python
stream = client.chat.completions.create(
messages=[{"role": "user", "content": "Explain quantum computing"}],
model="sonar",
stream=True
)
for chunk in stream:
if chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="")
```
### Multi-Turn Conversation
```python
messages = [
{"role": "system", "content": "You are a research assistant."},
{"role": "user", "content": "What causes climate change?"},
{"role": "assistant", "content": "Climate change is caused by..."},
{"role": "user", "content": "What are the solutions?"}
]
completion = client.chat.completions.create(messages=messages, model="sonar")
```
### Web Search Options
```python
completion = client.chat.completions.create(
messages=[{"role": "user", "content": "Latest renewable energy news"}],
model="sonar",
web_search_options={
"search_recency_filter": "week",
"search_domain_filter": ["energy.gov", "iea.org"]
}
)
```
### Pro Search (Multi-Step Research)
```python
# REQUIRES stream=True
completion = client.chat.completions.create(
model="sonar-pro",
messages=[{"role": "user", "content": "Research solar panel ROI"}],
search_type="pro",
stream=True
)
for chunk in completion:
print(chunk.choices[0].delta.content or "", end="")
```
### Image Attachment
```python
completion = client.chat.completions.create(
model="sonar-pro",
messages=[{
"role": "user",
"content": [
{"type": "text", "text": "Describe this image"},
{"type": "image_url", "image_url": {"url": "https://example.com/image.jpg"}}
]
}]
)
```
### File Attachment (PDF Analysis)
```python
completion = client.chat.completions.create(
model="sonar-pro",
messages=[{
"role": "user",
"content": [
{"type": "text", "text": "Summarize this document"},
{"type": "file_url", "file_url": {"url": "https://example.com/report.pdf"}}
]
}]
)
```
### Return Images in Response
```python
completion = client.chat.completions.create(
model="sonar",
messages=[{"role": "user", "content": "Mount Everest photos"}],
return_images=True,
image_format_filter=["jpg", "png"]
)
```
### Domain Filtering (Search API)
```python
# Allowlist: include only these domains
search = client.search.create(
query="climate research",
search_domain_filter=["science.org", "nature.com"]
)
# Denylist: exclude these domains
search = client.search.create(
query="tech news",
search_domain_filter=["-reddit.com", "-pinterest.com"]
)
```
### Multi-Query Search
```python
search = client.search.create(
query=[
"AI trends 2024",
"machine learning healthcare",
"neural networks applications"
],
max_results=5
)
for i, query_results in enumerate(search.results):
print(f"Query {i+1} results:")
for result in query_results:
print(f" {result.title}")
```
### Structured Outputs (JSON Schema)
```python
from pydantic import BaseModel
class ContactInfo(BaseModel):
email: str
phone: str
completion = client.chat.completions.create(
model="sonar-pro",
messages=[{"role": "user", "content": "Find contact for Tesla IR"}],
response_format={
"type": "json_schema",
"json_schema": {"schema": ContactInfo.model_json_schema()}
}
)
contact = ContactInfo.model_validate_json(completion.choices[0].message.content)
```
### Async Operations
```python
import asyncio
from perplexity import AsyncPerplexity
async def main():
async with AsyncPerplexity() as client:
tasks = [
client.search.create(query="AI news"),
client.search.create(query="tech trends")
]
results = await asyncio.gather(*tasks)
asyncio.run(main())
```
### Rate Limit Handling
```python
import time
from perplexity import RateLimitError
def search_with_retry(client, query, max_retries=3):
for attempt in range(max_retries):
try:
return client.search.create(query=query)
except RateLimitError:
if attempt < max_retries - 1:
time.sleep(2 ** attempt)
else:
raise
```
## Response Parameters
| Parameter | Default | Description |
| ------------------- | ------- | ------------------------------- |
| `temperature` | 0.7 | Creativity (0-2) |
| `max_tokens` | varies | Response length limit |
| `top_p` | 0.9 | Nucleus sampling |
| `presence_penalty` | 0 | Reduce repetition (-2 to 2) |
| `frequency_penalty` | 0 | Reduce word frequency (-2 to 2) |
## Search API Parameters
| Parameter | Description |
| ------------------------ | --------------------------------------- |
| `max_results` | 1-20 results per query |
| `max_tokens_per_page` | Content extraction depth (default 2048) |
| `country` | ISO country code for regional results |
| `search_domain_filter` | Domain allowlist/denylist (max 20) |
| `search_language_filter` | ISO 639-1 language codes (max 10) |
## Pricing Quick Reference
**Search API:** $5/1K requests (no token costs)
**Sonar Models (per 1M tokens):**
| Model | Input | Output |
|-------|-------|--------|
| sonar | $1 | $1 |
| sonar-pro | $3 | $15 |
| sonar-reasoning-pro | $2 | $8 |
**Request fees** (per 1K requests): $5-$14 depending on search context size.
## Critical Prohibitions
- Do NOT request links/URLs in prompts (use `citations` field instead — model will hallucinate URLs)
- Do NOT use recursive JSON schemas (not supported)
- Do NOT use `dict[str, Any]` in Pydantic models for structured outputs
- Do NOT mix allowlist and denylist in `search_domain_filter`
- Do NOT exceed 5 queries in multi-query search
- Do NOT expect first request with new JSON schema to be fast (10-30s warmup)
- Do NOT use Pro Search without `stream=True` (will fail)
- Do NOT send images to `sonar-deep-research` (not supported)
- Do NOT include `data:` prefix for file attachments base64 (only for images)
- Do NOT try to control search via prompts (use API parameters instead)
## Error Handling
```python
import perplexity
try:
completion = client.chat.completions.create(...)
except perplexity.BadRequestError as e:
print(f"Invalid parameters: {e}")
except perplexity.RateLimitError:
print("Rate limited, retry later")
except perplexity.APIStatusError as e:
print(f"API error: {e.status_code}")
```
## OpenAI SDK Compatibility
Perplexity supports OpenAI Chat Completions format. Use OpenAI client by pointing to Perplexity endpoint.
## Links
- [API Portal](https://www.perplexity.ai/settings/api)
- [Documentation](https://docs.perplexity.ai/)
- [Python SDK (PyPI)](https://pypi.org/project/perplexityai/)
- [TypeScript SDK (npm)](https://www.npmjs.com/package/@perplexityai/perplexity)