Skip to main content

Exa AI Search

Get API Key: https://exa.ai

LiteLLM Python SDK​

Exa AI Search
import os
from litellm import search

os.environ["EXA_API_KEY"] = "exa-..."

response = search(
query="latest AI developments",
search_provider="exa_ai",
max_results=5
)

LiteLLM AI Gateway​

1. Setup config.yaml​

config.yaml
model_list:
- model_name: gpt-6.1-sol
litellm_params:
model: gpt-6.1-sol
api_key: os.environ/OPENAI_API_KEY

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

2. Start the proxy​

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

# RUNNING on http://0.0.0.0:4000

3. Test the search endpoint​

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

Provider-specific Parameters​

Exa AI Search with Provider-specific Parameters
import os
from litellm import search

os.environ["EXA_API_KEY"] = "exa-..."

response = search(
query="AI research papers",
search_provider="exa_ai",
max_results=10,
search_domain_filter=["arxiv.org"],
# Exa-specific parameters
type="neural", # 'neural', 'keyword', or 'auto'
contents={"text": True}, # Request text content
use_autoprompt=True # Enable Exa's autoprompt
)

Exa Response Fields​

Exa results carry the same title, url, snippet and date fields as every other search provider. On top of those, each result keeps Exa's highlights, highlight_scores and score whenever Exa returned them, and the response keeps every top-level field Exa sent except results (such as requestId, searchTime and costDollars) under provider_metadata. A result Exa sent without these fields keeps the plain shape.

FieldWherePresent when
results[].highlightseach resultyou request contents.highlights
results[].highlight_scoreseach resultExa scores the highlights
results[].scoreeach resultyou use type="neural"
provider_metadatathe responseevery Exa response

highlights are the sentences Exa picked from the page as the best match for your query. When you ask for highlights without text, snippet is those highlights joined together. provider_metadata.costDollars is what Exa charged for the call, so you can reconcile it with the cost LiteLLM tracked in x-litellm-response-cost and the spend logs.

Exa AI Search with highlights
import os
from litellm import search

os.environ["EXA_API_KEY"] = "exa-..."

response = search(
query="regional bank net interest margin outlook",
search_provider="exa_ai",
max_results=2,
type="neural",
contents={"highlights": {"numSentences": 1}},
)

for result in response.results:
print(result.score, result.highlights)

print(response.provider_metadata["costDollars"])
Same request through the AI Gateway
curl http://0.0.0.0:4000/v1/search/exa-search \
-H "Authorization: Bearer $LITELLM_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"query": "regional bank net interest margin outlook",
"max_results": 2,
"type": "neural",
"contents": {"highlights": {"numSentences": 1}}
}'
Response
{
"object": "search",
"results": [
{
"title": "Q2 earnings: net interest margin up 1 basis point",
"url": "https://example.com/q2-earnings",
"snippet": "Net interest income grew $9.3 million linked quarter.",
"date": "2026-08-31T15:00:25.000Z",
"last_updated": null,
"highlights": ["Net interest income grew $9.3 million linked quarter."],
"score": 0.42
}
],
"provider_metadata": {
"requestId": "1c8916cb62f8d5a7d6ea19515a26d5dc",
"resolvedSearchType": "neural",
"searchTime": 6.5,
"costDollars": {"total": 0.004, "search": {"neural": 0.004}}
}
}

Web search interception passes only each result's title, URL and snippet to the model, so these extra fields never reach the model's context.

LiteLLM Enterprise
SSO/SAML, audit logs, spend tracking, multi-team management, and guardrails, built for production.
Learn more →