Overview
Both Perplexity SDKs provide comprehensive type definitions to help you catch errors at development time and provide better IDE support. This guide covers type annotations, generic types, and advanced typing patterns.Basic Type Usage
Type Imports and Annotations
Use type imports for better IDE support and type checking:from perplexity import Perplexity
from perplexity.types import (
SearchCreateResponse,
ResponseCreateResponse,
SearchResult
)
client = Perplexity()
# Type hints for better IDE support
search_response: SearchCreateResponse = client.search.create(
query="OpenAI API release history and developer features"
)
# Access typed properties
result: SearchResult = search_response.results[0]
print(f"Title: {result.title}")
print(f"URL: {result.url}")
print(f"Snippet: {result.snippet}")
import Perplexity from '@perplexity-ai/perplexity_ai';
const client = new Perplexity();
// TypeScript provides full intellisense and type checking
const searchResponse: Perplexity.Search.SearchCreateResponse = await client.search.create({
query: "OpenAI API release history and developer features"
});
// Access typed properties with intellisense
const result = searchResponse.results[0];
console.log(`Title: ${result.title}`);
console.log(`URL: ${result.url}`);
console.log(`Snippet: ${result.snippet}`);
Response
Response
{
"id": "4a713b10-40e7-4d2a-9e7b-fdd9870702e8",
"results": [
{
"snippet": "",
"title": "Changelog | OpenAI API",
"url": "https://developers.openai.com/api/docs/changelog",
"date": null,
"last_updated": "2026-05-27"
},
{
"snippet": "All latest OpenAI models support text and image input, text output, multilingual capabilities, and vision.\nModels are available via the Responses API and our Client SDKs.",
"title": "Models | OpenAI API",
"url": "https://developers.openai.com/api/docs/models",
"date": null,
"last_updated": "2026-05-07"
},
{
"snippet": "June 11, 2020\n...\nWe’re releasing an API for accessing new AI models developed by OpenAI.\nUnlike most AI systems which are designed for one use-case, the API today provides a general-purpose “text...",
"title": "OpenAI API",
"url": "https://openai.com/index/openai-api/",
"date": "2020-06-11",
"last_updated": "2026-03-29"
}
],
"server_time": null
}
Runtime Type Validation
Python SDK uses Pydantic for runtime type validation:from perplexity import Perplexity
from perplexity.types import SearchCreateResponse
client = Perplexity()
# Runtime validation ensures type safety
try:
search_response = client.search.create(
query="OpenAI o-series reasoning model benchmarks",
max_results=10
)
# Pydantic model methods for serialization
json_data = search_response.to_json()
dict_data = search_response.to_dict()
# Type validation on field access
first_result = search_response.results[0]
print(f"Result type: {type(first_result)}")
except ValueError as e:
print(f"Type validation error: {e}")
import Perplexity from '@perplexity-ai/perplexity_ai';
const client = new Perplexity();
// TypeScript compile-time type checking
const searchResponse: Perplexity.Search.SearchCreateResponse = await client.search.create({
query: "OpenAI o-series reasoning model benchmarks",
max_results: 10 // TypeScript ensures correct property names
});
// Serialization (already plain objects)
const jsonData = JSON.stringify(searchResponse);
const objectData = searchResponse; // Already a plain object
// Type safety at compile time
const firstResult = searchResponse.results[0];
console.log(`Result type available in IDE: ${typeof firstResult}`);
Response
Response
{
"id": "169d5d3b-272a-46ca-a59d-7c218f9d5ce2",
"results": [
{
"snippet": "",
"title": "Reasoning best practices | OpenAI API",
"url": "https://developers.openai.com/api/docs/guides/reasoning-best-practices",
"date": null,
"last_updated": "2026-05-21"
},
{
"snippet": "",
"title": "A Comparative Study on Reasoning Patterns of OpenAI's o1 Model",
"url": "https://arxiv.org/html/2410.13639v1",
"date": "2024-10-17",
"last_updated": "2026-03-22"
},
{
"snippet": "**OpenAI o1** is a generative pre-trained transformer (GPT), the first in OpenAI's \"o\" series of reasoning models.\nA preview of o1 was released by OpenAI on September 12, 2024.\no1 spends time...",
"title": "OpenAI o1 - Wikipedia",
"url": "https://en.wikipedia.org/wiki/OpenAI_o1",
"date": "2024-09-12",
"last_updated": "2026-03-31"
}
],
"server_time": null
}
Advanced Type Patterns
Generic Type Helpers
Create reusable typed functions:from typing import TypeVar, Generic, List, Optional, Callable
from perplexity import Perplexity
from perplexity.types import SearchCreateResponse, ResponseCreateResponse
T = TypeVar('T')
R = TypeVar('R')
class TypedPerplexityClient:
def __init__(self, client: Perplexity):
self.client = client
def search_with_transform(
self,
query: str,
transform: Callable[[SearchCreateResponse], T]
) -> T:
"""Perform search and transform the result with type safety"""
response = self.client.search.create(query=query)
return transform(response)
def batch_search(
self,
queries: List[str]
) -> List[SearchCreateResponse]:
"""Perform multiple searches with proper typing"""
results = []
for query in queries:
response = self.client.search.create(query=query)
results.append(response)
return results
# Usage with type safety
client = TypedPerplexityClient(Perplexity())
def extract_titles(response: SearchCreateResponse) -> List[str]:
return [result.title for result in response.results]
# Typed function call
titles: List[str] = client.search_with_transform("AI research", extract_titles)
import Perplexity from '@perplexity-ai/perplexity_ai';
class TypedPerplexityClient {
constructor(private client: Perplexity) {}
async searchWithTransform<T>(
query: string,
transform: (response: Perplexity.Search.SearchCreateResponse) => T
): Promise<T> {
const response = await this.client.search.create({ query });
return transform(response);
}
async batchSearch(queries: string[]): Promise<Perplexity.Search.SearchCreateResponse[]> {
const tasks = queries.map(query =>
this.client.search.create({ query })
);
return Promise.all(tasks);
}
}
// Usage with type safety
const client = new TypedPerplexityClient(new Perplexity());
function extractTitles(response: Perplexity.Search.SearchCreateResponse): string[] {
return response.results.map(result => result.title);
}
// Typed function call with full intellisense
const titles: string[] = await client.searchWithTransform("AI research", extractTitles);
Custom Type Guards
Create type guards for safer type checking:from typing import Union, TypeGuard
from perplexity.types import (
SearchCreateResponse,
ResponseCreateResponse,
SearchResult
)
def is_search_response(
response: Union[SearchCreateResponse, ResponseCreateResponse]
) -> TypeGuard[SearchCreateResponse]:
"""Type guard to check if response is a search response"""
return hasattr(response, 'results')
def is_valid_search_result(result: SearchResult) -> TypeGuard[SearchResult]:
"""Type guard to validate search result structure"""
return (
hasattr(result, 'title') and
hasattr(result, 'url') and
hasattr(result, 'snippet') and
result.title is not None and
result.url is not None
)
# Usage
def process_response(
response: Union[SearchCreateResponse, ResponseCreateResponse]
) -> None:
if is_search_response(response):
# Python type checker now knows this is SearchCreateResponse
for result in response.results:
if is_valid_search_result(result):
print(f"Valid result: {result.title}")
else:
print("Invalid result format")
import Perplexity from '@perplexity-ai/perplexity_ai';
function isSearchResponse(
response: Perplexity.Search.SearchCreateResponse | Perplexity.StreamChunk
): response is Perplexity.Search.SearchCreateResponse {
return 'results' in response;
}
function isValidSearchResult(result: { title: string; url: string; snippet: string }): boolean {
return (
typeof result.title === 'string' &&
typeof result.url === 'string' &&
typeof result.snippet === 'string' &&
result.title.length > 0 &&
result.url.length > 0
);
}
// Usage
function processResponse(
response: Perplexity.Search.SearchCreateResponse | Perplexity.StreamChunk
): void {
if (isSearchResponse(response)) {
// TypeScript now knows this is SearchCreateResponse
response.results.forEach(result => {
if (isValidSearchResult(result)) {
console.log(`Valid result: ${result.title}`);
} else {
console.log("Invalid result format");
}
});
}
}
Response Type Utilities
Extracting Nested Types
Work with nested response structures safely:from typing import List, Optional
from perplexity import Perplexity
from perplexity.types import (
SearchCreateResponse,
SearchResult,
ResponseCreateResponse
)
class ResponseUtils:
@staticmethod
def extract_search_titles(response: SearchCreateResponse) -> List[str]:
"""Extract all search result titles with type safety"""
return [result.title for result in response.results if result.title]
@staticmethod
def extract_search_urls(response: SearchCreateResponse) -> List[str]:
"""Extract all search result URLs with type safety"""
return [result.url for result in response.results if result.url]
@staticmethod
def get_first_search_result(
response: SearchCreateResponse
) -> Optional[SearchResult]:
"""Get first search result safely"""
return response.results[0] if response.results else None
@staticmethod
def extract_response_output(
response: ResponseCreateResponse
) -> Optional[str]:
"""Extract response output safely"""
if response.output:
return response.output
return None
# Usage
client = Perplexity()
search_response = client.search.create(query="Python 3.13 free-threaded GIL changes")
titles = ResponseUtils.extract_search_titles(search_response)
urls = ResponseUtils.extract_search_urls(search_response)
first_result = ResponseUtils.get_first_search_result(search_response)
print(f"Found {len(titles)} results")
if first_result:
print(f"First result: {first_result.title}")
import Perplexity from '@perplexity-ai/perplexity_ai';
class ResponseUtils {
static extractSearchTitles(response: Perplexity.Search.SearchCreateResponse): string[] {
return response.results
.filter(result => result.title)
.map(result => result.title);
}
static extractSearchUrls(response: Perplexity.Search.SearchCreateResponse): string[] {
return response.results
.filter(result => result.url)
.map(result => result.url);
}
static getFirstSearchResult(
response: Perplexity.Search.SearchCreateResponse
) {
return response.results[0];
}
static extractChatContent(
response: Perplexity.StreamChunk
): string | undefined {
const content = response.choices[0]?.message?.content;
// Handle content which can be string, array of chunks, or null
if (typeof content === 'string') {
return content;
}
if (Array.isArray(content)) {
// Extract text from content chunks
return content
.filter(chunk => chunk.type === 'text' && 'text' in chunk)
.map(chunk => (chunk as { text: string }).text)
.join('');
}
return undefined;
}
}
// Usage
const client = new Perplexity();
const searchResponse: Perplexity.Search.SearchCreateResponse = await client.search.create({
query: "Python 3.13 free-threaded GIL changes"
});
const titles = ResponseUtils.extractSearchTitles(searchResponse);
const urls = ResponseUtils.extractSearchUrls(searchResponse);
const firstResult = ResponseUtils.getFirstSearchResult(searchResponse);
console.log(`Found ${titles.length} results`);
if (firstResult) {
console.log(`First result: ${firstResult.title}`);
}
Response
Response
{
"id": "915ddb6e-c856-4856-a036-330e8e021895",
"results": [
{
"snippet": "Starting with the 3.13 release, CPython has support for a build of\nPython called where the\n(GIL) is disabled.\nFree-threaded execution allows for full utilization of the\navailable processing power by...",
"title": "Python support for free threading — Python 3.14.5 documentation",
"url": "https://docs.python.org/3/howto/free-threading-python.html",
"date": null,
"last_updated": "2026-05-18"
},
{
"snippet": "CPython 3.13 was released two weeks ago and this release is the most\nperformance-oriented in some time.\nAfter a quick read of the release notes, a\nfew things stand out for the impact they can have on...",
"title": "State of Python 3.13 Performance: Free-Threading - CodSpeed",
"url": "https://codspeed.io/blog/state-of-python-3-13-performance-free-threading",
"date": "2024-11-05",
"last_updated": "2026-05-14"
},
{
"snippet": "In this video, I'll discuss how Python 3.13 is revolutionizing performance by making the Global Interpreter Lock (GIL) optional!\nLearn what the GIL is, why it exists, and the potential impacts of its...",
"title": "How Much FASTER Is Python 3.13 Without the GIL? - YouTube",
"url": "https://www.youtube.com/watch?v=zWPe_CUR4yU",
"date": "2024-08-02",
"last_updated": "2026-03-17"
}
],
"server_time": null
}
Custom Response Mappers
Create typed mappers for domain-specific data structures:from typing import List, Optional, Dict, Any
from dataclasses import dataclass
from perplexity import Perplexity
from perplexity.types import SearchCreateResponse, SearchResult
@dataclass
class SimplifiedSearchResult:
title: str
url: str
snippet: str
domain: str
@dataclass
class SearchSummary:
query: str
total_results: int
results: List[SimplifiedSearchResult]
domains: List[str]
class SearchResponseMapper:
@staticmethod
def to_simplified(response: SearchCreateResponse, query: str) -> SearchSummary:
"""Convert API response to simplified domain model"""
simplified_results = []
domains = set()
for result in response.results:
if result.title and result.url and result.snippet:
# Extract domain from URL
try:
from urllib.parse import urlparse
domain = urlparse(result.url).netloc
domains.add(domain)
simplified_results.append(SimplifiedSearchResult(
title=result.title,
url=result.url,
snippet=result.snippet,
domain=domain
))
except Exception:
# Skip invalid URLs
continue
return SearchSummary(
query=query,
total_results=len(simplified_results),
results=simplified_results,
domains=list(domains)
)
# Usage with type safety
client = Perplexity()
query = "PyTorch versus JAX performance benchmarks for large language model training"
api_response = client.search.create(query=query)
summary: SearchSummary = SearchResponseMapper.to_simplified(api_response, query)
print(f"Query: {summary.query}")
print(f"Results: {summary.total_results}")
print(f"Unique domains: {len(summary.domains)}")
import Perplexity from '@perplexity-ai/perplexity_ai';
interface SimplifiedSearchResult {
title: string;
url: string;
snippet: string;
domain: string;
}
interface SearchSummary {
query: string;
totalResults: number;
results: SimplifiedSearchResult[];
domains: string[];
}
class SearchResponseMapper {
static toSimplified(response: Perplexity.Search.SearchCreateResponse): SearchSummary {
const simplifiedResults: SimplifiedSearchResult[] = [];
const domains = new Set<string>();
for (const result of response.results) {
if (result.title && result.url && result.snippet) {
try {
const domain = new URL(result.url).hostname;
domains.add(domain);
simplifiedResults.push({
title: result.title,
url: result.url,
snippet: result.snippet,
domain
});
} catch {
// Skip invalid URLs
continue;
}
}
}
return {
query: '',
totalResults: simplifiedResults.length,
results: simplifiedResults,
domains: Array.from(domains)
};
}
}
// Usage with type safety
const client = new Perplexity();
const apiResponse: Perplexity.Search.SearchCreateResponse = await client.search.create({
query: "PyTorch versus JAX performance benchmarks for large language model training"
});
const summary: SearchSummary = SearchResponseMapper.toSimplified(apiResponse);
console.log(`Query: ${summary.query}`);
console.log(`Results: ${summary.totalResults}`);
console.log(`Unique domains: ${summary.domains.length}`);
Response
Response
{
"id": "e48a6f66-7d8a-4dfd-aa79-342ae22199b6",
"results": [
{
"snippet": "### Performance\n*In this section, we will explore two main implementations in Machine Learning, one suitable for large datasets, working in a streaming fashion, and another ideal for smaller...",
"title": "ML Engineer comparison of Pytorch, TensorFlow, JAX, and ...",
"url": "https://softwaremill.com/ml-engineer-comparison-of-pytorch-tensorflow-jax-and-flax/",
"date": "2024-09-24",
"last_updated": "2026-05-27"
},
{
"snippet": "The predictability of pure functions and functional programming unlocks many benefits in JAX, such as Just-In-Time (JIT) compilation, where the XLA compiler can significantly optimize code on GPUs or...",
"title": "A guide to JAX for PyTorch developers",
"url": "https://cloud.google.com/blog/products/ai-machine-learning/guide-to-jax-for-pytorch-developers",
"date": "2025-01-07",
"last_updated": "2026-05-22"
},
{
"snippet": "",
"title": "TensorFlow vs PyTorch vs JAX: Performance Benchmark",
"url": "https://apxml.com/posts/tensorflow-vs-pytorch-vs-jax-performance-benchmark",
"date": "2025-03-24",
"last_updated": "2026-03-18"
}
],
"server_time": null
}
IDE Integration
Enhanced Development Experience
Maximize IDE support with proper type usage:from perplexity import Perplexity
from perplexity.types import ResponseCreateResponse, SearchCreateResponse
class EnhancedClient:
def __init__(self):
self.client = Perplexity()
def search(self, query: str, **kwargs) -> SearchCreateResponse:
"""
Perform search with full type hints
Args:
query: Search query string
**kwargs: Additional search parameters
Returns:
SearchCreateResponse: Typed search results
"""
return self.client.search.create(query=query, **kwargs)
def respond(self, message: str, effort: str = "low") -> ResponseCreateResponse:
"""
Agent API response with type hints
Args:
message: User message
effort: Research effort to use
Returns:
ResponseCreateResponse: Typed Agent API response
"""
return self.client.responses.create(
effort=effort,
input=message
)
# Usage with full IDE support
enhanced_client = EnhancedClient()
# IDE provides full autocomplete and type checking
search_result = enhanced_client.search("Python tutorials")
print(search_result.results[0].title) # Full intellisense available
agent_result = enhanced_client.respond("Explain decorators")
print(agent_result.output_text)
import Perplexity from '@perplexity-ai/perplexity_ai';
class EnhancedClient {
private client: Perplexity;
constructor() {
this.client = new Perplexity();
}
/**
* Perform search with full type hints
*/
async search(
query: string,
options?: Partial<Perplexity.Search.SearchCreateParams>
): Promise<Perplexity.Search.SearchCreateResponse> {
return this.client.search.create({
query,
...options
});
}
/**
* Agent API response with inferred types
*/
async respond(
message: string,
effort: string = "low"
) {
return this.client.responses.create({
effort,
input: message
});
}
}
// Usage with full IDE support
const enhancedClient = new EnhancedClient();
// IDE provides full autocomplete and type checking
const searchResult = await enhancedClient.search("Python tutorials");
console.log(searchResult.results[0].title); // Full intellisense available
const agentResult = await enhancedClient.respond("Explain decorators");
console.log(agentResult.output_text);
Type Safety Best Practices
1
Always use type imports
Import and use specific types for better IDE support and error catching.
# Good: Specific type imports
from typing import List
from perplexity.types import SearchCreateResponse, SearchResult
def process_search(response: SearchCreateResponse) -> List[str]:
return [result.title for result in response.results]
// Good: Use namespace types for type safety
import Perplexity from '@perplexity-ai/perplexity_ai';
function processSearch(response: Perplexity.Search.SearchCreateResponse): string[] {
return response.results.map(result => result.title);
}
2
Use type guards for runtime safety
Implement proper type checking for dynamic data.
TypeScript types are compile-time only. Use type guards for runtime validation.
3
Leverage generic types
Create reusable typed functions and classes for common patterns.
Generic types help maintain type safety while providing flexibility.
4
Document with types
Use type annotations as documentation for better code maintainability.
def analyze_search_results(
response: SearchCreateResponse,
min_score: float = 0.5
) -> Dict[str, Any]:
"""
Analyze search results with scoring
Args:
response: Search API response
min_score: Minimum quality score threshold
Returns:
Analysis results with scores and recommendations
"""
# Implementation with type safety
/**
* Analyze search results with scoring
*/
function analyzeSearchResults(
response: Perplexity.Search.SearchCreateResponse,
minScore: number = 0.5
): { scores: number[]; recommendations: string[] } {
// Implementation with type safety
}
Related Resources
Error Handling
Type-safe error handling patterns
Best Practices
Type safety in production code