Browse documentation
Evidence with provenance and a coverage receipt
Get the smallest defensible evidence set for an objective, with provenance and a coverage receipt — the call to start with.
/ground Request
curl \
-H "x-api-key: $UNLOB_API_KEY" \
"https://api.unlob.com/ground?objective=<objective>" Behaviour
Runs retrieval, story deduplication, origin clustering and ranking on the server and returns evidence items rather than links: each says who originally published it (origin_type), who republished it, what kind of source it is (source_role), who owns it, and whether it is independent of the others. `coverage` says what was searched, what was not, how fresh the set is and which source classes are missing; `independent_origins` counts origins with distinct owners, so seventeen copies of one wire story are one origin.
Read `status` first. sufficient: enough independent origins and a primary or official source. insufficient: evidence exists but does not meet the bar — `next_actions` says what would. stale: nothing inside max_age; `stale_evidence` shows what older material exists. partial: part of the index was unreachable — never treat the answer as complete. empty: nothing found.
No generated answer is returned: the evidence and its structure are, and the reasoning is yours.
Costs 5 credits; a call that runs and fails costs 1.
Parameters
| Name | Type | Description |
|---|---|---|
objectiverequired | string | What you need evidence for — a question, a task, or a claim to check. `q` is accepted as an alias. |
token_budget | integer | Ceiling on the evidence returned, in estimated tokens. Default 3000. |
max_age | string | Freshness contract: seconds, or 30m / 6h / 7d / 2w. Older evidence is reported as `stale_evidence`, never substituted silently. |
min_independent_origins | integer | Origins with distinct owners required for status=sufficient. Default 2. |
latency_budget_ms | integer | Bound on the time spent expanding stories; when it cuts in, `coverage.not_searched.story_expansion_truncated` is true. |
require_role | string | Comma list of roles of which at least one must be present for sufficient. Default `primary,official`; empty means no requirement. |
claim | string | Experimental: relate each item to this claim as supports / contradicts / qualifies / unresolved. Heuristic; no model. |
mode | string | keyword | semantic | hybrid (default). |
vertical | string | Restrict to one vertical; the receipt lists the others as not searched. |
lang | string | Single language code. |
safe | boolean | true (default) drops explicit content. |
strip_instruction_like | boolean | Remove instruction-like sentences from snippets instead of only flagging them. |
Responses
| Status | Meaning |
|---|---|
200 | The evidence set, its origins, the coverage receipt, the budget spent, and what to do next. Read `status` first. |
400 | A duration that does not parse. |
401 | Missing, unknown or revoked key. A key minted moments ago can answer 401 until it propagates to the serving fleet. |
429 | Over the per-minute rate (spent in credits), or a hard-capped key without the credits this call costs. `retry-after` is present on the rate-limit case only. |
Response body
GroundResponse
| Name | Type | Description |
|---|---|---|
budgetrequired | object | — |
contradictions | string[] | Ids of evidence items whose claim_relation is contradicts |
coveragerequired | object | The coverage receipt |
evidencerequired | object[] | — |
next_actionsrequired | object[] | — |
objectiverequired | string | — |
originsrequired | object[] | — |
provenancerequired | object | — |
stale_evidence | object[] | Only when max_age was set and nothing inside it was found |
statusrequired | "sufficient" | "insufficient" | "stale" | "partial" | "empty" | — |
The same call over MCP
This capability is ground on the
MCP server, taking the same parameters and returning the same body. A parity test
in the API fails the build if the two ever diverge, so you can read either
reference and use the other.
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "ground",
"arguments": {
"objective": "<objective>"
}
}
} Most clients build that frame for you — see Connect a client.
See Errors for what to do with each status, and Retries and backoff for which are worth repeating.
FAQ
- What does 200 mean on GET /ground?
- The evidence set, its origins, the coverage receipt, the budget spent, and what to do next. Read `status` first.
- What does 400 mean on GET /ground?
- A duration that does not parse.
- What does 401 mean on GET /ground?
- Missing, unknown or revoked key. A key minted moments ago can answer 401 until it propagates to the serving fleet.
- What does 429 mean on GET /ground?
- Over the per-minute rate (spent in credits), or a hard-capped key without the credits this call costs. `retry-after` is present on the rate-limit case only.