Introducing OpenWebSearch
copy markdown
OpenWebSearch is a router for web indexes like Google SERP, Exa, Brave, Perplexity and more. The router standardizes both the API inputs and outputs, so that you can easily switch between different providers with centralized billing.
Like LLMs, web indexes are becoming commoditized with different indexes having different strengths and weaknesses with access to niche data, performance and cost. Every large model lab including Interfaze has to build their own internal mini-Google for training and eventually launch that index as a service.
So the bet is we'll start seeing a lot more web indexes as a service in the next few years.
Search is worth more than parameters
DeepMind made this case back in 2022. In this paper, Lazaridou et al. took Gopher models from 44M up to 280B parameters and compared closed-book answering against the same models conditioned on Google Search results.
On Natural Questions and HotpotQA, the 7B model with search beat the 280B model without it. On Natural Questions, so did the 1B.
Conditioning on as few as 5 retrieved paragraphs was enough for the 7B model to pass closed-book Gopher-280B, which the authors summed up as "suggesting that searching the Internet is worth more than 273 billion parameters".
Your first search
- Sign in at openwebsearch.ai
- Create a key and save it
It's a plain REST endpoint that takes and returns JSON, so it drops into any language and wires up as a tool call like any other API.
fetch
const response = await fetch("https://api.openwebsearch.ai/v1/search", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.OPENWEBSEARCH_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
provider: "exa",
query: "What changed in browser automation this week?",
max_results: 5,
}),
});
const { results, provider, usage } = await response.json();
console.log(`${provider} served ${results.length} results for $${usage.cost}`);One response shape
Every successful request returns the same top-level object, whichever index served it.
{
"id": "req-3f0c...",
"provider": "exa",
"query": "browser automation",
"results": [
{
"title": "Browser automation in 2026",
"url": "https://example.com/browser-automation",
"snippet": "A look at what changed across headless browsers this year.",
"content": "Full page content when available.",
"published_date": "2026-08-02",
"source": "example.com",
"raw": {}
}
],
"usage": {
"cost": 0.007,
"results_count": 1
},
"warnings": []
}The result fields are the ones RAG and agent pipelines already expect, so you don't need a per-provider adapter:
| Field | Description |
|---|---|
title | Result title |
url | Canonical result URL |
snippet | Short excerpt or description |
content | Full text when the provider supplies it |
published_date | Provider-supplied publication date, never fabricated |
source | Domain or source name |
raw | The original untouched provider result |
The provider field always names the index that actually served the request, including when a fallback kicked in.
Fallbacks for when an index goes down
Pass an ordered providers list instead of a single provider and the router walks it for you.
{
"query": "latest advances in fusion energy",
"providers": ["exa", "perplexity", "brave"],
"allow_fallbacks": true,
"max_results": 5
}The first successful response wins. It moves to the next index when one returns no results, times out, or has a transient failure, and an invalid request stops immediately instead of burning through your whole list.
Provider-specific options
Not every index supports every filter. GET /v1/providers reports each provider's result cap and whether a given parameter is native, emulated, or unsupported, so you can discover capabilities at runtime instead of hardcoding them.
Unsupported parameters are dropped and reported in warnings by default. Set strict_params: true to get a 400 instead of a silent drop.
When you need a native feature that isn't part of the unified schema, scope it under provider_options:
{
"query": "transformer architecture",
"provider": "exa",
"provider_options": {
"exa": {
"type": "fast",
"contents": { "text": true, "highlights": true }
}
}
}Providers
There's no universally best index. Historical depth, people data, freshness and ranking quality all vary, so the point is to pick per job rather than per integration.
| Provider | Best for | Status |
|---|---|---|
| Parallel | Token-dense excerpts for AI agents | Live |
| Brave | Independent broad-web and media search | Live |
| Exa | People, companies and semantic discovery | Live |
| Perplexity | Citation-backed, real-time answers | Live |
| Valyu | Academic, financial and proprietary data | Live |
| Apify Serp | Localized SERP features and rankings | Live |
| Tavily | Fresh news and agent-ready research | Coming soon |
| Bing | Broad web, local, news and image results | Coming soon |
| Interfaze | Research, social and financial indexes | Coming soon |
| Octen | Real-time and multimodal web search | Coming soon |
More are on the way, and GET /v1/providers is always the source of truth for live slugs, caps and capabilities.
Extracting the full page
While search gives you the right pages, it's not always easy to extract the content of that page in a structured or markdown format.
Depending on the pages like government sites or linkedin profiles, bot checks and other anti-scraping measures, it's difficult to extract the content of that page in a structured or markdown format.
You can use Interfaze to scrape any page as it figures out the best way to extract the content using AI with access to a full browser and proxies built in.
Interfaze SDK
Vercel AI SDK
LangChain SDK
import { Interfaze, responseFormat } from "interfaze";
import { z } from "zod";
const interfaze = new Interfaze();
const ArticleSchema = z.object({
title: z.string(),
author: z.string().optional(),
published_date: z.string().optional(),
key_points: z.array(z.string()),
});
// results[0].url came back from the OpenWebSearch call above
const response = await interfaze.chat.completions.create({
messages: [{ role: "user", content: `Extract the article details from ${results[0].url}` }],
response_format: responseFormat(z.toJSONSchema(ArticleSchema), "article_schema"),
});
console.log(JSON.parse(response.choices[0]?.message.content ?? "{}"));When you want the page itself rather than specific fields, run it as a task instead. The scraper task has a fixed pre-defined output, which makes it faster and cheaper than asking for a custom schema:
Interfaze SDK
const page = await interfaze.tasks.scrape(results[0].url);
console.log("Web Scrape Results:", page);Extraction uses your INTERFAZE_API_KEY, so it's a separate call from the search. Full details are in the web scraping docs.
Billing and usage
Pricing is dynamic because it follows the provider you route to, not a flat platform rate. Most providers bill per request, so a 10-result search costs the same as a 5-result one.
Every response carries its own usage.cost in USD, so spend is attributable request by request rather than reconciled at the end of the month.
The only platform fee is 5% on credit purchases. Top up $100 and you're charged $105, with the full $100 landing in your balance. Nothing is added on top of a search itself, so the cost you see on a response is the cost you pay.
Zero data retention by default
Query text and the results we return are not retained. We keep only the metadata needed to bill and show usage: the request id, the provider that served it, the cost and the latency.
One caveat worth knowing is that whichever provider a request routes to applies its own retention policy to the query it receives. If you need a specific guarantee, check the policies of the indexes you route to and pin your provider list accordingly.
Takeaway
- One index: set
providerand send a normal REST request. - High availability: pass an ordered
providerslist and requests fall through automatically. - Switching: change one request field instead of rewriting an integration.
- Native features: reach them through
provider_optionsand read them back underraw. - Billing: one prepaid balance across every provider, with
usage.coston every response.
Web indexes will keep multiplying, so the integration you write today should outlive whichever one currently wins.
- Get an API key
- Read the OpenWebSearch docs
- Using Interfaze directly? Web search is built into the model
- Join the Discord