Migrate from Tavily to fastCRW — Search API Migration Guide
Migrate from Tavily search API to fastCRW POST /v1/search. fastCRW search averaged 880 ms across a 100-query benchmark, and adds scrape, crawl, and map. Param mapping table, before/after code, and honest gaps (BYOK-only answer synthesis, no domain filters).
Migrating from Tavily to fastCRW maps the Tavily search call onto POST /v1/search with renamed params — and adds scrape, crawl, and map that Tavily does not offer.
Verdict
Migrating from Tavily to fastCRW takes about 15 minutes because fastCRW exposes a Tavily-style REST search API on POST /v1/search — most of the work is renaming parameters (max_results → limit, time_range → tbs, topic → sources). The upside beyond search: fastCRW also runs /v1/scrape, /v1/crawl, and /v1/map, which Tavily does not.
This page is honest about Tavily-only features fastCRW does not match. The compatibility matrix labels every gap.
Who this is for
- Teams whose product needs search plus scraping — Tavily is search and answer only; fastCRW consolidates search, scrape, crawl, and map on one key.
- Teams sensitive to search latency — fastCRW averaged 880 ms versus Tavily's 2000 ms on a 100-query benchmark.
- Teams that want self-hosting — Tavily is cloud-only; fastCRW is AGPL-3.0 with a bundled SearXNG sidecar.
If you actively use Tavily's include_domains/exclude_domains filtering, country targeting, or the /research agentic endpoint, stay on Tavily — fastCRW does not match those, and this guide says so plainly. (Tavily's include_answer does have an equivalent — fastCRW's answer: true — but it is BYOK; see below.)
Before and after: Tavily search to fastCRW search
A typical Tavily search call:
# Before — Tavily
from tavily import TavilyClient
client = TavilyClient(api_key="tvly-YOUR_KEY")
result = client.search(
"agentic search benchmarks",
max_results=10,
topic="news",
time_range="week",
)
for item in result["results"]:
print(item["title"], item["content"])
The fastCRW equivalent is a POST /v1/search with renamed params:
# After — fastCRW
import requests
response = requests.post(
"https://fastcrw.com/api/v1/search",
headers={"Authorization": "Bearer fcrw_YOUR_KEY"},
json={
"query": "agentic search benchmarks",
"limit": 10, # was max_results
"sources": ["news"], # was topic
"tbs": "qdr:w", # was time_range="week"
},
)
for item in response.json()["data"]:
print(item["title"], item["description"]) # content -> description
Note the response field rename: Tavily's results[].content is data[].description in fastCRW. The Tavily alternative page ships a ~50-line CrwTavilyShim adapter that absorbs these renames so a Tavily-shape call hits fastCRW unchanged.
Parameter mapping table
This table maps Tavily's search surface onto fastCRW and marks every gap honestly. (Endpoint surface verified 2026-05-22; re-verify the live route list before quoting.)
| Tavily endpoint / param | fastCRW equivalent | Migration note |
|---|---|---|
POST /search | POST /v1/search | 1 credit per query. SearXNG-backed. |
max_results (default 5, max 20) | limit (default 5, max 20) | Rename only. |
time_range (day/week/month/year) | tbs (qdr:d/qdr:w/qdr:m/qdr:y) | Semantic match. |
topic (general/news) | sources (["web"]/["news"]) | topic="finance" has no equivalent. |
include_raw_content | scrapeOptions.formats | Shape differs; the adapter wires it through. |
search_depth (basic/advanced) | (no equivalent) | Gap — no depth control. |
include_domains / exclude_domains | (no equivalent) | Gap — no domain filtering. |
country (195+ codes) | (no equivalent) | Gap — no country targeting. |
include_answer (bundled LLM) | answer: true (BYOK) | Supported — but you pass your own LLM key (llmApiKey / llmProvider). |
results[].content | data[].description | Response field renamed. |
results[].score | data[].score | Scale differs; treat as ordinal. |
answer (response) | present when answer: true | Returned only in BYOK answer mode. |
/extract (batched, ≤20 URLs) | /v1/scrape (single URL) | Iterate /v1/scrape or use /v1/crawl for batches. |
/crawl | /v1/crawl | Async → job id; poll GET /v1/crawl/:id. |
/map | /v1/map | URL discovery. 1 credit. |
/research (async + SSE) | (no equivalent) | Tavily-only agentic endpoint. |
MCP tools tavily-search | built-in /mcp (crw_search, crw_scrape, …) | Tool names differ. |
Step-by-step migration
The numbered steps below mirror the howToSteps schema for this page.
1. Inventory your Tavily calls
Grep for Tavily usage. List search, extract, and any /research calls. Flag anything using include_answer, include_domains, exclude_domains, country, or search_depth — those are the gaps that need a decision.
2. Provision a key or self-host
Sign up at fastcrw.com for a fcrw_ key — the Free tier ships 500 one-time lifetime credits that never reset. To self-host, run the AGPL-3.0 stack; it ships a single static Rust binary plus a bundled hardened SearXNG sidecar for the search backend.
3. Point search calls at /v1/search
Change the endpoint from Tavily's POST /search to fastCRW's POST /v1/search. Search costs 1 credit per query.
4. Rename the parameters
Apply the renames: max_results → limit, time_range → tbs (with the qdr: value mapping), topic → sources. include_raw_content becomes scrapeOptions.formats.
5. Drop in the adapter shim
Use the CrwTavilyShim adapter from the Tavily alternative page. It translates a Tavily-shape search() call into the fastCRW body and remaps the response — results[].content ← data[].description — so most call sites stay untouched.
6. Remove or adapt unsupported calls
include_answer maps to answer: true, but it is BYOK — supply llmApiKey and llmProvider, or handle synthesis in your own LLM layer. Drop include_domains/exclude_domains and country, or post-filter results client-side. There is no /research equivalent.
7. Optionally adopt scrape, crawl, and map
This is the migration's payoff. Add /v1/scrape, /v1/crawl, and /v1/map where your product previously needed a second vendor. They share the same API key and credit pool as search.
What does not carry over
Be explicit with your team about these Tavily-only features:
- Answer synthesis is BYOK. Tavily's
include_answeruses a bundled model; fastCRW'sanswer: trueworks but requires your own LLM key (llmApiKey+llmProvider). - No domain filtering.
include_domainsandexclude_domainsare not supported; post-filter client-side. - No
countryparameter and nosearch_depthcontrol. - No
/researchagentic endpoint and no streamed results. - Response field names and error envelopes differ.
results[].content→data[].description;scorescale differs. fastCRW is Tavily-style, not byte-identical. /extractis single-URL via/v1/scrape— Tavily's batched extract (≤20 URLs) is not matched.
Performance and pricing context
On a 100-query benchmark (triple-bench.ts), fastCRW search averaged 880 ms versus Tavily's 2000 ms, with 73 of 100 latency wins and 100% success. Treat this as a point-in-time snapshot on that query set, not a universal guarantee — the methodology is published and the benchmark page documents the run.
On price, fastCRW is credit-based: search 1 credit/query, scrape 1, crawl 1/page, map 1. The Free tier ships 500 one-time lifetime credits that never reset; Hobby is $13/mo launch (3k credits) and Standard $69/mo (100k). The AGPL-3.0 self-host build is $0 in license terms. Launch pricing ends 2026-06-01. For Tavily's current rates, check tavily.com.
Related
Continue exploring
More from Integrations
Claude Code Web Scraping Integration — fastCRW [MCP Server]
Add fastCRW as a Claude Code MCP server. One npx command registers scrape, search, crawl, map, and crawl-status tools. A single static Rust binary, local-first, self-host free under AGPL-3.0.
Migrate from Firecrawl to fastCRW in 10 Minutes — Drop-In Guide
Migrate from Firecrawl to fastCRW with a base-URL swap. fastCRW exposes a Firecrawl-compatible REST API on /scrape, /crawl, /map, /search — keep the firecrawl-py SDK, point it at fastcrw.com, done. Endpoint mapping table + honest divergences.
CrewAI Web Scraping Integration — fastCRW [Firecrawl-Compatible]
Give every CrewAI agent a fastCRW scrape and search tool — via the official crewai-crw package or a hand-rolled BaseTool subclass. A single static Rust binary, local-first, Firecrawl-compatible for low-friction migration.
Related hubs