Open data
Every score we publish, with the raw value behind it — so you can check our work rather than trust it.
Files
What you can do with it
Recompute our numbers. indicator-scores.csv carries the raw input value behind every score, alongside the normalized 0–100 result. Take the matching (methodologyVersion, indicatorId) row in indicators.csv, apply its normalization rule to the raw value, and you should land on our number. The rule ships with the files for every version present — the methodology page shows only the version serving the site today, which is not the one that computed most of this history. If you do not land on our number, we would like to know.
Three timestamps, and they mean different things. periodDate is the period the data describes; scoreDate is the date the score is attributed to; computedAt is when we ran the calculation. An annual indicator published in 2026 can describe 2024. None of the three is the date we collected it.
Every score row carries the methodology version that computed it — not the current one, the one in force when that score was calculated. Past scores keep their version permanently, so a series can span several. The dictionaries carry one entry per version, including the normalization rule in force under each, so join on (methodologyVersion, indicatorId) rather than on the id alone. Most of the history predates the version now serving the site (v2.5.1), which is exactly why the older rules ship with it.
The flags carry their thresholds too. isStale compares a row's stalenessDays against the maxStalenessDays of its own methodology version, so it is reproducible per row. degraded follows the degradedRule named on each battery definition, and the two rules differ: the six batteries compare their coverage against the threshold in the JSON's meta, while the composite is degraded as soon as any of its six components is — its own coverage being their average, it can sit above the threshold and still be flagged. That one is a code constant rather than a registry field, so we have never archived it per version: a row computed under an earlier value cannot be told apart.
How a battery score is built, so you can rebuild it. Each row of batteries.csv names its own aggregation rule. The six batteries are weighted_sum_carry_forward: the weighted sum runs over every indicator, a stale one keeps its last value in the sum, and the weights are never renormalized — coverage is the only place staleness shows. The composite is unweighted_mean over the six. If you drop the stale rows and renormalize instead, you will get a different number than ours — which is why the rule ships with the file. Rebuild a battery only from the indicator rows of that battery sharing its methodologyVersion and scoreDate, and whose computedAt is not later than the battery's. We always write a battery's inputs just before the battery itself, so its inputs are never newer than it is. An indicator row that is newer than the battery row is therefore a later calculation that replaced it without recomputing the battery — and the inputs behind that published battery score are no longer in this file. Version and date alone would not tell you: a re-run under the same version overwrites an indicator in place. Like the coverage threshold above, this rule is a code constant rather than a registry field, so it has never been archived per version.
World aggregates only. Every row describes the planet, not a country — the same limit the rest of the site carries.
Licence
The scores are CC BY-SA 4.0. The 26 normalized indicators, the 6 batteries and the composite are released under Creative Commons Attribution-ShareAlike 4.0. Attribute Civilization Watch and share derivative work under the same terms.
The licence travels with the files. datapackage.json is the manifest for the whole set — it names each data file, the columns of each table, and who licenses what, in the format open-data tooling already reads. Files that are entirely ours carry a Link: …; rel="license" header; the two that also contain rawValue deliberately do not — an unqualified licence header would cover the source column too. They point at the manifest instead, with rel="describedby". A CSV detached from the set still carries nothing in its own bytes: the format has no metadata channel that a strict parser would not read as data. Keepdatapackage.jsonalongside the files, or use the JSON export.
Take the files in one go. Each file is cached under its own URL, so in the hours after a methodology revision a cached dictionary can lag the score files. Every data file carries an ETag naming the snapshot it was rendered from — the same value on two files means the same snapshot, rendered by the same code, so if they differ, re-fetch. The gap is bounded: a published methodology snapshot never changes, so a lagging dictionary is missing the newest version's rows, never wrong about the ones it has. datapackage.jsondescribes the shape of the set rather than any one snapshot, so it carries no such tag.
The source data keeps its own licences. The eleven upstream sources do not share one licence, and we cannot relicense them. Each indicator row in indicators.csv names its source and that source's licence, so an attribution can be built from the file itself.
That distinction has one concrete consequence in these files. rawValue reproduces the figure the source published — it is the one column we do not license, and the manifest says so per resource rather than blanketing the whole package. Every other column is our own derived work.
Scores last recomputed 15 Aug 2026, 04:18 UTC. The files are regenerated from the same database that serves this site; what the pipeline did last night is on the status page.