> ## Documentation Index
> Fetch the complete documentation index at: https://docs.linkup.so/llms.txt
> Use this file to discover all available pages before exploring further.

# Migrating from Tavily

> Guide for switching from Tavily Search and Extract to Linkup Search and Fetch

## Overview

Switch from Tavily's **Search** and **Extract** to Linkup's [**Search**](/pages/documentation/endpoints/search/overview) and [**Fetch**](/pages/documentation/endpoints/fetch/overview) in a line of code.

| Tavily          | Linkup            | Role                             |
| --------------- | ----------------- | -------------------------------- |
| `POST /search`  | `POST /v1/search` | Web search for AI agents         |
| `POST /extract` | `POST /v1/fetch`  | Extract clean content from a URL |

**Search** is Linkup's synchronous web search endpoint, optimized for AI consumption. Given a natural-language query, the `/search` route returns ranked sources, optionally bundled with a cited natural-language answer or with structured output matching a JSON schema. **Fetch** is Linkup's real-time page content extractor. Given a URL, the `/fetch` route returns a clean markdown rendering of the page, optimized for LLM consumption.

## Quick start

### Get your API key

<Card title="Get your API key" icon="key" href="https://app.linkup.so" horizontal="True">
  Create a Linkup account for free to get your API key.
</Card>

### Install the SDK

<CodeGroup>
  ```bash Python theme={"system"}
  pip install linkup-sdk
  ```

  ```bash JavaScript theme={"system"}
  npm install linkup-sdk
  ```
</CodeGroup>

## Migrate your search calls

### Replace your API calls

**Tavily**

<CodeGroup>
  ```bash cURL theme={"system"}
  curl -X POST "https://api.tavily.com/search" \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer tvly-YOUR_API_KEY" \
    -d '{
      "query": "latest AI news",
      "search_depth": "basic",
      "max_results": 10
    }'
  ```

  ```python Python theme={"system"}
  from tavily import TavilyClient

  client = TavilyClient(api_key="tvly-YOUR_API_KEY")

  response = client.search(
      query="latest AI news",
      search_depth="basic",
      max_results=10
  )
  print(response)
  ```

  ```javascript JavaScript theme={"system"}
  const { tavily } = require("@tavily/core");

  const client = tavily({ apiKey: "tvly-YOUR_API_KEY" });

  const response = await client.search("latest AI news", {
    searchDepth: "basic",
    maxResults: 10
  });
  console.log(response);
  ```
</CodeGroup>

**Linkup**

<CodeGroup>
  ```bash cURL theme={"system"}
  curl "https://api.linkup.so/v1/search" \
    -G \
    -H "Authorization: Bearer YOUR_LINKUP_KEY" \
    --data-urlencode "q=latest AI news" \
    --data-urlencode "depth=standard" \
    --data-urlencode "outputType=searchResults" \
    --data-urlencode "maxResults=10"
  ```

  ```python Python theme={"system"}
  from linkup import LinkupClient

  client = LinkupClient(api_key="YOUR_LINKUP_KEY")

  response = client.search(
      query="latest AI news",
      depth="standard",
      output_type="searchResults",
      max_results=10
  )
  print(response)
  ```

  ```javascript JavaScript theme={"system"}
  import { LinkupClient } from 'linkup-sdk';

  const client = new LinkupClient({ apiKey: 'YOUR_LINKUP_KEY' });

  client.search({
    query: 'latest AI news',
    depth: 'standard',
    outputType: 'searchResults',
    maxResults: 10
  }).then(console.log);
  ```
</CodeGroup>

### Parameter mapping

