Fit a result set into a token budget
Use fields[] to drop everything the agent will not read and limit to cap the set, or let assemble_context pack to a budget for you.
The problem
Retrieval quietly dominates an agent's token bill. Ten full results with every field is a few thousand tokens before the model has reasoned about anything, and most of those tokens are fields the agent never looks at.
What to send
fields[]url, title, snippet
Return only what the agent reads. The single largest saving available.
limit5
Precision beats recall when every extra result is billed.
budget4000
On /assemble_context — pack to a token budget directly instead of trimming afterwards.
- System prompt and tools1,8006%
- Retrieved context, packed to budget4,00013%
- Conversation so far3,20010%
- Left for reasoning23,00072%
The code
curl -H "x-api-key: ulb_..." \
"https://api.unlob.com/search?q=rust+async&fields[]=url&fields[]=title&fields[]=snippet&limit=5"import httpx
# assemble_context does the selection, deduplication and packing in one
# call, to an explicit token budget.
pack = httpx.get(
"https://api.unlob.com/assemble_context",
headers={"x-api-key": "ulb_..."},
params={"query": "post-quantum cryptography migration", "budget": 4000},
).json()
print(pack["used_tokens"], "of", pack["budget"])
for p in pack["passages"]:
print(p["url"], p["reason"]) # why each passage earned its placeThe mistake to avoid
Requesting `limit=20` and truncating client-side. You are billed for the tokens either way — trimming after the fact saves the model's attention but not your bill, and it discards the API's ranking in favour of an arbitrary cut.
Frequently asked questions
Does search ever return the page body?
No. Search returns metadata only — url, host, title, snippet, score and signals — and full text comes from a separate `/doc` call for the one result the agent chose. That separation is the main reason a search here costs an agent a few hundred tokens rather than tens of thousands.
How do I know how many tokens a result set will cost?
Count them. `/assemble_context` reports `used_tokens` against the budget you set, which is the honest number; for a plain search, the payload is small and predictable once you have pinned `fields[]` and `limit`.
Try it against your own queries
10,000 requests a month on the free tier, no card. Enough to run a real evaluation set rather than a demo.