Deux familles de routes bien distinctes. Les régions
(/api/regions, /api/region/*) agrègent
plusieurs pays — zones nommées (Union européenne, OCDE…) ou zone sur
mesure — en recalculant systématiquement la valeur, jamais reprise telle
quelle de la World Bank. Le sous-Atlas
(/api/subdivisions/*) descend sous le niveau pays : régions,
états, comtés. Il ne couvre pas tous les pays
— au
09/09/2026, seuls la France, les États-Unis
et le Canada ont un sous-Atlas. GET
/api/subdivisions liste précisément quels pays et à quels niveaux
administratifs, à interroger plutôt que de supposer une couverture.
Les deux routes de prévision de cette page
(/api/country/{code}/forecast est traitée dans « Pays &
séries » ; /api/subdivisions/{iso3}/indicators/{code}/forecast
en est le mirror strict, un seul indicateur à la fois) portent toujours
un disclaimer et un tableau warnings dans leur
réponse — jamais de valeur prédite sans cet avertissement. TimesFM
(l'extra forecast) peut être absent du déploiement : la
route répond alors 503 plutôt que d'improviser une
valeur.
/api/regionsRegistre des zones agrégées multi-pays nommées (Union européenne, OCDE, CEDEAO…) disponibles pour le sélecteur du front. Ne prend aucun paramètre : c'est la liste complète, dans les 4 langues, à filtrer côté client si besoin.
curl "https://atlasfeed.fr/api/regions"
import requests
r = requests.get("https://atlasfeed.fr/api/regions")
r.raise_for_status()
print(r.json())fetch("https://atlasfeed.fr/api/regions")
.then(r => r.json())
.then(console.log);{
"regions": [
{
"code": "EU",
"label": "Union européenne",
"labels": {
"fr": "Union européenne",
"en": "European Union",
"es": "Unión Europea",
"de": "Europäische Union"
},
"countries": ["AUT", "BEL", "BGR", "HRV", "CYP", "..."]
}
]
}Piège : le code de l'Union européenne est EU, pas UE — /api/region/UE renvoie 404.
/api/region/{code}Agrégat recalculé (jamais repris tel quel de la World Bank) pour une zone nommée de {code}. La casse du code n'importe pas.
EU), insensible à la casse.>= 1960.<= 2100.unknown_regionregions.REGIONS.unknown_indicatorsindicators n'est reconnu.too_many_indicatorstoo_many_requests_minutecurl -H "X-API-Key: $ATLAS_KEY" \ "https://atlasfeed.fr/api/region/EU?indicators=NY.GDP.MKTP.CD"
import requests
r = requests.get(
"https://atlasfeed.fr/api/region/EU",
params={"indicators": "NY.GDP.MKTP.CD"},
headers={"X-API-Key": "..."},
)
r.raise_for_status()
print(r.json())fetch("https://atlasfeed.fr/api/region/EU?indicators=NY.GDP.MKTP.CD", {
headers: { "X-API-Key": "..." },
})
.then(r => r.json())
.then(console.log);{
"region": {
"code": "EU",
"label": "Union européenne",
"countries": ["AUT", "BEL", "..."]
},
"indicators": [
{
"code": "NY.GDP.MKTP.CD",
"label": "PIB",
"theme": "Économie",
"unit": "US$ courants",
"fmt": "currency",
"headline": true,
"points": [{ "year": 1960, "value": 270626809484.91116 }],
"latest": { "...": "..." },
"unavailable": false
}
]
}/api/region/custom/aggregateAgrégat calculé pour une zone « sur mesure » définie à la volée — mêmes contraintes de liste de pays que /api/compare (5 pays maximum).
>= 1960.<= 2100.empty_countries_paramcountries ne contient aucun code exploitable.unknown_countriesunknown_indicatorsindicators n'est reconnu.too_many_indicatorstoo_many_requests_minutecurl -H "X-API-Key: $ATLAS_KEY" \ "https://atlasfeed.fr/api/region/custom/aggregate\ ?countries=FRA,DEU&indicators=NY.GDP.MKTP.CD"
import requests
r = requests.get(
"https://atlasfeed.fr/api/region/custom/aggregate",
params={"countries": "FRA,DEU", "indicators": "NY.GDP.MKTP.CD"},
headers={"X-API-Key": "..."},
)
r.raise_for_status()
print(r.json())fetch("https://atlasfeed.fr/api/region/custom/aggregate?countries=FRA,DEU&indicators=NY.GDP.MKTP.CD", {
headers: { "X-API-Key": "..." },
})
.then(r => r.json())
.then(console.log);{
"region": { "code": null, "label": "Zone sur mesure", "countries": ["FRA", "DEU"] },
"indicators": [
{
"code": "NY.GDP.MKTP.CD",
"label": "PIB",
"theme": "Économie",
"unit": "US$ courants",
"fmt": "currency",
"headline": true,
"points": [{ "year": 1960, "value": 146578931766.60352 }],
"unavailable": false
}
]
}/api/subdivisionsPoint d'entrée du sous-Atlas : liste les pays qui en ont un, avec leurs niveaux administratifs. Le front ne connaît aucun ISO3 de sous-Atlas par son nom — il découvre tout par cette route.
curl "https://atlasfeed.fr/api/subdivisions"
import requests
r = requests.get("https://atlasfeed.fr/api/subdivisions")
r.raise_for_status()
print(r.json())fetch("https://atlasfeed.fr/api/subdivisions")
.then(r => r.json())
.then(console.log);{
"countries": [
{
"iso3": "FRA",
"levels": [
{ "key": "region", "depth": 0, "codeScheme": "iso-3166-2" },
{ "key": "departement", "depth": 1, "codeScheme": "iso-3166-2" }
]
},
{
"iso3": "USA",
"levels": [
{ "key": "etat", "depth": 0, "codeScheme": "fips-6-4" },
{ "key": "comte", "depth": 1, "codeScheme": "fips-6-4" }
]
},
{
"iso3": "CAN",
"levels": [
{ "key": "province", "depth": 0, "codeScheme": "sgc" },
{ "key": "division", "depth": 1, "codeScheme": "sgc" }
]
}
]
}/api/subdivisions/{iso3}/levelsNiveaux administratifs déclarés par ce pays (du plus large au plus fin), avec la géométrie vendorisée associée — permet au front de ne rien coder en dur par pays.
FRA, USA, CAN au 09/09/2026)."aucun sous-Atlas pour ce pays : {iso3}" — le pays n'a pas de sous-Atlas.curl "https://atlasfeed.fr/api/subdivisions/FRA/levels"
import requests
r = requests.get("https://atlasfeed.fr/api/subdivisions/FRA/levels")
r.raise_for_status()
print(r.json())fetch("https://atlasfeed.fr/api/subdivisions/FRA/levels")
.then(r => r.json())
.then(console.log);{
"iso3": "FRA",
"levels": [
{ "key": "region", "depth": 0, "codeScheme": "iso-3166-2", "hasParent": false, "parentCodePrefix": null },
{ "key": "departement", "depth": 1, "codeScheme": "iso-3166-2", "hasParent": true, "parentCodePrefix": null }
],
"geometry": { "departement": "./vendor/france/departements-version-simplifiee.geojson" },
"insetGeometry": [
{ "url": "./vendor/france/departements-guadeloupe.geojson", "label": "Guadeloupe", "code": "FR-971" }
],
"mainProjectionExcludes": []
}/api/subdivisions/{iso3}/{level}Identité de toutes les subdivisions d'un niveau donné, sans indicateur. Déclarée après /levels dans le routeur : un pays dont un niveau s'appellerait littéralement levels serait inatteignable ici (piège connu et accepté dans le code).
region), vue via /levels.iso3 n'a pas de sous-Atlas."niveau inconnu pour {iso3} ({niveaux attendus}) : {level}" — level n'existe pas pour ce pays.curl "https://atlasfeed.fr/api/subdivisions/FRA/region"
import requests
r = requests.get("https://atlasfeed.fr/api/subdivisions/FRA/region")
r.raise_for_status()
print(r.json())fetch("https://atlasfeed.fr/api/subdivisions/FRA/region")
.then(r => r.json())
.then(console.log);{
"iso3": "FRA",
"level": "region",
"subdivisions": [
{
"code": "FR-ARA",
"name": "Auvergne-Rhône-Alpes",
"kind": "region",
"parent_code": null,
"flag_url": "https://commons.wikimedia.org/wiki/Special:FilePath/Flag%20of%20the%20region%20Auvergne-Rh%C3%B4ne-Alpes.svg",
"coat_of_arms_url": "https://commons.wikimedia.org/wiki/Special:FilePath/Blason%20Auvergne-Rh%C3%B4ne-Alpes.svg",
"area_km2": 69711.0,
"population": 8205557,
"population_year": 2023,
"prefecture": "Lyon",
"president": null
}
]
}/api/subdivisions/{iso3}/{level}/{code}Identité de la subdivision, plus la dernière valeur de chaque indicateur disponible pour elle.
FR-ARA)."subdivision inconnue : {code}" — code n'existe pas à ce niveau.curl "https://atlasfeed.fr/api/subdivisions/FRA/region/FR-ARA"
import requests
r = requests.get("https://atlasfeed.fr/api/subdivisions/FRA/region/FR-ARA")
r.raise_for_status()
print(r.json())fetch("https://atlasfeed.fr/api/subdivisions/FRA/region/FR-ARA")
.then(r => r.json())
.then(console.log);{
"subdivision": {
"code": "FR-ARA", "name": "Auvergne-Rhône-Alpes", "kind": "region", "parent_code": null,
"flag_url": "...", "coat_of_arms_url": "...", "area_km2": 69711.0,
"population": 8205557, "population_year": 2023, "prefecture": "Lyon", "president": null
},
"indicators": [
{
"code": "INSEE_FILOSOFI_MEDIANE:FR-ARA",
"label": "Niveau de vie médian annuel, Filosofi 2023 (€)",
"source": "insee_subdivisions",
"fmt": "number",
"theme": "Social",
"familyKey": "INSEE_FILOSOFI_MEDIANE",
"latest": {
"year": 2023, "value": 26920.0, "previousYear": null,
"previousValue": null, "changeAbs": null, "changePct": null,
"preferredChange": "pct"
},
"unavailable": false
}
]
}Contrairement au catalogue pays, les indicateurs de subdivision ne portent pas de champ unit traduit — ils viennent d'une découverte « live » sans cette métadonnée structurée.
/api/subdivisions/{iso3}/{level}/{code}/seriesSéries temporelles complètes de la subdivision, pour tracer un graphe.
>= 1960.<= 2100.curl "https://atlasfeed.fr/api/subdivisions/FRA/region/FR-ARA/series?start=2018"
import requests
r = requests.get(
"https://atlasfeed.fr/api/subdivisions/FRA/region/FR-ARA/series",
params={"start": 2018},
)
r.raise_for_status()
print(r.json())fetch("https://atlasfeed.fr/api/subdivisions/FRA/region/FR-ARA/series?start=2018")
.then(r => r.json())
.then(console.log);{
"subdivision": { "code": "FR-ARA", "name": "Auvergne-Rhône-Alpes", "...": "..." },
"range": { "start": 2018, "end": null },
"series": [
{
"code": "INSEE_FILOSOFI_MEDIANE:FR-ARA",
"label": "Niveau de vie médian annuel, Filosofi 2023 (€)",
"source": "insee_subdivisions",
"fmt": "number",
"theme": "Social",
"familyKey": "INSEE_FILOSOFI_MEDIANE",
"points": [{ "year": 2023, "value": 26920.0 }],
"latest": {
"year": 2023, "value": 26920.0, "previousYear": null,
"previousValue": null, "changeAbs": null, "changePct": null,
"preferredChange": "pct"
},
"unavailable": false
}
]
}/api/subdivisions/{iso3}/rank/{level}/{family_key}Classement d'une subdivision parmi les autres de même échelle — national (toutes les subdivisions du niveau) ou régional (au sein d'une subdivision parente), mirror adapté de /api/rank/*.
INSEE_FILOSOFI_MEDIANE).nationalnational ou regional.scope=regional"scope invalide (national|regional attendu)".scope=regional sur un niveau sans parent (ex. region en France)."paramètre subdivision requis pour scope=regional"."aucune zone pour ce family_key/kind : {family_key}/{kind}" — famille inconnue pour ce niveau.curl "https://atlasfeed.fr/api/subdivisions/FRA/rank/region/INSEE_FILOSOFI_MEDIANE"
import requests
r = requests.get(
"https://atlasfeed.fr/api/subdivisions/FRA/rank/region/INSEE_FILOSOFI_MEDIANE"
)
r.raise_for_status()
print(r.json())fetch("https://atlasfeed.fr/api/subdivisions/FRA/rank/region/INSEE_FILOSOFI_MEDIANE")
.then(r => r.json())
.then(console.log);{
"code": "INSEE_FILOSOFI_MEDIANE",
"kind": "region",
"scope": "national",
"label": "Niveau de vie médian annuel, Filosofi 2023 (€)",
"fmt": "number",
"theme": "Social",
"ranking": [
{ "rank": 1, "code": "FR-IDF", "name": "Île-de-France", "value": 28210.0, "year": 2023, "points": [[2023, 28210.0]] },
{ "rank": 2, "code": "FR-ARA", "name": "Auvergne-Rhône-Alpes", "value": 26920.0, "year": 2023, "points": [[2023, 26920.0]] }
]
}/api/subdivisions/{iso3}/indicators/{code}/forecastMirror strict de /api/country/{code}/forecast (voir « Pays & séries »), mais sur un seul indicateur de subdivision — jamais en masse, jamais de liste de codes.
INSEE_FILOSOFI_MEDIANE:FR-ARA) — pas un code ISO 3166-2 de subdivision seul.1 à 30."indicateur de subdivision inconnu : {code}" — code ne se résout pas via subdivision_sources.resolve.forecast_unavailableforecast) n'est pas installé sur ce déploiement.too_many_requests_minutecurl "https://atlasfeed.fr/api/subdivisions/FRA/indicators/\ INSEE_FILOSOFI_MEDIANE:FR-ARA/forecast?horizon=5"
import requests
r = requests.get(
"https://atlasfeed.fr/api/subdivisions/FRA/indicators/"
"INSEE_FILOSOFI_MEDIANE:FR-ARA/forecast",
params={"horizon": 5},
)
r.raise_for_status()
print(r.json())fetch( "https://atlasfeed.fr/api/subdivisions/FRA/indicators/" + "INSEE_FILOSOFI_MEDIANE:FR-ARA/forecast?horizon=5" ) .then(r => r.json()) .then(console.log);
{
"code": "INSEE_FILOSOFI_MEDIANE:FR-ARA",
"label": "Niveau de vie médian annuel, Filosofi 2023 (€)",
"source": "insee_subdivisions",
"fmt": "number",
"theme": "Social",
"familyKey": "INSEE_FILOSOFI_MEDIANE",
"horizon": 5,
"model": "timesfm-2.5-200m",
"disclaimer": "Extrapolation zero-shot d'une série annuelle courte. [...]",
"history": [{ "year": 2023, "value": 26920.0 }],
"forecast": [{ "year": 2024, "value": 0 }],
"contextYears": 1,
"unavailable": false,
"warnings": [],
"lastPointPartial": false
}lastPointPartial vaut true uniquement pour les sources qui portent cette information (Banque de France, CFTDC — année en cours partielle), false sinon.