| Tavily parameter      | Linkup parameter         | Notes                                                                                                                                                                |
| --------------------- | ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `query`               | `query`                  | Required parameter                                                                                                                                                   |
| `max_results`         | `maxResults`             | Total number of results returned. Linkup default: `10`                                                                                                               |
| `search_depth`        | `depth`                  | Map `"ultra-fast"` / `"fast"` → `"fast"`, `"basic"` → `"standard"`, `"advanced"` → `"deep"`                                                                          |
| `include_answer`      | `outputType`             | Use `"sourcedAnswer"` instead of `true` / `"basic"` / `"advanced"`                                                                                                   |
| `include_raw_content` | N/A (or **Fetch**)       | Linkup `"searchResults"` already returns content snippets. For full page content, call [**Fetch**](/pages/documentation/endpoints/fetch/overview) on the result URLs |
| `include_domains`     | `includeDomains`         | Array of domain strings                                                                                                                                              |
| `exclude_domains`     | `excludeDomains`         | Array of domain strings                                                                                                                                              |
| `start_date`          | `fromDate`               | ISO 8601 date (`YYYY-MM-DD`)                                                                                                                                         |
| `end_date`            | `toDate`                 | ISO 8601 date (`YYYY-MM-DD`)                                                                                                                                         |
| `time_range`          | `fromDate`               | Approximate with an explicit date (e.g. `"week"` → seven days ago)                                                                                                   |
| `include_images`      | `includeImages`          | Returns image results when supported                                                                                                                                 |
| N/A                   | `outputType`             | Choose `"searchResults"`, `"sourcedAnswer"`, or `"structured"`                                                                                                       |
| N/A                   | `structuredOutputSchema` | Define a custom JSON schema when `outputType` is `"structured"`                                                                                                      |

### Response format differences

**Tavily response structure**

```json theme={"system"}
{
  "query": "latest AI news",
  "results": [
    {
      "title": "Page Title",
      "url": "https://example.com",
      "content": "Snippet or summary...",
      "score": 0.95
    }
  ],
  "answer": "Optional LLM answer when include_answer is set..."
}
```

**Linkup response structure (`"searchResults"`)**

```json theme={"system"}
{
  "results": [
    {
      "name": "Page Title",
      "url": "https://example.com",
      "content": "Full content text...",
      "type": "html"
    }
  ]
}
```

**Linkup response structure (`"sourcedAnswer"`)** — replaces Tavily `include_answer`

```json theme={"system"}
{
  "answer": "Generated answer with citations...",
  "sources": [
    {
      "name": "Page Title",
      "url": "https://example.com",
      "snippet": "Relevant excerpt..."
    }
  ]
}
```

**Linkup response structure (`"structured"`)**

```json theme={"system"}
{
  "output": {
    "customField1": "Extracted data following your schema...",
    "customField2": ["Array", "of", "values"]
  }
}
```

### Examples

#### Fresh content search

**Tavily**

<CodeGroup>
  ```bash cURL theme={"system"}
  curl -X POST "https://api.tavily.com/search" \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer tvly-YOUR_API_KEY" \
    -d '{
      "query": "AI news",
      "time_range": "week",
      "include_answer": true
    }'
  ```

  ```python Python theme={"system"}
  response = client.search(
      query="AI news",
      time_range="week",
      include_answer=True
  )
  ```

  ```javascript JavaScript theme={"system"}
  const response = await client.search("AI news", {
    timeRange: "week",
    includeAnswer: true
  });
  ```
</CodeGroup>

**Linkup**

<CodeGroup>
  ```bash cURL theme={"system"}
  curl "https://api.linkup.so/v1/search" \
    -G \
    -H "Authorization: Bearer YOUR_KEY" \
    --data-urlencode "q=AI news" \
    --data-urlencode "depth=standard" \
    --data-urlencode "outputType=sourcedAnswer" \
    --data-urlencode "fromDate=2026-03-05"
  ```

  ```python Python theme={"system"}
  from datetime import date

  response = client.search(
      query="AI news",
      depth="standard",
      output_type="sourcedAnswer",
      from_date=date(2026, 3, 5)
  )
  print(response)
  ```

  ```javascript JavaScript theme={"system"}
  client.search({
    query: 'AI news',
    depth: 'standard',
    outputType: 'sourcedAnswer',
    fromDate: new Date('2026-03-05')
  }).then(console.log);
  ```
</CodeGroup>

#### Domain-specific search

**Tavily**

<CodeGroup>
  ```bash cURL theme={"system"}
  curl -X POST "https://api.tavily.com/search" \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer tvly-YOUR_API_KEY" \
    -d '{
      "query": "transformers",
      "include_domains": ["arxiv.org"]
    }'
  ```

  ```python Python theme={"system"}
  response = client.search(
      query="transformers",
      include_domains=["arxiv.org"]
  )
  ```

  ```javascript JavaScript theme={"system"}
  const response = await client.search("transformers", {
    includeDomains: ["arxiv.org"]
  });
  ```
</CodeGroup>

