unlob for OpenAI Agents SDK
The built-in web search tool is convenient and opaque. A function tool costs a few lines and gives you filters, corroboration thresholds and portability across models.
import os, requests
from agents import function_tool
BASE = "https://api.unlob.com"
HEADERS = {"x-api-key": os.environ["UNLOB_API_KEY"]}
@function_tool
def web_search(query: str, limit: int = 8) -> list[dict]:
"""Search the web. Metadata-only hits with corroboration counts."""
r = requests.get(f"{BASE}/search", headers=HEADERS, timeout=10,
params={"q": query, "limit": limit, "collapse": "story",
"min_independent_sources": 2})
r.raise_for_status()
return r.json()["results"]
@function_tool
def why_not(url: str) -> dict:
"""Explain whether a URL is in the index, was removed, or was never seen."""
r = requests.get(f"{BASE}/why_not", headers=HEADERS,
params={"url": url}, timeout=10)
r.raise_for_status()
return r.json()Setup
Get an API key
10,000 free requests a month.
Define the tools
Search, and — worth including — why_not, so the agent can distinguish "not indexed" from "does not exist".
Set the defaults yourself
Pin collapse and corroboration thresholds in the function rather than in the schema.
Register with your agent
Pass the tools when constructing the agent as usual.
Worth knowing
- Including why_not measurably reduces confident wrong answers about absence — it converts an ambiguous empty result into a stated fact.
- Function tools keep retrieval portable. The built-in web tool does not survive a move to another model.
Frequently asked questions
Why not use the built-in web search tool?
It works, and it gives you no filters, no corroboration signal, no visibility into exclusions and no portability. For anything where retrieval quality determines output quality, that is a lot to give up.
Get a key and connect it
10,000 requests a month, no card. The config above works unchanged once you have a key.