Home / Blog / The most under-cited AU dataset: APRA's monthly ADI key stats
2026-05-20 · Harry Vass
The most under-cited AU dataset: APRA's monthly ADI key stats
APRA's Monthly Authorised Deposit-taking Institution Statistics (MADIS) is the cleanest public look at every AU bank's balance sheet, and almost nobody outside the prudential team queries it directly. Here's how, and why.
Ask any AU banking analyst where they get monthly bank balance-sheet data and they'll say one of three things: a Bloomberg terminal, an annual report PDF, or "we pay a vendor for it." Almost none will say APRA, and yet APRA publishes the Monthly Authorised Deposit-taking Institution Statistics (MADIS) for every single ADI in the country, with about 50 line items per institution, on a one-month publication lag.
It is the cleanest, most under-cited public dataset in Australian financial regulation. This post walks through why nobody uses it, what's in it, and how to query it in one line via apra-mcp or the hosted API.
<!-- IMG: madis-coverage-diagram.png -->
What MADIS actually contains
For every Australian ADI (about 140 institutions, big 4, regional banks, mutuals, foreign branches, restricted ADIs), MADIS publishes monthly:
- Loans by category: housing (owner-occupier vs investor), credit cards, personal, business
- Deposits by category: household, intermediated, CDs, at-call vs term
- Total assets, total liabilities, capital
- Cash, due-from-other-banks, trading securities
- Provisions for impairment
Every line item. Every ADI. Every month. CC-BY 3.0 AU.
The closest commercial substitute is RBA's E1 and B-series tables, which aggregate to the system level, useful for macro, useless if you want to see Bendigo and Adelaide Bank's mortgage book separate from Suncorp's.
Why almost nobody queries it directly
Three reasons.
1. The publication format is a 30-tab XLSX with merged headers. APRA publishes MADIS as MADIS_back-series_YYYY-MM.xlsx. The first tab is a contents list. Each subsequent tab is one balance-sheet category. The ADI names are in column A. The dates run across columns B onwards. Cells have footnoted suffixes ((a), (b)) that aren't in the data, they're in a notes tab seven sheets later.
Writing a robust pandas parser for that takes about a day. Maintaining it across APRA's occasional format tweaks takes more.
2. ADI codes are not standardised across releases. "Westpac Banking Corporation" and "Westpac Banking Corp" and "WBC" appear in different vintages. Fuzzy matching is fine if you know to do it; brittle pipelines have shipped without it.
3. The data is split across MADIS (monthly) and QADIS (quarterly). Monthly has the volume metrics. Quarterly adds capital, profitability, and credit-quality. Joining them is the analyst's job, APRA does not publish a combined view.
The net effect: there's a real dataset behind a real wall of friction. Most teams pay vendors $50-200k/yr for cleaned versions of public data.
Querying it via apra-mcp
The free apra-mcp package wraps MADIS (and six other APRA datasets) behind the standard portfolio surface:
from apra_mcp import server
# List the curated APRA datasets
print(server.list_curated())
# Describe MADIS, schema, columns, valid filters
print(server.describe_dataset("MADIS"))
# Query: total housing loans for the big 4, last 12 months
data = server.get_data(
dataset_id="MADIS",
filters={
"institution": ["ANZ", "CBA", "NAB", "Westpac"],
"measure": "housing_loans_total",
},
period={"start": "2025-05", "end": "2026-04"},
)
print(data.records[:3])
Output (truncated):
[
{
"institution": "Australia and New Zealand Banking Group Limited",
"period": "2026-04",
"measure": "housing_loans_total",
"value_aud_millions": 286412.0
},
...
]
You get parsed records, period-normalised to YYYY-MM, with the institution names already aliased to canonical forms. No XLSX parsing. No footnote stripping.
Via the hosted API
If you'd rather not host an MCP, the same data is in ausdata-api:
curl -H "Authorization: Bearer $AUSDATA_KEY" \
"https://api.ausdata.io/v1/data/apra/MADIS?filters.institution=ANZ&filters.measure=housing_loans_total&period.start=2025-05"
Returns the standard DataResponse envelope, source URL, attribution, retrieved_at, the works.
Three queries every banking team should run
1. Deposit-flight monitor. Households moving money between ADIs in response to rate changes:
data = server.get_data(
dataset_id="MADIS",
filters={"measure": "household_deposits_total"},
period={"start": "2024-01"},
)
# Pivot to (institution, period), diff month-on-month, sort.
2. Investor-mortgage growth-rate concentration. Which ADI is growing the investor book fastest:
data = server.get_data(
dataset_id="MADIS",
filters={"measure": "housing_loans_investor"},
period={"start": "2025-01"},
)
3. New ADI watch. Restricted ADIs and foreign branches that have just started reporting:
data = server.list_curated()
# Check institution coverage in latest period vs N-12 months ago.
What this isn't
MADIS is not:
- Real-time. There's a ~30-day publication lag from month-end.
- Granular below ADI level. No branch-level, no geographic, no per-product breakdown.
- A capital-adequacy dataset on its own. For Tier 1 ratios, join MADIS with QADIS.
- A substitute for the prudential reporting forms (ARF/ARS) that ADIs file privately, those are confidential and APRA doesn't release them.
If you need real-time bank data, you're going to pay a vendor or scrape disclosures. If you can live with month-lag balance-sheet data for every AU ADI, MADIS is free and excellent.
Pricing
- Free tier: 500 calls/month, fits a quarterly research workflow.
- Analyst: $29/mo, 10k calls, fits a weekly newsletter or research note.
- Pro: $99/mo, 100k calls, fits a fintech that polls hourly.
Free key at ausdata.io.