perplexity

v2026.09.24

Perplexity API for web-grounded AI and search. Covers Sonar models, chat/search APIs, streaming, structured outputs, filters, and attachments. Keywords: Perplexity, Sonar, search API, grounded LLM.

GitHub
Install command
npx skhub add itechmeat/perplexity
Markdown
SKILL.md

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
  • Browser sessions API: references/browser.md
  • Embeddings API: references/embeddings.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

Install: pip install perplexityai (Python) or npm install @perplexityai/perplexity (TypeScript/JavaScript).

Authentication

# 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

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)

Note (v0.28.0): The Python client includes a custom JSON encoder to support additional types in request payloads.

Quick Start — Search API

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}")

Release Highlights (0.34.1 -> 0.38.0)

  • Streaming: responses.create now yields named SSE events and discriminates the ResponseStreamEvent union, which matters for typed stream consumers.
  • Search context: search_context_size was briefly exposed on search.create, removed in 0.35.1, then reintroduced in 0.37.0 for both the Search API and the web_search tool to control retrieved context size.
  • Background responses: the SDK adds background-task support and responses.retrieve, so long-running response workflows can be polled instead of only streamed inline.
  • Reasoning effort: xhigh is available where the API supports reasoning-effort controls.
  • Sandbox tool: 0.36.0 adds the Responses API sandbox built-in tool; 0.38.0 adds a files subresource for retrieving sandbox-produced files. Gate both like other executable/tooling surfaces.

Model Selection Guide

ModelUse CaseCost
sonarQuick facts, simple Q&ALowest
sonar-proComplex queries, researchMedium
sonar-reasoning-proMulti-step reasoning, analysisMedium
sonar-deep-researchExhaustive research, reportsHighest

Key Patterns

Streaming Responses

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

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

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)

# 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

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)

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

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)

# 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

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)

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

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

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

ParameterDefaultDescription
temperature0.7Creativity (0-2)
max_tokensvariesResponse length limit
top_p0.9Nucleus sampling
presence_penalty0Reduce repetition (-2 to 2)
frequency_penalty0Reduce word frequency (-2 to 2)

Search API Parameters

ParameterDescription
max_results1-20 results per query
max_tokens_per_pageContent extraction depth (default 2048)
countryISO country code for regional results
search_domain_filterDomain allowlist/denylist (max 20)
search_language_filterISO 639-1 language codes (max 10)

Pricing Quick Reference

Search API: $5/1K requests (no token costs)

Sonar Models (per 1M tokens):

ModelInputOutput
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

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

Discovery
Tags

No tags published for this skill.

Version
Latest version metadata

Version

v2026.09.24

Published

Sep 24, 2026

Category

Uncategorized

License

MIT

Source path

skills/perplexity

Default branch

master

Latest commit

7ae8a00

Tree SHA

47f5439