Home / Blog / Cross-source signals: the moat the agencies can't build
2026-05-20 · Harry Vass
Cross-source signals: the moat the agencies can't build
The most interesting AU economic indicators don't live inside any one agency, they're cross-source joins that ABS, RBA, and APRA structurally cannot publish themselves. Here's why.
The Reserve Bank publishes the nominal cash rate. The Bureau of Statistics publishes inflation. Neither publishes the real cash rate, which is the number every monetary-policy commentator actually quotes. The arithmetic is one subtraction.
So why doesn't either agency just publish it?
The answer is structural, and it's the answer to why a thin API layer over public data has a real moat, even when the data underneath is free and the arithmetic is trivial.
<!-- IMG: signal-architecture-diagram.png -->
The four signals we ship today
These five derived endpoints don't exist on any source agency's API. They're built by joining 2-4 source datasets per response:
/v1/real-rate-regime, RBA nominal cash rate minus ABS trimmed-mean CPI (year-ended)./v1/real-wages, ABS Wage Price Index minus ABS CPI, both year-on-year./v1/cost-of-living, ABS Selected Living Cost Indexes joined to ABS CPI for relative comparison across household types./v1/housing-affordability, RBA E2 (housing prices) joined to ABS WPI joined to RBA F1 (cash rate) joined to ABS HES (household income)./v1/gender-pay-context, WGEA gender pay gap by industry joined to ABS Labour Force participation rates and ABS earnings by industry.
Each is one API call. Each cites every source it draws from. Each has a stable schema and a cached fallback when an upstream source 503s.
from ausdata import Ausdata
api = Ausdata()
# One call. Two source agencies. Joined for you.
result = api.get("/v1/real-rate-regime")
print(result["data"])
# {"cash_rate_pct": "<latest>", "real_cash_rate_pct": "<latest>", "trimmed_mean_cpi_pct": "<latest>"}
Why agencies don't (and won't) ship these
Five structural reasons. None of them are technical, the arithmetic is trivial. They're institutional.
1. Mandate boundaries. ABS publishes statistics. RBA publishes monetary-policy data and analysis. Neither agency is permitted to publish derivatives of the other agency's data as an official series without explicit inter-agency agreement. There is no Real Cash Rate Working Group. There never will be, the political cost of an official "real cash rate" series is non-zero (it implies a stance on inflation expectations) and the institutional benefit is zero.
2. Methodology disagreement. Which inflation measure should you subtract? Headline CPI? Trimmed mean? Weighted median? Six-month annualised? RBA tends to use trimmed mean; press tends to use headline; some economists use core. Any single official choice would be politicised. A third-party API can publish a default and let the user override.
3. Update-cycle mismatch. RBA cash-rate decisions are 11 times a year. ABS CPI is quarterly (monthly indicator notwithstanding). For an official series to exist, one agency would need to commit to a publication cadence keyed to the other's release schedule. That's a procurement decision that involves both organisations' executive committees. It does not happen.
4. License compatibility. Each agency licences under CC-BY (ABS, RBA: 4.0; APRA, AIHW, WGEA, ASIC: 3.0 AU). Combining them in an official derived series would require lawyers to sign off on whether 3.0 AU and 4.0 compose cleanly for an official redistribution. A third-party redistributor can comply with each separately (attribution to each source on every response).
5. Audit and revision liability. When ABS revises CPI six weeks later (which it does, routinely), every downstream official series would have to be revised. Agencies don't take on liability for re-publishing other agencies' revisions. A third-party can, because we're explicit that our signals are derived, our retrieved_at timestamps are honest, and our cached fallback is labeled stale=True.
What this means for the moat
The cross-source signal is the actual product. The single-source endpoints are tablestakes, they exist mostly so that the signal responses can credibly cite their components, and so that customers can drop into a source-specific query when they need to.
The moat compounds because:
- Signal count grows linearly with engineering time, not with source count. Once you have N sister MCPs that share a uniform response envelope, the number of N-way signals you can build is combinatorial. The 12th signal is cheaper to build than the 1st.
- Cross-source caching is hard to replicate. Each signal call has to handle the possibility that one source is down. We cache and degrade per-source, then re-compose. A naïve build would 503 on the whole signal when any source 503s; we serve
stale=Truefor the affected component and a full response for the rest.
- Maintenance is the real cost. ABS changes SDMX dataflow IDs. APRA tweaks XLSX format. RBA renames F-tables. Every change ripples into signals. The agencies won't fund maintenance against a derivative they don't publish; the third-party that depends on them economically has every incentive to absorb the maintenance cost.
The economist's view
The signal story isn't unique to AU. Bloomberg's terminal is the world's most successful cross-source signal business, its value is not the underlying data (most of which is public or near-public) but the joined, normalised, queryable layer on top.
The AU public-data world is small enough that one person can build a Bloomberg-shaped layer over the free public sources, charge $29/mo for it, and have a real business. The reason there isn't already one is not technical scarcity, it's that the work is unglamorous and the margins compound slowly.
Worked example: real wages
# Without a signal:
from rba_mcp import server as rba
from abs_mcp import server as abs_
cpi = abs_.get_data("CPI", filters={"measure": "All groups CPI", "region": "Australia"})
wpi = abs_.get_data("WPI", filters={"measure": "Total hourly rates"})
# Align quarters, compute YoY for both, subtract, deal with revisions...
# About 80 lines of pandas.
# With the signal:
from ausdata import Ausdata
print(Ausdata().real_wages(limit=12))
The signal returns the result, the source URLs, the attribution, the retrieved-at timestamp, and a stale flag if any component is from cache. The signal absorbs every breaking change ABS or RBA makes upstream. The user pays $29/mo and writes one line.
What this isn't
The signal story isn't:
- A claim that the underlying data is somehow not free. It is, go download CPI from ABS yourself, the data is yours.
- A claim that we have unique sources. The sources are the public APIs every researcher uses.
- A claim that no competitor can build this. Anyone can. The moat is the maintenance burden and the cost of getting 12 signals to ship-quality at the same time.
Pricing
- Free: 500 calls/month, covers a personal research workflow.
- Analyst: $29/mo, 10k calls, a working newsletter or research team's monthly volume.
- Pro: $99/mo, 100k calls with webhooks, for tools that ship AU data inside their product.
Free key at ausdata.io. Every tier sees every signal.