Skip to main content
Tavily

Tavily's /search + /extract API → the Naive search primitive

Tavily is a trademark of its respective owner, used here for identification and migration comparison only. No endorsement, partnership, or affiliation is implied.
Tavily is a web search and content-extraction API built for LLM agents: search returns ranked, snippet-rich results; extract pulls clean content from URLs; crawl and map traverse whole sites. It does agent-grade retrieval well — a purpose-built ranker, an LLM-friendly response shape, and a generous free tier. But when the thing doing the searching is an agent that also holds cards, an inbox, a phone number, and a KYC’d identity, a Tavily account is a disconnected vendor account:
  • Retrieval lives behind a Tavily API key (tvly-...) — a credential that exists only inside Tavily, unrelated to where the same agent’s cards, email, and KYC live.
  • Whether the agent may search, and how much it may spend doing so, is not something Tavily governs at execution time — it is a key you hold. There is no “can this agent research right now?” check tied to the agent’s broader permission set.
  • “Which agent ran this query, for which end-user, and who let it?” is answered in Tavily’s usage dashboard for search, and in unrelated systems for the agent’s spend, comms, and identity.
Naive’s search primitive gives the agent the same capability — web_search, read_url, and research — but it is one primitive on one governed account. And it is honest to say the results are the same: Naive’s search is Tavily-backed under the hood (with a Brave fallback), so web_search proxies Tavily Search and read_url proxies Tavily Extract. You keep Tavily-quality retrieval and gain:
  • The Account Kit that decides whether the agent may issue a card or send email also decides whether it may use search at all — checked at execution time, not in a separate dashboard.
  • Search spend is metered in the same credit balance and budget ceiling as every other primitive, so a runaway agent hits one cap, not a separate Tavily bill.
  • Every query records the acting agent and lands in the same activity log as its card spend, email sends, and KYC events.
