The CITATION rung of the chain. `explore_data_catalogue`, `run_saved_query` and
`get_signed_sql_drilldown` hand back rows; this says where each number CAME FROM.
Reach for it whenever the user asks "where does that come from", "which filing",
"can you cite that", "how do you know" — and unprompted before you publish a figure
they are going to act on.
TWO WAYS IN, and the FIRST is preferred:
1. `relation` + `keys` — `relation` is a name off the result's
`sources.relations[].relation`; `keys` is one JSON object per row you want
traced. Pass EVERY identifying column the row carries — the reported grain
AND the period/date — e.g. [{"symbol": "SNOW", "cik": "0001273087",
"date": "2026-06-30"}]. Extra columns are ignored; a missing one is fatal.
Grain alone is NOT always enough: the join behind a view can need a column
its `grain` does not list (current_institutional_holders_v reports grain
[symbol, cik] but joins on `date` too, and keys without it resolve nothing).
No token and no SQL, so this is the form
that works when you assembled a table across several calls (`run_saved_query`
issues one call per saved token, so a token only ever describes a fragment of
what you ended up with) or filtered the rows yourself. Trace the rows you will
actually cite — a few dozen — not the whole result set.
2. `encrypted_query_token` — a `trace_token` from a `sources` block, or the
original `query_token` / `signed_query_url`, for the "I have a link and
nothing else" case. The URL form is unwrapped automatically. Tokens are minted
server-side only: never construct, guess or edit one, and never pass SQL here.
THREE CITATION GRAINS come back, finest first. Which one answers depends on the
relation and you do not choose it — one surface over several stacks:
- `citations` carrying `quotes` — the passages an analysis row was actually
WRITTEN from, with quotes machine-verified against the section text. The
strongest evidence in the system; quote these verbatim.
- `citations` of kind `transcript_section` — a link to ONE numbered speaker turn
of an earnings call. `get_document_section` fetches that turn's text.
- `documents` — the whole source document (SEC 13F / Form 4 / 8-K / 10-Q / 10-K,
an earnings-call transcript, an IR PDF) a number was read from. The fallback,
and available wherever lineage reaches a document at all.
`providers` names which of those answered, and every relation's traceability is
derived from the live data model — a redefined view re-derives its own on the next
refresh, so trust this response over anything remembered.
READ `traceable` BEFORE YOU WRITE. "row" means each row maps to one document and
may be cited that way. "cohort" means the number is a sum over a SET of filings:
the response carries `cohort` instead of `documents`, only the set can honestly be
cited, and writing "per this filing, hedge funds own 4.1%" off a cohort row is the
exact failure this field exists to prevent. "none" means the lineage reaches no
document — say the number cannot be sourced rather than reaching for a plausible
filing. A `reason` of "no_keys" means a column the join needs was missing
from every key object — nearly always the period/date — not that the number is
unsourced. Add the date and any other identifying column on the row, and re-call.
`column` traces ONE column instead of the whole row — necessary for a YoY or
change relation, where each value column resolves to a DIFFERENT filing (the
result's `sources.relations[].per_column` says which columns work this way).
`resolve_passages=True` fetches the speaker turn or filing section text instead of
just a link — a link is already a citation. `values` and `prompt` re-aim a
placeholder-twin token but cannot change WHICH documents come back for a given set
of rows.
Requires auth (your MCP client attaches the OAuth bearer automatically). A 403 means
the token is invalid or tampered — re-fetch the link rather than retrying an altered
one; a 422 means neither `relation`+`keys` nor `t` arrived in a usable form.