Skip to main content

Overview

FeatureSupported
Supported Providersperplexity, tavily, parallel_ai, exa_ai, brave, google_pse, dataforseo, firecrawl, searxng, linkup, duckduckgo, searchapi, serper, you_com, apiserpent, agentcore, nimble, bing_grounding
Cost Tracking✅
Logging✅
Load Balancing❌
info

Supported from LiteLLM v1.78.7+

LiteLLM Python SDK Usage​

Quick Start​

Basic Search
from litellm import search
import os

os.environ["PERPLEXITYAI_API_KEY"] = "pplx-..."

response = search(
query="latest AI developments in 2024",
search_provider="perplexity",
max_results=5
)

# Access search results
for result in response.results:
print(f"{result.title}: {result.url}")
print(f"Snippet: {result.snippet}\n")

To use Parallel AI Search, set PARALLEL_API_KEY and pass search_provider="parallel_ai".

Async Usage​

Async Search
from litellm import asearch
import os, asyncio

os.environ["PERPLEXITYAI_API_KEY"] = "pplx-..."

async def search_async():
response = await asearch(
query="machine learning research papers",
search_provider="perplexity",
max_results=10,
search_domain_filter=["arxiv.org", "nature.com"]
)

# Access search results
for result in response.results:
print(f"{result.title}: {result.url}")
print(f"Snippet: {result.snippet}")

asyncio.run(search_async())

Optional Parameters​

Search with Options
response = search(
query="AI developments",
search_provider="perplexity",
# Unified parameters (work across all providers)
max_results=10, # Maximum number of results (1-20)
search_domain_filter=["arxiv.org"], # Filter to specific domains
country="US", # Country code filter
max_tokens_per_page=1024 # Max tokens per page
)

LiteLLM AI Gateway Usage​

LiteLLM provides a Perplexity API compatible /search endpoint for search calls.

Setup

Add this to your litellm proxy config.yaml

config.yaml
model_list:
- model_name: gpt-5.6-terra
litellm_params:
model: gpt-5.6-terra
api_key: os.environ/OPENAI_API_KEY

search_tools:
- search_tool_name: perplexity-search
litellm_params:
search_provider: perplexity
api_key: os.environ/PERPLEXITYAI_API_KEY

- search_tool_name: tavily-search
litellm_params:
search_provider: tavily
api_key: os.environ/TAVILY_API_KEY

- search_tool_name: parallel-search
litellm_params:
search_provider: parallel_ai
api_key: os.environ/PARALLEL_API_KEY

Start litellm

litellm --config /path/to/config.yaml

# RUNNING on http://0.0.0.0:4000

Test Request​

Option 1: Search tool name in URL (Recommended - keeps body Perplexity-compatible)

cURL Request
curl http://0.0.0.0:4000/v1/search/perplexity-search \
-H "Authorization: Bearer $LITELLM_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"query": "latest AI developments 2024",
"max_results": 5,
"search_domain_filter": ["arxiv.org", "nature.com"],
"country": "US"
}'

Option 2: Search tool name in body

cURL Request with search_tool_name in body
curl http://0.0.0.0:4000/v1/search \
-H "Authorization: Bearer $LITELLM_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"search_tool_name": "perplexity-search",
"query": "latest AI developments 2024",
"max_results": 5
}'

Load Balancing​

Give multiple search tools the same search_tool_name to load balance across them. Each request picks one of the matching tools at random. router_settings.routing_strategy does not apply to search tools, so strategies like least-busy or latency-based-routing have no effect on which provider serves a search request

config.yaml with load balancing
search_tools:
- search_tool_name: my-search
litellm_params:
search_provider: perplexity
api_key: os.environ/PERPLEXITYAI_API_KEY

- search_tool_name: my-search
litellm_params:
search_provider: tavily
api_key: os.environ/TAVILY_API_KEY

- search_tool_name: my-search
litellm_params:
search_provider: exa_ai
api_key: os.environ/EXA_API_KEY

- search_tool_name: my-search
litellm_params:
search_provider: brave
api_key: os.environ/BRAVE_API_KEY

Test with load balancing:

curl http://0.0.0.0:4000/v1/search/my-search \
-H "Authorization: Bearer $LITELLM_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"query": "AI developments",
"max_results": 10
}'

Restrict Search Tool Access​

Set search_tools under object_permission on a key or team to limit which search tools it can call. The allowlist applies to /search, /v1/search, /search/{search_tool_name}, web search interception, router fallbacks between search tools, and /search_tools/list

Grant a team one search tool
curl http://0.0.0.0:4000/team/new \
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
-H "Content-Type: application/json" \
-d '{
"team_alias": "research",
"object_permission": {"search_tools": ["tavily-search"]}
}'

By default an empty or missing search_tools list allows every search tool. To make every search tool opt-in, turn on search_tool_deny_by_default:

config.yaml
general_settings:
search_tool_deny_by_default: true

The setting defaults to false. With it on, the requested search tool must be listed in object_permission.search_tools of each identity the request resolves to

CallerGrants required
Virtual key without a teamThe key
Virtual key with a teamThe key and its team
Team member without a virtual key (JWT or lite login session)The team the request resolved to
User without a virtual key or teamThe user

