Skip to main content
Alternatives/Alternative / Tavily

Tavily-Style Search API — Free to Self-Host (2026)

Tavily-style search API, free to self-host on Docker. AGPL-3.0 OSS. Compatibility matrix, migration adapter, and a hosted plan when you don't run servers.

Published
April 5, 2026
Updated
May 29, 2026
Category
alternatives
Verdict

Choose fastCRW when you want Tavily-style search you can self-host on Docker for $0, with a documented migration adapter and a hosted plan as a fallback.

Free to self-host (AGPL-3.0): docker compose up — no API key, no per-credit billingTavily-style /v1/search endpoint with documented compatibility matrix + Python adapter shimHosted plan for teams that don't want to run servers, with attributed migration path

TL;DR — pick your path before reading the matrix

This page serves three readers. If you're:

  • Hunting a hosted Tavily alternative, jump to the hosted plan section. Tavily's free Researcher tier (1,000 credits/month) and PAYG ($0.008/credit) are the obvious paid options to compare against.
  • Looking for OSS or self-hosted, skip to free to self-host. fastCRW is AGPL-3.0; OrioSearch, agent-search, and Vane are the other live OSS projects worth knowing about.
  • Weighing Tavily's domain/country filtering, the where Tavily still has an edge section covers that one gap directly.

fastCRW Cloud (hosted, paid) and fastCRW (OSS) (AGPL-3.0, free to self-host) are different products. Above the fold this page is mostly about the OSS one — the part that's free.

At-a-glance comparison

Decision areafastCRW (OSS)fastCRW CloudTavily
Pricing$0 + your serverHosted planFree Researcher tier (1,000 cr/mo); PAYG $0.008/credit
LicenseAGPL-3.0Proprietary (managed)Proprietary
HostingSelf-host on DockerManagedCloud-only
Search endpoint/v1/search (Tavily-style)/v1/search (Tavily-style)/search
Synthesized answerYes (your own LLM key)Yes (managed LLM, paid plans)Yes (include_answer)
Batch extractYes — /v1/extract, up to 50 URLsYes — /v1/extract, up to 50 URLsYes (up to 20 URLs)
MCP servercrw_search/crw_scrape/crw_crawl/crw_mapSametavily-search/tavily-extract
Migration adapterPython shim includedSamen/a

fastCRW ships things Tavily doesn't: free self-hosting, MCP across scrape/crawl/map, AGPL source code, a batched /v1/extract that takes up to 50 URLs per call, and its own Research API (/v1/search/research/papers) fanning out to arXiv, OpenAlex, and Semantic Scholar. Answer synthesis works on both sides — self-host via your own configured LLM key, Cloud via the managed LLM (paid plans; FREE has no LLM features). The one real difference: Tavily has dedicated include_domains/exclude_domains and country filtering that fastCRW does not.

Free to self-host: the durable argument

The strongest reason to evaluate fastCRW is that you can run it for $0 beyond your own server. The compose stack:

git clone https://github.com/us/crw && cd crw
cp .env.example .env
docker compose up --build
# fastCRW + hardened search backend + Redis on :8080

What you get for $0:

  • A Tavily-style /v1/search endpoint with optional Bearer auth.
  • /v1/scrape, /v1/crawl, /v1/map with the same bearer-token model.
  • An MCP server (crw-mcp) wired for Claude Desktop, Cursor, and Windsurf.
  • A search-backend sidecar configured with read-only rootfs, dropped Linux capabilities, no-new-privileges, memory and PID limits, and a pinned image tag. The hardening config is in the repo; you can audit it.

What you don't get:

  • An external service that absorbs upstream rate limits. A self-hosted search backend is at the mercy of the engines it queries. At scale, move to hosted.
  • A managed uptime SLA. Self-hosted means you own the pager.

Read the self-hosting hardening notes →

Compatibility matrix

The single load-bearing claim on this page is Tavily-style — same concepts, different param names. Below is the abridged matrix; the full row-by-row version lives in COMPATIBILITY.md.

Search request

