RÉGIONS & SOUS-ATLAS

Zones agrégées et subdivisions infranationales

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.

GET/api/regions

Registre 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.

Erreurs génériques : voir Démarrage. Aucune erreur propre à cette route (toujours 200).
CURL
curl "https://atlasfeed.fr/api/regions"
PYTHON
import requests

r = requests.get("https://atlasfeed.fr/api/regions")
r.raise_for_status()
print(r.json())
JAVASCRIPT
fetch("https://atlasfeed.fr/api/regions")
  .then(r => r.json())
  .then(console.log);
RÉPONSE
{
  "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.

GET/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.

Paramètre
Type
Requis
Défaut
Description
code
string (path)
oui
—
Code de zone (ex. EU), insensible à la casse.
indicators
string (query)
non
tout le catalogue curaté
Codes séparés par des virgules.
start
int (query)
non
—
Année de début, >= 1960.
end
int (query)
non
—
Année de fin, <= 2100.
Code
Erreur
Cas
404
unknown_region
Le code de zone n'existe pas dans regions.REGIONS.
400
unknown_indicators
Aucun code d'indicators n'est reconnu.
400
too_many_indicators
Plus de 120 codes explicites demandés.
429
too_many_requests_minute
Anonyme, au-delà de 30 requêtes/min (route coûteuse en calcul).
CURL
curl -H "X-API-Key: $ATLAS_KEY" \
  "https://atlasfeed.fr/api/region/EU?indicators=NY.GDP.MKTP.CD"
PYTHON
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())
JAVASCRIPT
fetch("https://atlasfeed.fr/api/region/EU?indicators=NY.GDP.MKTP.CD", {
  headers: { "X-API-Key": "..." },
})
  .then(r => r.json())
  .then(console.log);
RÉPONSE
{
  "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
    }
  ]
}
GET/api/region/custom/aggregate

Agré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).

Paramètre
Type
Requis
Défaut
Description
countries
string (query)
oui
—
Codes pays séparés par des virgules, tronqués aux 5 premiers.
indicators
string (query)
non
tout le catalogue curaté
Codes séparés par des virgules.
start
int (query)
non
—
Année de début, >= 1960.
end
int (query)
non
—
Année de fin, <= 2100.
Code
Erreur
Cas
400
empty_countries_param
countries ne contient aucun code exploitable.
404
unknown_countries
Un ou plusieurs codes pays sont inconnus.
400
unknown_indicators
Aucun code d'indicators n'est reconnu.
400
too_many_indicators
Plus de 120 codes explicites demandés.
429
too_many_requests_minute
Anonyme, au-delà de 30 requêtes/min.
CURL
curl -H "X-API-Key: $ATLAS_KEY" \
  "https://atlasfeed.fr/api/region/custom/aggregate\
?countries=FRA,DEU&indicators=NY.GDP.MKTP.CD"
PYTHON
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())
JAVASCRIPT
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);
RÉPONSE
{
  "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
    }
  ]
}
GET/api/subdivisions

Point 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.

Erreurs génériques : voir Démarrage. Aucune erreur propre à cette route (toujours 200).
CURL
curl "https://atlasfeed.fr/api/subdivisions"
PYTHON
import requests

r = requests.get("https://atlasfeed.fr/api/subdivisions")
r.raise_for_status()
print(r.json())
JAVASCRIPT
fetch("https://atlasfeed.fr/api/subdivisions")
  .then(r => r.json())
  .then(console.log);
RÉPONSE
{
  "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" }
      ]
    }
  ]
}
GET/api/subdivisions/{iso3}/levels

Niveaux 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.

Paramètre
Type
Requis
Défaut
Description
iso3
string (path)
oui
—
Code ISO3 du pays (FRA, USA, CAN au 09/09/2026).
Code
Erreur
Cas
404
message brut, pas via l'i18n
"aucun sous-Atlas pour ce pays : {iso3}" — le pays n'a pas de sous-Atlas.
CURL
curl "https://atlasfeed.fr/api/subdivisions/FRA/levels"
PYTHON
import requests

r = requests.get("https://atlasfeed.fr/api/subdivisions/FRA/levels")
r.raise_for_status()
print(r.json())
JAVASCRIPT
fetch("https://atlasfeed.fr/api/subdivisions/FRA/levels")
  .then(r => r.json())
  .then(console.log);
RÉPONSE
{
  "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": []
}
GET/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).

Paramètre
Type
Requis
Défaut
Description
iso3
string (path)
oui
—
Code ISO3 du pays.
level
string (path)
oui
—
Clé du niveau (ex. region), vue via /levels.
Code
Erreur
Cas
404
message brut
iso3 n'a pas de sous-Atlas.
404
message brut
"niveau inconnu pour {iso3} ({niveaux attendus}) : {level}" — level n'existe pas pour ce pays.
CURL
curl "https://atlasfeed.fr/api/subdivisions/FRA/region"
PYTHON
import requests

r = requests.get("https://atlasfeed.fr/api/subdivisions/FRA/region")
r.raise_for_status()
print(r.json())
JAVASCRIPT
fetch("https://atlasfeed.fr/api/subdivisions/FRA/region")
  .then(r => r.json())
  .then(console.log);
