Tavily Research (Agentic Search)
The Research API is the most advanced feature of the Tavily SDK. Unlike standard Search (which is a single shot query), Research spins up an autonomous, multi-step agent on Tavily's backend.
Given a complex topic, the Research agent will break down the prompt, execute multiple distinct searches, aggregate the findings, filter out contradictions, and synthesize a final, cited report.
Because comprehensive research takes time (often 10 to 60 seconds), the API operates asynchronously from the HTTP perspective. You can interact with it via Polling (background execution) or Streaming.
Method 1: Background Execution (Polling)
When you call .research() with stream=False (the default), the API instantly returns a request_id acknowledging that the task has been queued. You must then poll the get_research() endpoint until the task completes.
Example Workflow
from tavily import TavilyClient
import time
client = TavilyClient()
# 1. Initiate the research task
response = client.research(
input="Analyze the impact of EU AI Act on open-source LLM development.",
model="pro",
citation_format="apa"
)
request_id = response["request_id"]
print(f"Research task queued. Request ID: {request_id}")
# 2. Poll for completion
max_attempts = 30
for attempt in range(max_attempts):
result = client.get_research(request_id)
if result["status"] == "completed":
print("\n✅ Research Complete!")
print("\n--- Report Content ---")
print(result["content"])
print("\n--- Sources Used ---")
for source in result["sources"]:
print(f"- {source['title']} ({source['url']})")
break
elif result["status"] == "failed":
print("\n❌ Research task failed on the server.")
break
else:
print(f"Status: {result['status']}... waiting 5 seconds.")
time.sleep(5)
Method 2: Streaming Research
If you are building a user-facing application (like a chatbot or a web dashboard), making the user wait 30 seconds staring at a loading spinner is a poor experience.
By setting stream=True, .research() returns a Python Generator of bytes, yielding chunks of the report as the agent writes them in real-time.
# Initiate streaming research
stream = client.research(
input="Compare the architectures of Transformer vs Mamba models.",
model="auto",
stream=True
)
print("Generating Report:\n")
# Iterate through the generator
for chunk in stream:
# Decode the raw bytes into a UTF-8 string
text_chunk = chunk.decode('utf-8')
# Print without newlines and flush the buffer immediately
print(text_chunk, end="", flush=True)
Note: If you are using AsyncTavilyClient, stream=True returns an AsyncGenerator, and you must use async for chunk in stream: (see Async Usage).
Research Parameters
input(str): The core prompt, task, or question to investigate.model("mini","pro","auto"): Defines the cognitive capability and thoroughness of the agent."mini": Faster, uses fewer credits, does shallow multi-search."pro": Slower, executes deep recursive searches, synthesizes massive amounts of context. Ideal for complex academic or technical queries."auto": Lets Tavily decide based on prompt complexity.
citation_format("numbered","mla","apa","chicago"): Instructs the agent on how to format inline citations within the generated report.output_schema(dict): Advanced. You can pass a standard JSON Schema dictionary. The Research agent will strictly format its final output to match this schema, guaranteeing structured data rather than free-form text. Highly recommended if feeding the output into another programmatic pipeline.