Search versus research
What a search API gives your model, what it leaves for your model to do, and which of those steps /research handles inside the call.
Search is access to the web. Research is the work that comes after it.
If you are wiring web access into your own model, this is the distinction that decides how much code you own. This page maps the steps involved, says which ones a search API covers, and shows the same job done both ways.
The loop behind a current answer
Section titled “The loop behind a current answer”Answering a question from the live web takes more than one step:
| Step | Search API | Fetch tool | /research |
|---|---|---|---|
| Work out what to search for | No | No | Yes |
| Run the search | Yes | No | Yes |
| Choose which results are worth reading | Sometimes | No | Yes |
| Fetch and render the pages | Sometimes | Yes | Yes |
| Recover readable content from the markup | Sometimes | Yes | Yes |
| Judge relevance and reliability | No | No | Yes |
| Notice what is still missing | No | No | Yes |
| Search again to close the gap | No | No | Yes |
| Reconcile sources that disagree | No | No | Yes |
| Synthesize the answer | No | No | Yes |
| Attach sources to the claims they support | No | No | Yes |
Search APIs differ. Some return bare links, some return snippets, some return extracted page content, and some offer an answer endpoint of their own. Either way, the steps marked No above land on your model and the code around it.
Why that matters more when you run your own model
Section titled “Why that matters more when you run your own model”Nothing here is impossible with a search tool and a fetch tool. It is a question of who pays for the orchestration.
- Tool calling. The loop needs a model that calls tools reliably, several times, in the right order. Model quality on that axis varies a lot more once you are choosing your own model.
- Context. Raw page content fills the window fast. Reading five pages to answer one question can cost more context than the answer is worth.
- Latency and tokens. Every step in the loop is another round trip through your model.
- Silent failure. A fetch that returns a cookie banner, a source that was never read, a citation that points at a page which does not contain the claim. These do not raise errors. They lower answer quality.
- Maintenance. Pages change, models change, frameworks change, and the loop is yours to keep working.
You chose your own model to control the model layer. The web layer is a separate decision.
The same job, both ways
Section titled “The same job, both ways”With search and fetch tools
Section titled “With search and fetch tools”Your model drives. Roughly, your code looks like this:
// You own every line of this, plus the prompt that makes the model use it well.let notes = [];
for (let round = 0; round < MAX_ROUNDS; round++) { const queries = await model.plan(question, notes); // step 1 const results = await search(queries); // step 2 const chosen = await model.rank(results); // step 3 const pages = await Promise.all(chosen.map(fetchAndClean)); // steps 4 and 5 notes = await model.assess(question, notes, pages); // steps 6 and 7
if (await model.isComplete(question, notes)) break; // step 8}
const answer = await model.synthesize(question, notes); // steps 9 and 10const cited = await model.attachSources(answer, notes); // step 11Every call there is a place to tune, a place to spend tokens, and a place to fail.
With /research
Section titled “With /research”import Tabstack from "@tabstack/sdk";
const client = new Tabstack();
const stream = await client.agent.research({ query: "What are the main approaches to browser automation for AI agents?", mode: "fast",});
for await (const event of stream) { if (event.event === "complete") { console.log(event.data.report); // the answer console.log(event.data.metadata.citedPages); // the sources it cited }}from tabstack import Tabstack
client = Tabstack()
for event in client.agent.research( query="What are the main approaches to browser automation for AI agents?", mode="fast",): if event.event == "complete": print(event.data.report) # the answer print(event.data.metadata.cited_pages) # the sources it citedtabstack agent research "What are the main approaches to browser automation for AI agents?" --mode fastThe complete event carries the finished result:
{ "report": "There are three main approaches...", "metadata": { "totalPagesAnalyzed": 9, "citedPages": [ { "url": "https://example.com/browser-automation", "title": "Browser Automation Approaches", "claims": [] } ] }}Your model never sees a search result, a URL, or a page of markup. It gets the report. The progress events stream while the loop runs, so you can show the work without running it. See the Research guide for the full event list.
When a search API is the right choice
Section titled “When a search API is the right choice”Use search, not research, when:
- You want the links themselves, for example to show a result list to a person.
- Your model genuinely does need the raw material, because the reasoning over it is the product.
- You are answering from one known source and can skip discovery entirely. Use
/extract/markdownfor that instead. - Cost per call matters more than steps saved. A
/researchcall runs several actions and bills for each. See Pricing.
When building the loop yourself is the right choice
Section titled “When building the loop yourself is the right choice”Build it when the loop is the product. If your differentiation is how you select sources, weight them, or reconcile them, that logic belongs in your codebase, not behind an API. Tabstack is the better trade when the result is what matters and the loop is plumbing.
Next steps
Section titled “Next steps”- Quickstart: API key to first cited answer.
- Research guide: modes, events, timeouts, and failure handling.
- Comparisons: how Tabstack differs from specific products.
- API Reference:
/research.