Tavily Search

The Search feature is the foundational capability of the Tavily platform. Unlike consumer search engines, the Tavily Search API is engineered from the ground up for Retrieval-Augmented Generation (RAG) and autonomous AI agents. It doesn't just return links; it returns parsed, dense, factual context.

The search() method is your primary entry point. At a minimum, it requires a single query string.

from tavily import TavilyClient

client = TavilyClient()
response = client.search("What were the key takeaways from the latest Federal Reserve meeting?")

Advanced Search Parameters

To get the most out of Tavily, you should tune the search parameters to match your specific use case. The .search() method accepts numerous keyword arguments:

Search Depth

search_depth determines how aggressively Tavily fetches and processes data. Valid options are "basic", "advanced", "fast", or "ultra-fast".

  • "basic" (default): Fast and efficient. Good for general factual queries.
  • "advanced": Performs deeper crawling and analysis of the returned pages to ensure the extracted context perfectly answers the prompt. Takes slightly longer but yields superior quality for complex queries.
  • "fast" / "ultra-fast": Optimized for extreme low-latency requirements, trading off some depth for speed.

Content Filters

  • topic ("general", "news", "finance"): Tailors the underlying search indices. For example, topic="news" heavily prioritizes recent publications and journalistic sources.
  • days (int): Restricts results to articles published within the last N days. Crucial for queries about fast-moving events.
  • include_domains (List[str]): A strict allowlist. If provided, Tavily will only search within these domains (e.g., ["bloomberg.com", "wsj.com"]).
  • exclude_domains (List[str]): A strict blocklist. Useful for removing noisy sites (e.g., ["reddit.com", "quora.com"]).
  • country (str): An ISO country code (e.g., "us", "uk", "fr") to localize the search results, ensuring regional relevance.

Response Formatting

  • max_results (int): The upper limit of sources to return. Default is usually 5.
  • include_answer (bool | "basic" | "advanced"): If enabled, Tavily will use an internal LLM to synthesize a direct answer to the query based on the search results, returning it in the "answer" field of the response payload.
  • include_raw_content (bool | "markdown" | "text"): If true, returns the entire parsed content of the webpage in the "raw_content" field, rather than just the relevant snippet. You can specify the desired format.
  • include_images (bool): If true, the response will include a list of URLs pointing to relevant images found on the parsed pages.

Comprehensive Example: Financial Analyst Agent

Imagine you are building an AI agent that analyzes recent tech stocks. You want deep, recent news, excluding opinion forums, and you want the raw text to feed into a large context window LLM.

response = client.search(
    query="Nvidia Q3 earnings report analysis and stock performance",
    search_depth="advanced",     # Ensure high-quality extraction
    topic="finance",             # Focus on financial indices
    days=7,                      # Only news from the last week
    max_results=3,               # Top 3 articles are enough
    exclude_domains=["reddit.com", "stocktwits.com"], # Remove retail chatter
    include_raw_content="markdown", # Get the full article body
    include_answer=True          # Have Tavily summarize it for us quickly
)

print(f"Tavily Summary: {response['answer']}\n")

for result in response["results"]:
    print(f"Source: {result['url']}")
    # result['raw_content'] contains the full markdown of the article
    print(f"Content Length: {len(result['raw_content'])} characters\n")

Deprecated Helper Methods

⚠️ Deprecation Warning: The SDK contains older helper methods like get_search_context(), qna_search(), and get_company_info(). These are maintained for backward compatibility but trigger DeprecationWarnings.

Why are they deprecated?

The core .search() method has evolved to handle all these use cases natively via parameters (e.g., include_answer=True replaces qna_search). You should transition to using .search() and parsing the resulting dictionary.

  • Instead of get_search_context(query): Use .search(query) and iterate over response['results'] to build your context string.
  • Instead of qna_search(query): Use .search(query, include_answer=True) and read response['answer'].