The neobank dataset is now on Hugging Face and Kaggle
The dataset behind this site has always been public — one data.json file, MIT-licensed, no key and no rate limit. As of today it's also mirrored on the two places people actually go looking for data:
| Where | What you get |
|---|---|
| Hugging Face · neobankbeat/neobanks ↗ | Browsable table, one load_dataset call, direct file downloads without an account |
| Kaggle · neobankbeat/neobanks ↗ | Same files, plus a worked notebook that reproduces the charts below |
Both carry 368 verified-active neobanks across 78 countries, and both are generated from the same file this site runs on. If the three ever disagree, data.json is right — the mirrors are copies, not forks.
Two new shapes
The mirrors ship the data in formats the site doesn't serve, because data.json is one object wrapping meta and entities — convenient for a web app, awkward for pandas.
| File | Shape | Use it when |
|---|---|---|
entities.csv | Flat, 38 columns, one row per neobank | Spreadsheets, pandas, anything that wants a table |
entities.jsonl | One JSON object per line, nesting intact | You want fx_markup and friends with their source and date attached |
data.json | { meta, entities } | You want the counts, field notes and methodology too |
The flattening is the part worth knowing about. Several fields aren't scalars — fx_markup, reported_users and volume each carry a value plus the date it was verified and the source it came from. In the CSV those become their own columns, so fx_markup, fx_markup_as_of and fx_markup_source sit side by side. Nothing is dropped to make the table flat.
Load it
from datasets import load_dataset
ds = load_dataset("neobankbeat/neobanks", split="train")
print(ds.filter(lambda e: e["regulation_type"] == "Licensed bank").num_rows, "hold a bank licence")
Or skip the library entirely — the files are static and public:
import pandas as pd
df = pd.read_csv("https://huggingface.co/datasets/neobankbeat/neobanks/resolve/main/entities.csv")
print(df.groupby("regulation_type").size().sort_values(ascending=False))
That last line prints the census from the BaaS post: 127 licensed banks, 77 running on a partner bank, 51 self-custodial apps holding no money at all. The point of publishing the raw table is that you can check that yourself instead of taking the number from a blog post.
What's actually in it
The full field dictionary lives on the dataset page, but the fields that make this different from a marketing roundup are the regulatory ones: regulation_type (own bank licence, e-money institution, sponsor bank, or unregulated), licence (the named authorisation, where disclosed), and custody — who is actually holding the money. That layer is the thing nobody else publishes in machine-readable form, and it's the layer that decides what happens to your balance if the company dies.
Alongside it: cards and networks, verified money-movement services, FX markup with a source and date, stablecoin support, KYC posture, availability by country versus headquarters, founders, funding and disclosed backers.
reported_users_millions, funding and volume are what companies chose to announce, not audited numbers; check reported_users_metric before comparing two rows, because a wallet download is not a funded account. Rates move — cashback, yield and fx_markup are "up to" figures that vary by region, which is why each ships with an as_of date; a stale rate is worse than no rate. Coverage is deliberate — defunct neobanks and pure BaaS/infrastructure providers are excluded, so this is not a survival-analysis dataset, and unverified fields are empty rather than guessed.Why mirror it at all
Partly convenience: load_dataset("neobankbeat/neobanks") is a lower barrier than reading a schema and writing a parser. Partly reach — dataset hubs are where researchers and model pipelines look first, and a dataset that only exists as a JSON file on one domain is invisible to most of them.
And partly durability. This is a one-person project. Publishing the same MIT-licensed file to two independent hubs, with a data card explaining the methodology, means the work outlives this domain. That's the whole point of open data rather than an API with a key.
Keeping it honest
Every refresh is logged in the changelog, the mirrors are re-pushed on material changes, and corrections go through GitHub issues in public. The biggest open gap is still the sponsor-bank layer: most partner-bank neobanks won't say whose licence they're using, so if you know and can source one we've missed, the licence field takes a partner name and a source. Open a data-fix issue.
Cite it
Free to use, including commercially. Attribution appreciated but not required — that's what MIT means. If you build something with it, tell me; I'd like to see it.
Counts reflect the open dataset as of July 2026. Figures are compiled from public filings, registers and product documentation; rates carry their own as-of dates. Nothing here is financial advice. Sources on each profile page.