RÉPONSE
{
  "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
    }
  ]
}
GET/api/subdivisions/{iso3}/{level}/{code}

Identité de la subdivision, plus la dernière valeur de chaque indicateur disponible pour elle.

Paramètre
Type
Requis
Défaut
Description
iso3
string (path)
oui
—
Code ISO3 du pays.
level
string (path)
oui
—
Clé du niveau.
code
string (path)
oui
—
Code de la subdivision (ex. FR-ARA).
Code
Erreur
Cas
404
message brut
Pays ou niveau inconnu (mêmes messages que la route précédente).
404
message brut
"subdivision inconnue : {code}" — code n'existe pas à ce niveau.
CURL
curl "https://atlasfeed.fr/api/subdivisions/FRA/region/FR-ARA"
PYTHON
import requests

r = requests.get("https://atlasfeed.fr/api/subdivisions/FRA/region/FR-ARA")
r.raise_for_status()
print(r.json())
JAVASCRIPT
fetch("https://atlasfeed.fr/api/subdivisions/FRA/region/FR-ARA")
  .then(r => r.json())
  .then(console.log);
RÉPONSE
{
  "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.

GET/api/subdivisions/{iso3}/{level}/{code}/series

Séries temporelles complètes de la subdivision, pour tracer un graphe.

Paramètre
Type
Requis
Défaut
Description
iso3
string (path)
oui
—
Code ISO3 du pays.
level
string (path)
oui
—
Clé du niveau.
code
string (path)
oui
—
Code de la subdivision.
start
int (query)
non
—
Année de début, >= 1960.
end
int (query)
non
—
Année de fin, <= 2100.
Code
Erreur
Cas
404
message brut
Pays, niveau ou code de subdivision inconnu (mêmes messages que la route précédente).
CURL
curl "https://atlasfeed.fr/api/subdivisions/FRA/region/FR-ARA/series?start=2018"
PYTHON
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())
JAVASCRIPT
fetch("https://atlasfeed.fr/api/subdivisions/FRA/region/FR-ARA/series?start=2018")
  .then(r => r.json())
  .then(console.log);
RÉPONSE
{
  "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
    }
  ]
}
GET/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/*.

Paramètre
Type
Requis
Défaut
Description
iso3
string (path)
oui
—
Code ISO3 du pays.
level
string (path)
oui
—
Clé du niveau.
family_key
string (path)
oui
—
Famille d'indicateur (ex. INSEE_FILOSOFI_MEDIANE).
scope
string (query)
non
national
national ou regional.
subdivision
string (query)
si scope=regional
—
Code de la subdivision de référence.
Code
Erreur
Cas
404
message brut
Pays ou niveau inconnu.
400
message brut
"scope invalide (national|regional attendu)".
400
message brut
scope=regional sur un niveau sans parent (ex. region en France).
400
message brut
"paramètre subdivision requis pour scope=regional".
404
message brut
"aucune zone pour ce family_key/kind : {family_key}/{kind}" — famille inconnue pour ce niveau.
CURL
curl "https://atlasfeed.fr/api/subdivisions/FRA/rank/region/INSEE_FILOSOFI_MEDIANE"
PYTHON
import requests

r = requests.get(
    "https://atlasfeed.fr/api/subdivisions/FRA/rank/region/INSEE_FILOSOFI_MEDIANE"
)
r.raise_for_status()
print(r.json())
JAVASCRIPT
fetch("https://atlasfeed.fr/api/subdivisions/FRA/rank/region/INSEE_FILOSOFI_MEDIANE")
  .then(r => r.json())
  .then(console.log);
RÉPONSE
{
  "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]] }
  ]
}
GET/api/subdivisions/{iso3}/indicators/{code}/forecast

Mirror 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.

Paramètre
Type
Requis
Défaut
Description
iso3
string (path)
oui
—
Code ISO3 du pays.
code
string (path)
oui
—
Code complet de l'indicateur de subdivision (ex. INSEE_FILOSOFI_MEDIANE:FR-ARA) — pas un code ISO 3166-2 de subdivision seul.
horizon
int (query)
non
5
Nombre d'années à prévoir, 1 à 30.
Code
Erreur
Cas
404
message brut
"indicateur de subdivision inconnu : {code}" — code ne se résout pas via subdivision_sources.resolve.
503
forecast_unavailable
TimesFM (extra forecast) n'est pas installé sur ce déploiement.
429
too_many_requests_minute
Anonyme, au-delà de 30 requêtes/min (route coûteuse en calcul).
CURL
curl "https://atlasfeed.fr/api/subdivisions/FRA/indicators/\
INSEE_FILOSOFI_MEDIANE:FR-ARA/forecast?horizon=5"
PYTHON
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())
JAVASCRIPT
fetch(
  "https://atlasfeed.fr/api/subdivisions/FRA/indicators/" +
  "INSEE_FILOSOFI_MEDIANE:FR-ARA/forecast?horizon=5"
)
  .then(r => r.json())
  .then(console.log);
RÉPONSE
{
  "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.

Erreurs 401/429 génériques : voir la page Démarrage. Voir aussi : Pays & séries