@lap v0.3
# Machine-readable API spec. Each @endpoint block is one API call.
@api Tavily Search and Extract API
@base https://api.tavily.com/
@version 1.0.0
@auth Bearer bearer
@endpoints 7
@toc search(1), extract(1), crawl(1), map(1), research(2), usage(1)

@group search
@endpoint POST /search
@desc Search for data based on a query
@required {query: str # The search query to execute with Tavily.}
@optional {search_depth: str(advanced/basic/fast/ultra-fast)=basic # Controls the latency vs. relevance tradeoff and how `results[].content` is generated: - `advanced`: Highest relevance with increased latency. Best for detailed, high-precision queries. Returns multiple semantically relevant snippets per URL (configurable via `chunks_per_source`). - `basic`: A balanced option for relevance and latency. Ideal for general-purpose searches. Returns one NLP summary per URL. - `fast`: Prioritizes lower latency while maintaining good relevance. Returns multiple semantically relevant snippets per URL (configurable via `chunks_per_source`). - `ultra-fast`: Minimizes latency above all else. Best for time-critical use cases. Returns one NLP summary per URL.  **Cost**: - `basic`, `fast`, `ultra-fast`: 1 API Credit - `advanced`: 2 API Credits  See [Search Best Practices](/documentation/best-practices/best-practices-search#search-depth) for guidance on choosing the right search depth., chunks_per_source: int=3 # Chunks are short content snippets (maximum 500 characters each) pulled directly from the source. Use `chunks_per_source` to define the maximum number of relevant chunks returned per source and to control the `content` length. Chunks will appear in the `content` field as: ` [...]  [...] `. Available only when `search_depth` is `advanced`., max_results: int=5 # The maximum number of search results to return., topic: str(general/news/finance)=general # The category of the search.`news` is useful for retrieving real-time updates, particularly about politics, sports, and major current events covered by mainstream media sources. `general` is for broader, more general-purpose searches that may include a wide range of sources., time_range: str(day/week/month/year/d/w/m/y)=null # The time range back from the current date to filter results based on publish date or last updated date. Useful when looking for sources that have published or updated data., start_date: str=null # Will return all results after the specified start date based on publish date or last updated date. Required to be written in the format YYYY-MM-DD, end_date: str=null # Will return all results before the specified end date based on publish date or last updated date. Required to be written in the format YYYY-MM-DD, include_answer: any=false # Include an LLM-generated answer to the provided query. `basic` or `true` returns a quick answer. `advanced` returns a more detailed answer., include_raw_content: any=false # Include the cleaned and parsed HTML content of each search result. `markdown` or `true` returns search result content in markdown format. `text` returns the plain text from the results and may increase latency., include_images: bool=false # Also perform an image search and include the results in the response., include_image_descriptions: bool=false # When `include_images` is `true`, also add a descriptive text for each image., include_favicon: bool=false # Whether to include the favicon URL for each result., include_domains: [str]= # A list of domains to specifically include in the search results. Maximum 300 domains., exclude_domains: [str]= # A list of domains to specifically exclude from the search results. Maximum 150 domains., country: str(afghanistan/albania/algeria/andorra/angola/argentina/armenia/australia/austria/azerbaijan/bahamas/bahrain/bangladesh/barbados/belarus/belgium/belize/benin/bhutan/bolivia/bosnia and herzegovina/botswana/brazil/brunei/bulgaria/burkina faso/burundi/cambodia/cameroon/canada/cape verde/central african republic/chad/chile/china/colombia/comoros/congo/costa rica/croatia/cuba/cyprus/czech republic/denmark/djibouti/dominican republic/ecuador/egypt/el salvador/equatorial guinea/eritrea/estonia/ethiopia/fiji/finland/france/gabon/gambia/georgia/germany/ghana/greece/guatemala/guinea/haiti/honduras/hungary/iceland/india/indonesia/iran/iraq/ireland/israel/italy/jamaica/japan/jordan/kazakhstan/kenya/kuwait/kyrgyzstan/latvia/lebanon/lesotho/liberia/libya/liechtenstein/lithuania/luxembourg/madagascar/malawi/malaysia/maldives/mali/malta/mauritania/mauritius/mexico/moldova/monaco/mongolia/montenegro/morocco/mozambique/myanmar/namibia/nepal/netherlands/new zealand/nicaragua/niger/nigeria/north korea/north macedonia/norway/oman/pakistan/panama/papua new guinea/paraguay/peru/philippines/poland/portugal/qatar/romania/russia/rwanda/saudi arabia/senegal/serbia/singapore/slovakia/slovenia/somalia/south africa/south korea/south sudan/spain/sri lanka/sudan/sweden/switzerland/syria/taiwan/tajikistan/tanzania/thailand/togo/trinidad and tobago/tunisia/turkey/turkmenistan/uganda/ukraine/united arab emirates/united kingdom/united states/uruguay/uzbekistan/venezuela/vietnam/yemen/zambia/zimbabwe)=null # Boost search results from a specific country. This will prioritize content from the selected country in the search results. Available only if topic is `general`., auto_parameters: bool=false # When `auto_parameters` is enabled, Tavily automatically configures search parameters based on your query's content and intent. You can still set other parameters manually, and your explicit values will override the automatic ones. The parameters `include_answer`, `include_raw_content`, and `max_results` must always be set manually, as they directly affect response size. Note: `search_depth` may be automatically set to advanced when it's likely to improve results. This uses 2 API credits per request. To avoid the extra cost, you can explicitly set `search_depth` to `basic`., exact_match: bool=false # Ensure that only search results containing the exact quoted phrase(s) in the query are returned, bypassing synonyms or semantic variations. Wrap target phrases in quotes within your query (e.g. `"John Smith" CEO Acme Corp`). Punctuation is typically ignored inside quotes., include_usage: bool=false # Whether to include credit usage information in the response., safe_search: bool=false # 🔒 Enterprise only.   whether to filter out adult or unsafe content from results. Not supported for `fast` or `ultra-fast` search depths.}
@returns(200) {query: str, answer: str, images: [map], results: [map], auto_parameters: map, response_time: num(float), usage: map, request_id: str} # Search results returned successfully
@errors {400: Bad Request - Your request is invalid., 401: Unauthorized - Your API key is wrong or missing., 429: Too many requests - Rate limit exceeded, 432: Key limit or Plan Limit exceeded, 433: PayGo limit exceeded, 500: Internal Server Error - We had a problem with our server.}

@endgroup

@group extract
@endpoint POST /extract
@desc Retrieve raw web content from specified URLs
@required {urls: any}
@optional {query: str # User intent for reranking extracted content chunks. When provided, chunks are reranked based on relevance to this query., chunks_per_source: int=3 # Chunks are short content snippets (maximum 500 characters each) pulled directly from the source. Use `chunks_per_source` to define the maximum number of relevant chunks returned per source and to control the `raw_content` length. Chunks will appear in the `raw_content` field as: ` [...]  [...] `. Available only when `query` is provided. Must be between 1 and 5., extract_depth: str(basic/advanced)=basic # The depth of the extraction process. `advanced` extraction retrieves more data, including tables and embedded content, with higher success but may increase latency.`basic` extraction costs 1 credit per 5 successful URL extractions, while `advanced` extraction costs 2 credits per 5 successful URL extractions., include_images: bool=false # Include a list of images extracted from the URLs in the response. Default is false., include_favicon: bool=false # Whether to include the favicon URL for each result., format: str(markdown/text)=markdown # The format of the extracted web page content. `markdown` returns content in markdown format. `text` returns plain text and may increase latency., timeout: num(float)=None # Maximum time in seconds to wait for the URL extraction before timing out. Must be between 1.0 and 60.0 seconds. If not specified, default timeouts are applied based on extract_depth: 10 seconds for basic extraction and 30 seconds for advanced extraction., include_usage: bool=false # Whether to include credit usage information in the response. `NOTE:`The value may be 0 if the total successful URL extractions has not yet reached 5 calls. See our [Credits & Pricing documentation](https://docs.tavily.com/documentation/api-credits) for details.}
@returns(200) {results: [map], failed_results: [map], response_time: num(float), usage: map, request_id: str} # Extraction results returned successfully
@errors {400: Bad Request, 401: Unauthorized - Your API key is wrong or missing., 429: Too many requests - Rate limit exceeded, 432: Key limit or Plan Limit exceeded, 433: PayGo limit exceeded, 500: Internal Server Error - We had a problem with our server.}

@endgroup

@group crawl
@endpoint POST /crawl
@desc Initiate a web crawl from a base URL
@required {url: str # The root URL to begin the crawl.}
@optional {instructions: str # Natural language instructions for the crawler. When specified, the mapping cost increases to 2 API credits per 10 successful pages instead of 1 API credit per 10 pages., chunks_per_source: int=3 # Chunks are short content snippets (maximum 500 characters each) pulled directly from the source. Use `chunks_per_source` to define the maximum number of relevant chunks returned per source and to control the `raw_content` length. Chunks will appear in the `raw_content` field as: ` [...]  [...] `. Available only when `instructions` are provided. Must be between 1 and 5., max_depth: int=1 # Max depth of the crawl. Defines how far from the base URL the crawler can explore., max_breadth: int=20 # Max number of links to follow per level of the tree (i.e., per page)., limit: int=50 # Total number of links the crawler will process before stopping., select_paths: [str]=null # Regex patterns to select only URLs with specific path patterns (e.g., `/docs/.*`, `/api/v1.*`)., select_domains: [str]=null # Regex patterns to select crawling to specific domains or subdomains (e.g., `^docs\.example\.com$`)., exclude_paths: [str]=null # Regex patterns to exclude URLs with specific path patterns (e.g., `/private/.*`, `/admin/.*`)., exclude_domains: [str]=null # Regex patterns to exclude specific domains or subdomains from crawling (e.g., `^private\.example\.com$`)., allow_external: bool=true # Whether to include external domain links in the final results list., include_images: bool=false # Whether to include images in the crawl results., extract_depth: str(basic/advanced)=basic # Advanced extraction retrieves more data, including tables and embedded content, with higher success but may increase latency. `basic` extraction costs 1 credit per 5 successful extractions, while `advanced` extraction costs 2 credits per 5 successful extractions., format: str(markdown/text)=markdown # The format of the extracted web page content. `markdown` returns content in markdown format. `text` returns plain text and may increase latency., include_favicon: bool=false # Whether to include the favicon URL for each result., timeout: num(float)=150 # Maximum time in seconds to wait for the crawl operation before timing out. Must be between 10 and 150 seconds., include_usage: bool=false # Whether to include credit usage information in the response. `NOTE:`The value may be 0 if the total use of /extract and /map have not yet reached minimum requirements. See our [Credits & Pricing documentation](https://docs.tavily.com/documentation/api-credits) for details.}
@returns(200) {base_url: str, results: [map], response_time: num(float), usage: map, request_id: str} # Crawl results returned successfully
@errors {400: Bad Request - Your request is invalid., 401: Unauthorized - Your API key is wrong or missing., 403: Forbidden - URL is not supported., 429: Too many requests - Rate limit exceeded, 432: Key limit or Plan Limit exceeded, 433: PayGo limit exceeded, 500: Internal Server Error - We had a problem with our server.}

@endgroup

@group map
@endpoint POST /map
@desc Initiate a web mapping from a base URL
@required {url: str # The root URL to begin the mapping.}
@optional {instructions: str=null # Natural language instructions for the crawler. When specified, the cost increases to 2 API credits per 10 successful pages instead of 1 API credit per 10 pages., max_depth: int=1 # Max depth of the mapping. Defines how far from the base URL the crawler can explore., max_breadth: int=20 # Max number of links to follow per level of the tree (i.e., per page)., limit: int=50 # Total number of links the crawler will process before stopping., select_paths: [str]=null # Regex patterns to select only URLs with specific path patterns (e.g., `/docs/.*`, `/api/v1.*`)., select_domains: [str]=null # Regex patterns to select crawling to specific domains or subdomains (e.g., `^docs\.example\.com$`)., exclude_paths: [str]=null # Regex patterns to exclude URLs with specific path patterns (e.g., `/private/.*`, `/admin/.*`)., exclude_domains: [str]=null # Regex patterns to exclude specific domains or subdomains from crawling (e.g., `^private\.example\.com$`)., allow_external: bool=true # Whether to include external domain links in the final results list., timeout: num(float)=150 # Maximum time in seconds to wait for the map operation before timing out. Must be between 10 and 150 seconds., include_usage: bool=false # Whether to include credit usage information in the response.`NOTE:`The value may be 0 if the total successful pages mapped has not yet reached 10 calls. See our [Credits & Pricing documentation](https://docs.tavily.com/documentation/api-credits) for details.}
@returns(200) {base_url: str, results: [str], response_time: num(float), usage: map, request_id: str} # Map results returned successfully
@errors {400: Bad Request - Your request is invalid., 401: Unauthorized - Your API key is wrong or missing., 403: Forbidden - URL is not supported., 429: Too many requests - Rate limit exceeded, 432: Key limit or Plan Limit exceeded, 433: PayGo limit exceeded, 500: Internal Server Error - We had a problem with our server.}

@endgroup

@group research
@endpoint POST /research
@desc Initiate a research task
@required {input: str # The research task or question to investigate.}
@optional {model: str(mini/pro/auto)=auto # The model used by the research agent. "mini" is optimized for targeted, efficient research and works best for narrow or well-scoped questions. "pro" provides comprehensive, multi-angle research and is suited for complex topics that span multiple subtopics or domains, stream: bool=false # Whether to stream the research results as they are generated. When 'true', returns a Server-Sent Events (SSE) stream. See [Streaming documentation](/documentation/api-reference/endpoint/research-streaming) for details., output_schema: map{properties: map, required: [str]}=null # A JSON Schema object that defines the structure of the research output. When provided, the research response will be structured to match this schema, ensuring a predictable and validated output shape. Must include a 'properties' field, and may optionally include 'required' field., citation_format: str(numbered/mla/apa/chicago)=numbered # The format for citations in the research report.}
@returns(201) {request_id: str, created_at: str, status: str, input: str, model: str, response_time: int} # Research task queued successfully (when not streaming)
@errors {400: Bad Request - Your request is invalid., 401: Unauthorized - Your API key is wrong or missing., 429: Too many requests - Rate limit exceeded, 432: Key limit or Plan Limit exceeded, 433: PayGo limit exceeded, 500: Internal Server Error - We had a problem with our server.}

@endpoint GET /research/{request_id}
@desc Get research task status and results
@required {request_id: str # The unique identifier of the research task.}
@returns(200) Research task is completed or failed.
@returns(202) {request_id: str, status: str, response_time: int} # Research task is not yet completed (pending or in_progress).
@errors {401: Unauthorized - Your API key is wrong or missing., 404: Research task not found, 500: Internal Server Error - We had a problem with our server.}

@endgroup

@group usage
@endpoint GET /usage
@desc Get API key and account usage details
@optional {X-Project-ID: str # Optional project ID to scope the usage query to a specific project}
@returns(200) {key: map{usage: int, limit: int, search_usage: int, extract_usage: int, crawl_usage: int, map_usage: int, research_usage: int}, account: map{current_plan: str, plan_usage: int, plan_limit: int, paygo_usage: int, paygo_limit: int, search_usage: int, extract_usage: int, crawl_usage: int, map_usage: int, research_usage: int}} # Usage details returned successfully
@errors {401: Unauthorized - Your API key is wrong or missing., 429: Too Many Requests}

@endgroup

@end