A missing permission record, a null list, and an empty list all grant nothing. A user's personal grants only count when the request has no virtual key and no team, so they never widen or narrow a key or team request. If a key names a team that cannot be loaded, the request is denied rather than treated as a key without a team. Denied requests return 403 before any search provider is called, with key_search_tool_access_denied, team_search_tool_access_denied, or user_search_tool_access_denied, and /search_tools/list only returns the tools the caller may call

For a team key, grant the tool on both objects:

Team and key both grant the search tool
curl -X POST 'http://localhost:4000/team/new' \
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
-H 'Content-Type: application/json' \
-d '{"team_alias": "research", "object_permission": {"search_tools": ["tavily-search"]}}'

curl -X POST 'http://localhost:4000/key/generate' \
-H "Authorization: Bearer $LITELLM_MASTER_KEY" \
-H 'Content-Type: application/json' \
-d '{"team_id": "<team_id from above>", "object_permission": {"search_tools": ["tavily-search"]}}'

The master key and dashboard login sessions are not restricted. A proxy admin calling with its own virtual key is restricted like any other key. Web search interception with no registered search tool stops falling back to the default provider for every restricted caller, since there is no tool name a grant could list. Existing keys and teams with empty lists lose search access as soon as the setting is on

Setting the flag back to false restores the earlier behavior, where an empty or unset list means unrestricted. A nonempty search_tools list that leaves out the requested tool is still rejected

Request/Response Format​

info

LiteLLM follows the Perplexity Search API specification.

See the official Perplexity Search documentation for complete details.

Example Request​

Search Request
{
"query": "latest AI developments 2024",
"max_results": 10,
"search_domain_filter": ["arxiv.org", "nature.com"],
"country": "US",
"max_tokens_per_page": 1024
}

Request Parameters​

ParameterTypeRequiredDescription
querystring or arrayYesSearch query. Can be a single string or array of strings
search_providerstringYes (SDK)The search provider to use: "perplexity", "tavily", "parallel_ai", "exa_ai", "brave", "google_pse", "dataforseo", "firecrawl", "searxng", "linkup", "duckduckgo", "searchapi", "serper", or "you_com" or "apiserpent" or "agentcore" or "bing_grounding"
search_tool_namestringYes (Proxy)Name of the search tool configured in config.yaml
max_resultsintegerNoMaximum number of results to return (1-20). Default: 10
search_domain_filterarrayNoList of domains to filter results (max 20 domains)
max_tokens_per_pageintegerNoMaximum tokens per page to process. Default: 1024
countrystringNoCountry code filter (e.g., "US", "GB", "DE")

Query Format Examples:

# Single query
query = "AI developments"

# Multiple queries
query = ["AI developments", "machine learning trends"]

Response Format​

The response follows Perplexity's search format with the following structure:

Search Response
{
"object": "search",
"results": [
{
"title": "Latest Advances in Artificial Intelligence",
"url": "https://arxiv.org/paper/example",
"snippet": "This paper discusses recent developments in AI...",
"date": "2024-01-15"
},
{
"title": "Machine Learning Breakthroughs",
"url": "https://nature.com/articles/ml-breakthrough",
"snippet": "Researchers have achieved new milestones...",
"date": "2024-01-10"
}
]
}

Response Fields​

FieldTypeDescription
objectstringAlways "search" for search responses
resultsarrayList of search results
results[].titlestringTitle of the search result
results[].urlstringURL of the search result
results[].snippetstringText snippet from the result
results[].datestringOptional publication or last updated date

Supported Providers​

ProviderEnvironment Variablesearch_provider Value
Perplexity AIPERPLEXITYAI_API_KEYperplexity
TavilyTAVILY_API_KEYtavily
Exa AIEXA_API_KEYexa_ai
Brave SearchBRAVE_API_KEYbrave
Parallel AIPARALLEL_AI_API_KEYparallel_ai
Google PSEGOOGLE_PSE_API_KEY, GOOGLE_PSE_ENGINE_IDgoogle_pse
DataForSEODATAFORSEO_LOGIN, DATAFORSEO_PASSWORDdataforseo
FirecrawlFIRECRAWL_API_KEYfirecrawl
SearXNGSEARXNG_API_BASE (required)searxng
LinkupLINKUP_API_KEYlinkup
SerperSERPER_API_KEYserper
DuckDuckGoDUCKDUCKGO_API_BASEduckduckgo
SearchAPI.ioSEARCHAPI_API_KEYsearchapi
You.comYOUCOM_API_KEY (optional — omit for keyless free tier)you_com
APISerpentAPISERPENT_API_KEYapiserpent
Bedrock AgentCoreAGENTCORE_GATEWAY_URL (required), AWS credentials or AGENTCORE_GATEWAY_TOKENagentcore
NimbleNIMBLE_API_KEYnimble
Grounding with Bing (Microsoft Foundry)BING_GROUNDING_PROJECT_ENDPOINT, BING_GROUNDING_MODEL (required), api_key or BING_GROUNDING_TOKEN or azure-identitybing_grounding

See the individual provider documentation for detailed setup instructions and provider-specific parameters.