**Linkup**

<CodeGroup>
  ```bash cURL theme={"system"}
  curl "https://api.linkup.so/v1/search" \
    -G \
    -H "Authorization: Bearer YOUR_KEY" \
    --data-urlencode "q=transformers" \
    --data-urlencode "depth=standard" \
    --data-urlencode "outputType=searchResults" \
    --data-urlencode "includeDomains=arxiv.org"
  ```

  ```python Python theme={"system"}
  response = client.search(
      query="transformers",
      depth="standard",
      output_type="searchResults",
      include_domains=["arxiv.org"]
  )
  print(response)
  ```

  ```javascript JavaScript theme={"system"}
  client.search({
    query: 'transformers',
    depth: 'standard',
    outputType: 'searchResults',
    includeDomains: ['arxiv.org']
  }).then(console.log);
  ```
</CodeGroup>

#### Excluding domains

**Tavily**

<CodeGroup>
  ```bash cURL theme={"system"}
  curl -X POST "https://api.tavily.com/search" \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer tvly-YOUR_API_KEY" \
    -d '{
      "query": "python tutorial",
      "exclude_domains": ["w3schools.com"]
    }'
  ```

  ```python Python theme={"system"}
  response = client.search(
      query="python tutorial",
      exclude_domains=["w3schools.com"]
  )
  ```

  ```javascript JavaScript theme={"system"}
  const response = await client.search("python tutorial", {
    excludeDomains: ["w3schools.com"]
  });
  ```
</CodeGroup>

**Linkup**

<CodeGroup>
  ```bash cURL theme={"system"}
  curl "https://api.linkup.so/v1/search" \
    -G \
    -H "Authorization: Bearer YOUR_KEY" \
    --data-urlencode "q=python tutorial" \
    --data-urlencode "depth=standard" \
    --data-urlencode "outputType=searchResults" \
    --data-urlencode "excludeDomains=w3schools.com"
  ```

  ```python Python theme={"system"}
  response = client.search(
      query="python tutorial",
      depth="standard",
      output_type="searchResults",
      exclude_domains=["w3schools.com"]
  )
  print(response)
  ```

  ```javascript JavaScript theme={"system"}
  client.search({
    query: 'python tutorial',
    depth: 'standard',
    outputType: 'searchResults',
    excludeDomains: ['w3schools.com']
  }).then(console.log);
  ```
</CodeGroup>

## Migrate your extraction calls

Tavily **Extract** pulls content from one or more URLs. Linkup **Fetch** extracts clean markdown from a single public URL (HTML or PDF), with optional JavaScript rendering.

<Info>
  **Fetch** accepts one `url` per request. If you currently pass an array of URLs to Tavily **Extract**, call Linkup **Fetch** once per URL (or in parallel). For batch workloads, submit your **Fetch** calls through [**Tasks**](/pages/documentation/endpoints/tasks/overview) — up to 100 per submission, with exactly the same parameters and pricing as direct `/fetch` calls.
</Info>

### Replace your API calls

**Tavily**

<CodeGroup>
  ```bash cURL theme={"system"}
  curl -X POST "https://api.tavily.com/extract" \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer tvly-YOUR_API_KEY" \
    -d '{
      "urls": ["https://docs.linkup.so"]
    }'
  ```

  ```python Python theme={"system"}
  from tavily import TavilyClient

  client = TavilyClient(api_key="tvly-YOUR_API_KEY")

  response = client.extract(
      urls=["https://docs.linkup.so"]
  )
  print(response)
  ```

  ```javascript JavaScript theme={"system"}
  const { tavily } = require("@tavily/core");

  const client = tavily({ apiKey: "tvly-YOUR_API_KEY" });

  const response = await client.extract(["https://docs.linkup.so"]);
  console.log(response);
  ```
</CodeGroup>

**Linkup**

<CodeGroup>
  ```bash cURL theme={"system"}
  curl -X POST "https://api.linkup.so/v1/fetch" \
    -H "Authorization: Bearer YOUR_LINKUP_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "url": "https://docs.linkup.so",
      "renderJs": true
    }'
  ```

  ```python Python theme={"system"}
  from linkup import LinkupClient

  client = LinkupClient(api_key="YOUR_LINKUP_KEY")

  response = client.fetch(
      url="https://docs.linkup.so",
      render_js=True,
  )
  print(response)
  ```

  ```javascript JavaScript theme={"system"}
  import { LinkupClient } from 'linkup-sdk';

  const client = new LinkupClient({ apiKey: 'YOUR_LINKUP_KEY' });

  const response = await client.fetch({
    url: 'https://docs.linkup.so',
    renderJs: true,
  });
  console.log(response);
  ```
