Citations
Every 2xx response from Blockchain Academics carries attribution.citations: an array, always, even when there is only one source.
"attribution": {
"citations": [
{
"cite_url": "https://blockchainacademics.com/article/bitcoin-price-history?src=claude",
"as_of": "2026-04-22T10:12:00Z",
"source_hash": "sha256:abc123..."
}
]
}This page explains why the array is a contract, not a convenience, and what it unlocks as the corpus grows.
Why array, not singleton?
The envelope committee debated three shapes. We locked array-only on 2026-04-22 because the other two create drift the day multi-source ships.
Rejected: singleton at root
// NOT the shape. Would force a breaking change later.
{ "data": {...}, "cite_url": "...", "as_of": "...", "source_hash": "..." }Rejected: singleton with a convenience shortcut
// NOT the shape. Two sources of truth = eventual drift.
{
"data": {...},
"attribution": {
"cite_url": "...", // shortcut for citations[0].cite_url
"citations": [ {...}, {...} ]
}
}Locked: array-only
{
"data": {...},
"attribution": { "citations": [ {...} ] }
}The winning argument: client code that reads citations[0].cite_url today keeps working unchanged when citations[1], citations[2], … get populated. A cite_url shortcut at the root would have forced every client to re-read the spec on the day multi-source shipped. We paid the small cost of [0] indexing up front in exchange for zero breakage later.
What citations[0] means today
For every response, citations[0] is the primary source: the page the payload was derived from. Since 0.4.0 that is the upstream page when a third party supplied the data, and the Blockchain Academics page otherwise:
- Tools built on our own corpus and products (
get_article,get_entity,get_explainer, the indicators, memos, theses and curated directories) cite the specific article, entity, explainer or dashboard page onblockchainacademics.com. One citation. - Tools that read a third-party upstream (
get_priceandget_ohlcfrom CoinGecko,get_txfrom the chain explorers,track_sec_filingsfrom the SEC,get_fear_greedfrom alternative.me, and so on) put that upstream page first, with its ownas_ofandsource_hash, and the Blockchain Academics editorial deep link second atcitations[1]. Two citations, the same count on every call. - On list endpoints (
search_news,list_stablecoins,get_trending) the Blockchain Academics citation points at the index page for that query (the search page with the query preserved, or/stablecoins).
What multi-source unlocks
The upstream citation shipped first. The same array can carry more entries wherever corroboration matters; three examples, the first partly live today:
1. Market data from multiple oracles
When a price is reconciled across several oracles, every oracle is listed:
"attribution": {
"citations": [
{ "cite_url": "https://blockchainacademics.com/market/btc?src=claude", "as_of": "2026-04-22T10:12:00Z", "source_hash": "sha256:primary..." },
{ "cite_url": "https://blockchainacademics.com/oracles/chainlink/btc-usd", "as_of": "2026-04-22T10:11:58Z", "source_hash": "sha256:chainlink..." },
{ "cite_url": "https://blockchainacademics.com/oracles/pyth/btc-usd", "as_of": "2026-04-22T10:11:59Z", "source_hash": "sha256:pyth..." }
]
}citations[0] remains the primary source (what the agent should cite to the end user). citations[1..] are the corroborating entries: auditable, but generally not surfaced in the agent's answer beyond the Blockchain Academics link.
2. News cross-referenced across outlets
Once the same event is covered by multiple publishers that BCA ingests, search_news can annotate articles with their corroborating outlets:
"attribution": {
"citations": [
{ "cite_url": "https://blockchainacademics.com/article/circle-mica-license?src=claude", "as_of": "2026-04-21T09:31:22Z", "source_hash": "sha256:bca..." },
{ "cite_url": "https://blockchainacademics.com/article/circle-mica-license/sources/the-block", "as_of": "2026-04-21T08:14:00Z", "source_hash": "sha256:tb..." },
{ "cite_url": "https://blockchainacademics.com/article/circle-mica-license/sources/coindesk", "as_of": "2026-04-21T08:22:11Z", "source_hash": "sha256:cd..." }
]
}Same contract: [0] is the BCA canonical page, [1..] are the outlets that corroborate the facts.
3. On-chain + off-chain reconciliation
For tools like get_wallet_profile, a response may reconcile on-chain activity (Etherscan, Helius, Mempool.space) with BCA-enriched narrative context. Each source that contributed gets its own citation entry.
Client behavior
Free / Starter: surface citations[0].cite_url verbatim
The end-user-facing citation rule (see Attribution & licensing) is about citations[0]. Corroborating sources are for audit / UI disclosure, not the primary cite.
Pro+: strip_attribution: true applies to the whole array
Passing strip_attribution: true on Pro and above does not remove attribution.citations from the response: that would break the canonical envelope shape. Instead, the server still returns citations[] (for audit logs and diagnostic purposes), but your tier permission is checked when you decide whether to surface citations[0].cite_url to the downstream end user.
Write the array, read [0]
Every first-party SDK (TS, Python) exposes a .primaryCitation / .primary_citation helper that returns citations[0]. If you're writing against raw HTTP or MCP, index directly:
const primary = env.attribution.citations[0];
console.log(primary.cite_url, primary.as_of);
// For audit logging, persist the full array:
logger.info({
request_id: env.meta.request_id,
sources: env.attribution.citations.map(c => c.source_hash),
});primary = env["attribution"]["citations"][0]
print(primary["cite_url"], primary["as_of"])
# For audit logging, persist the full array:
logger.info({
"request_id": env["meta"]["request_id"],
"sources": [c["source_hash"] for c in env["attribution"]["citations"]],
})Which endpoints return more than one citation?
| Endpoint family | Citations |
|---|---|
| Articles / news corpus | Outlet page first, editorial page second (since 0.4.0) |
| Market prices and candles | CoinGecko or DexScreener page first, editorial page second (since 0.4.0) |
| On-chain reads | Chain explorer first, editorial page second (since 0.4.0) |
| Regulatory, security, sentiment | The regulator, tracker or index page first, editorial page second (since 0.4.0) |
| Entity cards, explainers | Single source (editorial) |
| Indicators, memos, theses, curated directories | Single source (by design) |
| Agent jobs | Single source (by design) |
Entity cards and explainers are editorially curated: they have one canonical source by definition. Our curated directories are our own rankings, also single-source by design.
FAQ
Is citations[] ever empty? Not on HTTP 200. If you see an empty array, it is a bug: file it with the request_id.
Can a citation's as_of be null? Yes, on meta.status: "unseeded" responses the citation points at the canonical BCA page for the yet-to-ship feature, and as_of / source_hash may be null until the integration is live.
Can I pin my agent to citations.length === 1? Don't. You'll break the day we ship multi-source on your endpoint. Read [0], don't assert the length.
Does the order of citations[1..] matter? Only [0] (the primary source) and, when present, the Blockchain Academics editorial link at [1] have fixed meaning. Anything after that is set-valued: treat it as unordered.
Next
- Response envelope: full shape, status enum, error model.
- Attribution & licensing: tier rules for surfacing
cite_urldownstream. - REST API reference: endpoint map and curl examples.