The official TypeScript/JavaScript client for SERPdive, the AI Search API: ask a question, get answer-ready web content that is extracted, cleaned, and sized for an LLM. On a public, replayable 1,000-question benchmark, SERPdive runs at the same speed as Tavily, feeds your LLM 20.2% fewer tokens, and wins 60.7% of decided quality duels. If you are evaluating Tavily alternatives, that benchmark is public and replayable end to end: same questions, same judge, your machine.
There is a free tier, and it has no ceiling. The krill model is free and unlimited under fair use — no card, no credits, nothing to decrement. It returns the shortest set of sentences that still answers (about 700 tokens a search, roughly half what the usual alternatives send), one request at a time, at low priority. Use it to build; switch one word to mako when you need depth and steady latency.
Zero dependencies. Works in Node 18+, Bun, Deno, and edge runtimes (anywhere fetch exists). Full TypeScript types included.
npm install serpdiveimport { SerpDive } from "serpdive";
const client = new SerpDive({ apiKey: "sd_live_..." }); // or set SERPDIVE_API_KEY
const response = await client.search("who won the 2026 champions league final", {
answer: true,
});
console.log(response.answer);
for (const result of response.results) {
console.log(result.url, result.content.slice(0, 100));
}Get your API key at serpdive.com/dashboard/keys.
// mako (default): answers in a few seconds
await client.search("best rust web frameworks");
// krill: free and unlimited (fair use) — the smallest useful payload
await client.search("who is the ceo of vercel", { model: "krill" });
// moby: reads whole pages, for deep research
await client.search("timeline of the OpenAI board dispute", { model: "moby", answer: true });| model | cost | payload | notes |
|---|---|---|---|
krill |
free, unlimited (fair use) | ~700 tokens | one request at a time, low priority, no answer |
mako |
1 credit | ~1k tokens | the default; best for agents and RAG |
moby |
1.5 credits | up to ~15k tokens | whole page content, cited answer |
await client.search("your question", {
model: "moby", // "mako" (default), "krill" (free, unlimited), "moby" (whole pages)
answer: true, // also return a written answer built from the sources (not on krill)
maxResults: 5, // hard cap on delivered results, 1 to 10
});Localization is automatic: the language of the query picks where we search. There is no country parameter to configure.
Every API error is a typed exception with a stable code, the human message, and the HTTP statusCode:
import { SerpDive, RateLimitError, QuotaExceededError, SerpDiveError } from "serpdive";
try {
const response = await client.search("your question");
} catch (err) {
if (err instanceof RateLimitError) {
// slow down, then retry
} else if (err instanceof QuotaExceededError) {
// monthly credits exhausted
} else if (err instanceof SerpDiveError) {
console.error(err.code, err.message);
}
}Transient failures (HTTP 502/503) are retried automatically; failed searches are never billed. Tune with new SerpDive({ maxRetries, timeoutMs }).
search() resolves to a SearchResponse:
| Field | Type | Notes |
|---|---|---|
query |
string |
your query, echoed |
results |
SearchResult[] |
each has url, content, title, optional ISO date |
answer |
string | null |
only when answer: true was requested |
extra_info |
ExtraInfo |
direct-answer block (weather, rates, scores...) when the query has one |
model |
string |
which model answered |
response_time_ms |
number |
end-to-end latency |
Full documentation: serpdive.com/docs. The API is also self-describing for agents: llms.txt, openapi.json.
MIT