</CodeGroup>

### Response format differences

**Tavily response structure**

```json theme={"system"}
{
  "results": [
    {
      "url": "https://docs.linkup.so",
      "raw_content": "# Page title\n\nExtracted content..."
    }
  ],
  "failed_results": []
}
```

**Linkup response structure**

```json theme={"system"}
{
  "markdown": "# Page title\n\nExtracted content...",
  "rawHtml": "<!doctype html><html>...</html>",
  "images": [
    { "alt": "Logo", "url": "https://example.com/logo.svg" }
  ]
}
```

`rawHtml` is present only when `includeRawHtml` is `true`. `images` is present only when `extractImages` is `true`. `markdown` is always returned.

### Examples

#### JavaScript-rendered pages

**Tavily**

<CodeGroup>
  ```bash cURL theme={"system"}
  curl -X POST "https://api.tavily.com/extract" \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer tvly-YOUR_API_KEY" \
    -d '{
      "urls": ["https://example.com/dashboard"],
      "extract_depth": "advanced"
    }'
  ```

  ```python Python theme={"system"}
  response = client.extract(
      urls=["https://example.com/dashboard"],
      extract_depth="advanced"
  )
  ```

  ```javascript JavaScript theme={"system"}
  const response = await client.extract(["https://example.com/dashboard"], {
    extractDepth: "advanced"
  });
  ```
</CodeGroup>

**Linkup**

<CodeGroup>
  ```bash cURL theme={"system"}
  curl -X POST "https://api.linkup.so/v1/fetch" \
    -H "Authorization: Bearer YOUR_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "url": "https://example.com/dashboard",
      "renderJs": true
    }'
  ```

  ```python Python theme={"system"}
  response = client.fetch(
      url="https://example.com/dashboard",
      render_js=True,
  )
  print(response)
  ```

  ```javascript JavaScript theme={"system"}
  const response = await client.fetch({
    url: 'https://example.com/dashboard',
    renderJs: true,
  });
  console.log(response);
  ```
</CodeGroup>

#### Extract images with content

**Tavily**

<CodeGroup>
  ```bash cURL theme={"system"}
  curl -X POST "https://api.tavily.com/extract" \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer tvly-YOUR_API_KEY" \
    -d '{
      "urls": ["https://docs.linkup.so"],
      "include_images": true
    }'
  ```

  ```python Python theme={"system"}
  response = client.extract(
      urls=["https://docs.linkup.so"],
      include_images=True
  )
  ```

  ```javascript JavaScript theme={"system"}
  const response = await client.extract(["https://docs.linkup.so"], {
    includeImages: true
  });
  ```
</CodeGroup>

**Linkup**

<CodeGroup>
  ```bash cURL theme={"system"}
  curl -X POST "https://api.linkup.so/v1/fetch" \
    -H "Authorization: Bearer YOUR_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "url": "https://docs.linkup.so",
      "extractImages": true
    }'
  ```

  ```python Python theme={"system"}
  response = client.fetch(
      url="https://docs.linkup.so",
      extract_images=True
  )
  print(response)
  ```

  ```javascript JavaScript theme={"system"}
  const response = await client.fetch({
    url: 'https://docs.linkup.so',
    extractImages: true
  });
  console.log(response);
  ```
</CodeGroup>

## Need help?

* Check our [Quickstart Guide](/pages/documentation/get-started/quickstart)
* Read [Search best practices](/pages/documentation/endpoints/search/best-practices) and [Fetch best practices](/pages/documentation/endpoints/fetch/best-practices)
* Join our [Discord Community](https://discord.gg/9q9mCYJa86)
* Explore the [Search](/pages/documentation/endpoints/search/reference) and [Fetch](/pages/documentation/endpoints/fetch/reference) API references

<Info>
  Your Linkup account starts with \$20 of free credit when you sign up with a professional email address. You can monitor usage and add more credit in the [Billing](https://app.linkup.so/organization/billing) section.
</Info>