| Surface | Tavily | fastCRW | Compatible? | | ------------ | ------------------------------------------ | ----------------------------------------------------------------------------------- | ---------------- | ---------- | -------- | | Path | POST /search | POST /v1/search | adapter required | | Auth | Authorization: Bearer tvly-<key> | Authorization: Bearer <key> (optional self-host) | similar shape | | Result count | max_results (default 5, max 20) | limit (default 5, max 20) | rename only | | Time filter | time_range (day/week/month/year) | tbs (qdr:d/qdr:w/qdr:m/qdr:y) | semantic match | | Topic | topic (general/news/finance) | sources: ["web" | "news" | "images"] | overlaps | | Answer mode | include_answer | answer: true — self-host via your own LLM key, Cloud via managed LLM (paid plans) | match | | Raw content | include_raw_content | scrapeOptions.formats | shape differs |

Search response

Field (Tavily)Field (fastCRW)Match?
answerpresent when answer: true — self-host via your own LLM key, Cloud via managed LLM (paid plans)
results[].titledata[].title
results[].urldata[].url
results[].contentdata[].descriptionrenamed
results[].scoredata[].scorescale differs (treat as ordinal)
results[].raw_contentdata[].markdown (when scrapeOptions set)shape differs

Other endpoints

EndpointTavilyfastCRW
Extract/extract (batched, ≤20 URLs)/v1/extract (batched, ≤50 URLs)
Crawl/crawl/v1/crawl (different param names)
Map/map/v1/map
Research/research (async + SSE)/v1/search/research/papers — arXiv, OpenAlex, Semantic Scholar fan-out
MCP toolstavily-search, tavily-extractcrw_search, crw_scrape, crw_crawl, crw_map, crw_check_crawl_status

The forbidden phrase on this page is drop-in replacement. The honest phrase is Tavily-style with adapter. The next section ships the adapter.

Migration in 5 minutes — Python adapter shim

If you have existing code calling Tavily, this shim lets a Tavily-shape call hit fastCRW. Drop it in, swap your client, you're migrated.

import requests

class CrwTavilyShim:
    """Adapt Tavily-style calls to fastCRW /v1/search.

    Caveats vs real Tavily:
      - This minimal shim omits `answer` synthesis for brevity; pass
        `answer: true` directly in the request body to enable it
        (self-host via your own LLM key, Cloud via managed LLM on paid plans).
      - No `include_domains` / `exclude_domains` / `country` filtering.
      - `score` is upstream-derived; treat as ordinal not absolute.
      - `raw_content` requires scrapeOptions; this shim wires it through.
    """
    def __init__(self, base_url: str, api_key: str | None = None):
        self.base_url = base_url.rstrip("/")
        self.headers = {"Content-Type": "application/json"}
        if api_key:
            self.headers["Authorization"] = f"Bearer {api_key}"

    def search(
        self,
        query: str,
        *,
        max_results: int = 5,
        topic: str = "general",
        time_range: str | None = None,
        include_raw_content: bool | str = False,
        **_unsupported,
    ) -> dict:
        sources = {"general": ["web"], "news": ["news"]}.get(topic, ["web"])
        body = {"query": query, "limit": max_results, "sources": sources}
        if time_range:
            tbs_map = {"day": "qdr:d", "week": "qdr:w", "month": "qdr:m", "year": "qdr:y"}
            body["tbs"] = tbs_map.get(time_range, time_range)
        if include_raw_content:
            body["scrapeOptions"] = {"formats": ["markdown"], "onlyMainContent": True}
        r = requests.post(f"{self.base_url}/v1/search", json=body, headers=self.headers)
        r.raise_for_status()
        data = r.json()["data"]
        web = data["web"] if isinstance(data, dict) and "web" in data else data
        return {
            "query": query,
            "answer": "",  # this shim omits answers; pass answer:true in the request body to enable synthesis
            "results": [
                {
                    "title": item["title"],
                    "url": item["url"],
                    "content": item.get("description", ""),
                    "score": item.get("score"),
                    "raw_content": item.get("markdown"),
                }
                for item in web
            ],
        }


# Usage:
# client = CrwTavilyShim("http://localhost:8080", api_key=None)  # self-hosted, no auth
# client = CrwTavilyShim("https://api.fastcrw.com", api_key=os.environ["FASTCRW_KEY"])
# results = client.search("agentic search benchmarks", max_results=10, topic="news")

The shim is intentionally small — under 50 lines — so you can audit and adapt it. The full version with retry, backoff, and async support lives in the docs/search reference.

Pricing math at scale

