Browse documentation
Grounding: one call, an evidence set with a receipt
Give ground an objective and a budget; get back evidence with provenance, and a receipt that says whether it is enough.
What it is
ground is the call to start with. Search retrieves passages; ground says what the
retrieved evidence is — who originally published it, who republished it, what kind of
source each item is, whether two items are actually independent, how fresh the set is —
and whether it is enough to act on. No generated answer comes back. The evidence and its
structure do, and the reasoning is yours, with whichever model you use.
curl -sG -H "x-api-key: $UNLOB_API_KEY" https://api.unlob.com/ground \
--data-urlencode 'objective=what changed in the UK AI regulation position this week' \
-d max_age=7d -d min_independent_origins=2 -d token_budget=3000
A call costs 5 credits, however many stories it expands on the server, and a call that runs and fails costs 1. See Pricing.
The request
| Parameter | Meaning |
|---|---|
objective | What you need evidence for — a question, a task, or a claim to check. q is accepted as an alias. |
token_budget | Ceiling on the evidence returned, in estimated tokens. Default 3000. |
max_age | The freshness contract: seconds, or 30m, 6h, 7d, 2w. |
min_independent_origins | Origins with distinct owners required for sufficient. Default 2. |
require_role | Roles of which at least one must be present for sufficient. Default primary,official; an empty string means no requirement. |
latency_budget_ms | Bound on the time spent expanding stories into their members. |
claim | Experimental: relate each item to this claim. See Provenance. |
strip_instruction_like | Remove instruction-like sentences from snippets instead of only flagging them. See Untrusted content. |
mode, vertical, lang, safe | The same meanings as on /search. |
The response
{
"status": "sufficient",
"objective": "…",
"evidence": [
{
"hit": { "id": "…", "url": "…", "host": "reuters.com", "snippet": "…" },
"reason": "wire · 2 origins in this story · secondary source · owner: Thomson Reuters",
"source_role": "secondary",
"origin_type": "wire",
"origin": "o:3f2a9c1e4b7d",
"owner": "Thomson Reuters",
"independence_score": 1.0,
"age_secs": 2220,
"risk_flags": []
}
],
"origins": [ … ],
"coverage": { "complete": true, "independent_origins": 2, "known_gaps": [] },
"budget": { "token_budget": 3000, "context_tokens": 1420, "credits_billed": 5 },
"next_actions": [],
"provenance": { "method": "deterministic", "generated_at": 1757800000 }
}
Each evidence item is the representative passage of one origin. Republishes never
appear as evidence; they are listed under the origin they copy. What each field means is
on Provenance and independence; what coverage reports is on
Coverage receipts.
Read status first
status | Meaning | Do |
|---|---|---|
sufficient | At least min_independent_origins origins with distinct owners, and a source in require_role present | Read evidence and act |
insufficient | Evidence exists but does not meet the bar | Follow next_actions, or say the evidence is thin |
stale | Nothing inside max_age; stale_evidence shows what older material exists | Widen max_age, or report that nothing recent was found |
partial | Part of the index was unreachable | Retry; never treat the answer as complete |
empty | Nothing found | Reformulate, or ask why_not before asserting absence |
The status is computed by a fixed rule, in this order: partial if any part of the index
failed to answer; empty if no evidence came back; stale if a window was set and nothing
inside it was found; sufficient if the origin count and the role requirement are met;
insufficient otherwise. No model is involved anywhere in the call, so the same corpus
and the same request give the same status.
next_actions
When the set is not sufficient, next_actions says what would change that, as things you
can do with this API: retry on a partial answer, widen_max_age with a suggested value,
corroborate a specific item, a search with a filter hint (an authority or content-type
filter when a required role is missing), why_not before concluding absence, or
get_document when a snippet was truncated. They are suggestions in a fixed vocabulary,
not instructions from the corpus.
Budgets
token_budget is honoured as a ceiling on the evidence returned; budget.context_tokens
reports what was packed, estimated from the snippets and titles. latency_budget_ms
bounds the per-story lookups: when it cuts in, coverage.not_searched.story_expansion_truncated
is true and the unexpanded stories still contribute their best passage, just without
corroboration.
When to use it
ground— “what should I know, and can I trust it”: evidence with provenance and a verdict on sufficiency.search— “find me the page that says Y”: ranked passages with filters, and the cheapest call.assemble_context— a budget-packed reading set ranked by corroboration, without provenance or a receipt.
Over MCP, ?profile=grounding lists only ground and get_document — see
Profiles.
Next
- Coverage receipts — every field of
coverage. - Provenance and independence — roles, origins, owners.
- Freshness —
max_ageandstale. groundreference — arguments and the full return schema.