unlob Docs
Browse documentation

web_search

Search the agent-first web index. Returns metadata-only hits (url, host, snippet, score, trust and graph signals) — never the page body; fetch that with get_document when a snippet is not enough.

Behaviour

The query supports boolean operators: AND, OR, -term to exclude, and "exact phrase". Name a vertical to disambiguate, or omit it and the router picks one from the query.

The index is admission-controlled, so a small result set usually means the index holds little on the topic, not that the query was wrong. One exception: if `partial` comes back true, part of the corpus was unreachable and the answer really is incomplete.

Every filter below is also a query parameter on GET /search, with the same name and the same meaning. IN-list filters accept either an array or a comma-separated string.

Arguments

inputSchema

NameTypeDescription
authorityarray | stringPublisher-authority IN-list
collapse"none" | "host" | "page" | "story"Group results: one per host, per page, or per story (near-dup cluster). collapse=story is how you stop reading the same wire copy five times.
communityarray | stringGraph signal: restrict to these graph communities
content_typearray | stringIN-list: article, news, docs, reference, qa, forum, academic, product, code, how-to, opinion, video, document
exclude_sitearray | stringHosts to exclude
facetsbooleanAlso return host/vertical/source/content-type facet counts and a publish-year histogram
fieldsarray | stringProject the hit down to these fields, to save context
fromintegerOnly results fetched at/after this unix-second timestamp
langstringSingle language code, e.g. en
langsarray | stringLanguage IN-list
limitinteger0 returns only the match count
max_wordsintegerPassage length ceiling
min_centralitynumberGraph signal: only passages this central to the corpus
min_host_ranknumberTrust floor (0..1)
min_independent_sourcesintegerGraph signal: only stories asserted by at least this many distinct hosts. The corroboration filter.
min_qualityintegerQuality floor
min_wordsintegerPassage length floor
mode"keyword" | "semantic" | "hybrid"
prefer_authoritybooleanSoft rerank bias toward higher-authority hosts
prefer_recentbooleanSoft rerank bias toward newer passages — a nudge, not a filter
published_fromintegerContent publish date at/after this unix-second timestamp (not crawl time)
published_tointegerContent publish date at/before this
queryrequiredstringBoolean-capable: rust AND async, -python, "exact phrase"
safebooleantrue (the default) drops explicit content; false allows everything
sitestringRestrict to an exact host, e.g. docs.rs
sort"relevance" | "recency" | "host_rank" | "quality" | "published" | "words" | "centrality"
source"cc" | "delta"cc = Common Crawl, delta = freshly crawled
termstringExact-needle: only passages carrying this salient term, e.g. CVE-2024-3094. Use it for identifiers an embedder is blind to.
tldarray | stringTop-level-domain IN-list, e.g. edu, gov
tointegerOnly results fetched at/before this unix-second timestamp
topicarray | stringTopic-tag IN-list
verticalstringe.g. code, cooking, science. Omit to auto-route.

Returns

A JSON payload in the text content block, and the same payload as structuredContent for clients that support it.

outputSchema

NameTypeDescription
facetsobjectPresent only when facets=true
moderequired"keyword" | "semantic" | "hybrid"The mode actually used
partialbooleantrue when at least one shard failed or timed out — the answer is short because a slice of the corpus was unreachable, NOT because that is all there is. Never treat a partial result as complete.
resultsrequiredobject[]
routedrequiredbooleantrue when the router chose the vertical, false when you named it
totalrequiredinteger
verticalstring | nullThe vertical actually queried

Calling it

Over Streamable HTTP, with the required arguments filled in:

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "web_search",
    "arguments": {
      "query": "<query>"
    }
  }
}

Most clients do this for you — see Connect a client. To drive it by hand, complete the startup lifecycle first.