VolumeTavily PAYGTavily Researcher (free)fastCRW (OSS, your server)fastCRW Cloud
1,000 req/mo$8covered (1,000 credits free)~$5 server cost (Hetzner CX22)included in entry plan
10,000 req/mo$80not coveredsame serverhosted plan
100,000 req/mo$800not covered~$15 server (CX42) + opshosted plan
1,000,000 req/mo$8,000not covered~$60 server cluster + opsenterprise

Two notes on the numbers above:

  • "$0 to self-host" is software cost. Server time, monitoring, and your hours are real costs.
  • At occasional, very-low-volume use, Tavily's free Researcher tier has no cost at all. fastCRW's upgrade math wins from 5K–10K+ requests/month, where the server or hosted plan cost is already amortized.

Open the hosted pricing →

License notice (AGPL-3.0)

fastCRW is licensed under AGPL-3.0. The full license text is at gnu.org/licenses/agpl-3.0.html. AGPL has specific requirements for network-deployed modifications to the licensed software — calling the API from your application is not a modification. Consult your own legal counsel for your specific deployment; we deliberately do not author license interpretation in this page.

If your organization has a hard rule against AGPL-licensed dependencies, fastCRW Cloud is the obvious path — the cloud build is a separate offering with separate terms.

Vendor consolidation note (Nebius acquisition, Feb 2026)

Nebius announced its agreement to acquire Tavily on 2026-02-10: $275M cash + up to $125M earnouts. The official Nebius release confirms Tavily continues operating under its own brand, with founder Rotem Weiss joining Nebius. The deal had not closed publicly as of May 2026.

What this means for buyers:

  • Today, nothing has changed for Tavily users. Pricing, API surface, and roadmap all match pre-acquisition state.
  • The risk on the table is vendor consolidation — Tavily becomes a feature of Nebius's AI cloud, not an independent service.
  • If your procurement process treats consolidation as risk, the OSS fallback is exactly the question this page is built to answer.

This is not "Tavily is dying." Tavily reports ~1M developers and 3M monthly SDK downloads; the founding team is staying on. The angle is supply-chain optionality, not FUD.

Where Tavily still has an edge

One dimension where Tavily is genuinely ahead today: dedicated include_domains/exclude_domains filtering and country targeting, built directly into its search request shape. If those two params are load-bearing for your product right now, factor that in.

Everywhere else — self-hosting, MCP breadth, LLM-synthesized answers, batched multi-URL extract, and dedicated research tooling — fastCRW matches or goes further, and if your needs are broader than single-API search (scrape + crawl + map + self-host), fastCRW is the better-shaped tool.

Hosted plan: when you don't want to run servers

Some teams want Tavily-style endpoints, OSS-grade transparency, and a credit card instead of a Docker compose file. fastCRW Cloud is the same API surface as the OSS build, run by us, with usage-based pricing competitive with Tavily PAYG at the 10K–100K req/mo range. See the pricing page →

  1. Read the compatibility matrix above. Confirm include_domains/exclude_domains/country filtering, the one real gap, isn't a deal-breaker for your workload.
  2. Spin up the OSS stack locally: docker compose up. Hit /v1/search with curl. Make sure the response shape works for your code.
  3. Drop in the migration adapter. Swap TavilyClient for CrwTavilyShim in one staging service.
  4. Decide hosted vs self-host based on volume. Below ~5K req/mo, a free-tier trial (yours or Tavily's) is a fine way to kick the tires. 5K–100K, the OSS self-host or fastCRW Cloud both make sense depending on your ops appetite. Above 100K, talk to us.
  5. If you want to compare against more OSS options, read open-source Tavily alternatives (covers OrioSearch, agent-search, and Vane) and self-hosted search APIs (the broader category, devops-focused).

You can also compare against adjacent paid APIs: fastCRW vs Firecrawl, fastCRW vs SerpAPI, and Tavily vs Serper for the head-to-head between the two paid search APIs.

Three calls to action

  • Deploy OSSgit clone github.com/us/crw && docker compose up. Quickstart →
  • View docs — endpoint reference, error codes, MCP tool schema. Search docs →
  • Start hosted plan — managed, no Docker. Pricing →

Continue exploring

More from Alternatives

View all alternatives

Related hubs

Keep the crawl path moving