This guide maps Tavily’s retrieval API to Naive’s, shows the smallest working swap, and is explicit about what does not map yet — most importantly, that Naive’s search exposes a much smaller set of knobs than Tavily (no crawl/map, no per-request search_depth/topic/domain filters), and that search is workspace-scoped, not per-end-user isolated.
Tested against: the Tavily JavaScript SDK @tavily/core v0.7.6 (against the Tavily REST API, base https://api.tavily.com, /search and /extract endpoints, docs snapshot July 2026), and the Naive search primitive over the Naive REST API (base https://api.usenaive.ai/v1, /search, /search/url, /search/research endpoints, docs snapshot July 2026). The Naive @usenaive-sdk/server SDK does not ship a dedicated search sub-client yet — call search over REST (shown below) or via the naive search CLI.Version notes:
  • Auth model differs. Tavily authenticates with an account-wide bearer key (tvly-...). Naive authenticates per workspace with NAIVE_API_KEY, and you scope an end-user with naive.forUser(id) / POST /v1/users/:id/search — the same handle that reaches every other primitive.
  • Same provider under the hood. Naive web_search calls Tavily /search; Naive read_url calls Tavily /extract. If Naive is configured with Brave instead, results come from Brave — you don’t choose the provider, and you can’t pass your own Tavily plan/key. See what doesn’t map yet.
  • Smaller parameter surface. Naive web_search takes query + count (1–20). Tavily’s search_depth, topic, time_range, include_domains/exclude_domains, country, include_answer, include_raw_content, and exact_match have no pass-through today.
  • Naive adds research. POST /v1/search/research does multi-step search + synthesis with citations (a synchronous quick mode and async thorough/exhaustive jobs). On Tavily you’d compose search with your own LLM (or use include_answer for a one-line answer).

Concept map

Before / after: the core path

The path that matters for almost every agent is search the web, then read the best result — the classic grounding / RAG loop. Here it is on both platforms.
The search/read shape lines up closely. The real differences to plan for:
  • maxResultscount. Both cap at 20; Naive defaults to 5.
  • Result field rename. Tavily’s per-result content snippet becomes snippet on Naive; Naive’s response is { title, url, snippet } and does not include score or rawContent.
  • extract reads one URL. Tavily’s extract accepts up to 20 URLs per call; Naive’s read_url takes a single url (loop if you have several), plus an optional extract focus prompt that returns an AI-narrowed extracted field.
  • Synthesis is a separate call. Where you’d set Tavily include_answer: true, call Naive POST /v1/search/research for a cited, multi-source answer (see below).

The synthesis path

If you were leaning on Tavily’s include_answer (or wiring search results into your own LLM), Naive’s research tool does the multi-step version natively:

Minimal viable migration

The smallest swap that keeps a working agent running is search + read (and optionally research).
1

Set your key

Use your existing NAIVE_API_KEY (a server-side key from the dashboard). No separate search vendor account or tvly-... key to provision.
2

Swap the search call

Map tvly.search(query, { maxResults })POST /v1/search { query, count }. Read results from results[].snippet instead of results[].content. Drop Tavily-only options (search_depth, topic, include_domains, …) — they have no pass-through yet (gaps).
3

Swap the extract call

Map tvly.extract([url])POST /v1/search/url { url }, reading content (Tavily’s rawContent). One URL per call — loop for several. Add an extract focus prompt to get an AI-narrowed extracted field.
4

Swap synthesis (optional)

Replace include_answer / your own LLM-over-results with POST /v1/search/research { query, depth }. Use quick for an inline { summary, sources }; use thorough/exhaustive for a 202 { job_id } you poll at GET /v1/jobs/:id.
5

Reach for the CLI where handy

The same primitive is on the CLI: naive search "...", naive search url <url> --extract "...", and naive search research "..." --depth thorough --wait.
6

Ship it

At this point the agent’s research path is off Tavily’s direct API and onto Naive — same provider-backed results, one key. Everything below is upside, not a requirement.

Consolidate further once you’re on Naive

This is where the migration pays for itself. On Tavily, search is a self-contained account: an API key, its own credit pool, and its own dashboard — disconnected from the agent’s money, comms, and identity. On Naive, search is one primitive on the same account and Account Kit that governs the agent’s cards, email, phone, and vault.

Gain #1 — one account across primitives

  • With Tavily, search is an island behind its own key and credit pool. With Naive, naive.forUser(acme.id) is a single handle to search and cards and email and phone and KYC — no second vendor account, no tvly-... key to provision and rotate, no separate invoice.
  • Third-party connections (OAuth grants like Slack or Notion) and the agent’s native primitives sit under one identity and one Account Kit — the SaaS the agent connected and the web it searches, governed the same way.

Gain #2 — execution-time permission enforcement

  • Whether an agent may search at all is the search primitive on the user’s Account Kit, decided at execution time — not a key you gate separately from everything else the agent can do.
  • The agent’s code path stays the same for every tier — the same POST /v1/search. Whether it runs is decided by policy: a user whose Account Kit does not enable search is refused with forbidden (primitive_disabled_by_kit), with no code change on your side.
  • Each web_search spends 0.2 credits (read_url 0.05, research 0.5–1.6) against the same budget ceiling as the agent’s cards, phone, and LLM calls — so a misbehaving agent trips one combined cap, not a separate Tavily limit you monitor on its own.
The search primitive is gated by the Account Kit toggle and the budget, but it is not frozen for human approval by default — unlike money-moving primitives (cards, trading, domains). And it is company-scoped: the kit gates whether a user’s agent may search, but search itself doesn’t hold per-end-user data to isolate. See what doesn’t map yet.

Gain #3 — unified accountability

  • Every query records the acting agent and lands in one per-user activity log — alongside that customer’s card spend, email sends, and KYC events, not in a separate Tavily usage dashboard:
  • That is the question that is hard to answer when queries live in Tavily, cards live in Stripe, and the inbox lives somewhere else. Under Naive it is a single query.

What does not map yet

A migration guide that hides gaps is worse than none. The core path (search → read → synthesize) maps cleanly, but the following Tavily capabilities have no direct equivalent on Naive’s search primitive today. Check this list against your app before you commit.
The biggest thing to weigh is parameter surface, not the core loop. Tavily exposes a rich request API — search_depth, topic, time and domain filters, crawl, map, Hybrid RAG. Naive’s search primitive deliberately keeps a small surface (query + count for search, a single url for read, depth for research) and picks the provider for you. If your agent relies on Tavily’s crawl/map, domain/time filtering, or plan-level control over the search backend, those are the gaps most likely to matter — keep Tavily for that surface, or wait until Naive exposes more knobs. If you just need solid grounding — search, read, synthesize — the swap is clean, and the results are Tavily’s either way.

Where to go next

  • search primitive — full web_search / read_url / research reference, depth levels, and the choose-the-right-tool guide
  • search CLInaive search, naive search url, naive search research
  • Account Kits — enabling/disabling the search primitive per user at execution time
  • Tenant users — the identity that owns search, cards, email, and phone
  • Billing — the shared credit balance and budget ceiling search spends against
  • Logs — the unified per-user activity trail every query lands in