Accueil / Référence / Ancienne API
Ancien GeoService · déprécié

L'ancienne API /services

Les routes de l'ancien GeoService restent servies au même format, pour que les intégrations existantes continuent de fonctionner. Cette page dit ce qui a changé ; pour toute nouvelle intégration, utilisez l'API v2.

Cette API est dépréciée. Elle ne reçoit plus que des correctifs de sécurité et de justesse, et sera retirée le 1er avril 2027. Ne l'utilisez pas pour une nouvelle intégration.

Le guide de migration donne, route par route, l'équivalent dans l'API v2.

Référence

Les routes servies

Mêmes chemins qu'auparavant, sans clé d'API. Chaque route répond avec ou sans barre oblique finale. Seuls les paramètres listés sont lus ; les autres sont ignorés, sauf sur ban/*, qui les transmet tous au moteur.

RouteParamètres lusEn v2
GET /services/ban/searchq (requis), limit, type, postcode, citycode, lat, lon, autocomplete…Géocodage BAN
GET /services/ban/reverselat, lon (requis), limit, type…Géocodage BAN
GET /services/geocodeq (requis), lang, limitGéocodage OSM
GET /services/reverselat, lon (requis), langGéocodage OSM
GET /services/directions/routepoint=lat,lon (au moins deux), vehicule ou vehicle, locale, points_encodedItinéraire
GET /services/directions/isochronepoint=lat,lon (requis), vehicule ou vehicle, time_limit, distance_limit, bucketsIsochrone
POST /services/directions/matrixCorps JSON : from_points et to_points, ou points ; vehicle, out_arrays, fail_fastMatrice

Profils : car (par défaut), foot et bike. Tout autre chemin sous /services, dont l'ancien format /services/v1/*, répond 404.

Exemples

Exemples d'appels

Un appel par route, avec sa réponse réelle, abrégée quand elle est longue (…). Ils servent à reconnaître et à vérifier les appels existants : pour une nouvelle intégration, partez de l'équivalent v2, en lien sur chaque route.

GET/services/ban/searchÉquivalent v2

Format natif d'addok, identique à celui de /v2/geocoding/ban/search.

curl -G "https://geoservice.example.com/services/ban/search" \
  --data-urlencode "q=87 avenue d'italie, 75013" \
  -d limit=1
200 OK
{
  "type": "FeatureCollection",
  "version": "draft",
  "features": [{
    "type": "Feature",
    "geometry": {"type": "Point", "coordinates": [2.358434, 48.824031]},
    "properties": {
      "label": "87 Avenue d'Italie 75013 Paris",
      "score": 0.89274,
      "housenumber": "87",
      "id": "75113_4754_00087",
      "banId": "aee01bd3-241d-4939-9981-2432d129343f",
      "name": "87 Avenue d'Italie",
      "postcode": "75013",
      "citycode": "75113",
      "x": 652897,
      "y": 6858410.19,
      "city": "Paris",
      "district": "Paris 13e Arrondissement",
      "context": "75, Paris, Île-de-France",
      "type": "housenumber",
      "importance": 0.82014,
      "street": "Avenue d'Italie"
    }
  }],
  "attribution": "BAN",
  "licence": "ETALAB-2.0",
  "query": "87 avenue d'italie, 75013",
  "limit": 1
}

Adresse BAN d'un point

GET/services/ban/reverseÉquivalent v2

Ajoute distance, en mètres, entre le point demandé et l'adresse trouvée.

curl "https://geoservice.example.com/services/ban/reverse?lat=48.8240267&lon=2.3584248&limit=1"
200 OK
{
  "type": "FeatureCollection",
  "version": "draft",
  "features": [{
    "type": "Feature",
    "geometry": {"type": "Point", "coordinates": [2.358434, 48.824031]},
    "properties": {
      "label": "87 Avenue d'Italie 75013 Paris",
      "score": 0.9999999997274487,
      "housenumber": "87",
      "id": "75113_4754_00087",
      "banId": "aee01bd3-241d-4939-9981-2432d129343f",
      "name": "87 Avenue d'Italie",
      "postcode": "75013",
      "citycode": "75113",
      "x": 652897,
      "y": 6858410.19,
      "city": "Paris",
      "district": "Paris 13e Arrondissement",
      "context": "75, Paris, Île-de-France",
      "type": "housenumber",
      "importance": 0.82014,
      "street": "Avenue d'Italie",
      "distance": 0
    }
  }],
  "attribution": "BAN",
  "licence": "ETALAB-2.0",
  "limit": 1
}

Rechercher un lieu OSM

GET/services/geocodeÉquivalent v2

Format de photon : propriétés à plat, extent sur les objets étendus.

curl -G "https://geoservice.example.com/services/geocode" \
  --data-urlencode "q=Avenue d'Italie 75013 Paris France" \
  -d lang=fr -d limit=1
200 OK
{
  "features": [{
    "geometry": {"type": "Point", "coordinates": [2.3574814, 48.8254891]},
    "type": "Feature",
    "properties": {
      "osm_id": 685719842,
      "osm_type": "W",
      "osm_key": "highway",
      "osm_value": "primary",
      "name": "Avenue d'Italie",
      "street": "Avenue d'Italie",
      "postcode": "75013",
      "country": "France",
      "city": "Paris",
      "countrycode": "FR",
      "extent": [2.3574144, 48.825715, 2.3575502, 48.8252637]
    }
  }],
  "type": "FeatureCollection"
}

Lieu OSM d'un point

GET/services/reverseÉquivalent v2

Un seul résultat, quel que soit limit.

curl "https://geoservice.example.com/services/reverse?lat=48.8240267&lon=2.3584248&lang=fr"
200 OK
{
  "features": [{
    "geometry": {"type": "Point", "coordinates": [2.3584248, 48.8240267]},
    "type": "Feature",
    "properties": {
      "osm_id": 2540682965,
      "osm_type": "N",
      "osm_key": "place",
      "osm_value": "house",
      "housenumber": "87",
      "street": "Avenue d'Italie",
      "postcode": "75013",
      "country": "France",
      "city": "Paris",
      "countrycode": "FR"
    }
  }],
  "type": "FeatureCollection"
}

Itinéraire

GET/services/directions/routeÉquivalent v2

Format de GraphHopper : distances en mètres, durées en millisecondes.

curl -G "https://geoservice.example.com/services/directions/route" \
  -d point=48.855199,2.354035 \
  -d point=48.853138,2.349185 \
  -d vehicule=car -d locale=fr \
  -d points_encoded=false
200 OK · réponse abrégée
{
  "hints": {},
  "paths": [{
    "instructions": [
      {"distance": 15.0, "sign": 0, "interval": [0, 2], "text": "Conduisez vers le nord-ouest sur Rue de l'Hôtel de Ville.", "time": 5663, "street_name": "Rue de l'Hôtel de Ville"},
      {"distance": 79.0, "sign": 2, "interval": [2, 8], "text": "Tournez à droite dans Rue de Brosse.", "time": 34211, "street_name": "Rue de Brosse"},
      …
      {"distance": 0.0, "sign": 4, "interval": [75, 75], "text": "Vous êtes arrivé à votre destination.", "time": 0, "street_name": ""}
    ],
    "distance": 1185.0,
    "time": 321450,
    "bbox": [2.349207, 48.853633, 2.356614, 48.856957],
    "points_encoded": false,
    "points": {"type": "LineString", "coordinates": [[2.353976, 48.855143], [2.353882, 48.855185], …]},
    "snapped_waypoints": {"type": "LineString", "coordinates": [[2.353976, 48.855143], [2.349207, 48.853633]]},
    …
  }],
  "info": {"took": 96, "copyrights": ["Valhalla", "OpenStreetMap contributors"]}
}

Isochrone

GET/services/directions/isochroneÉquivalent v2

Deux minutes à pied (time_limit en secondes) ; un polygone par bucket, du plus petit au plus grand.

curl -G "https://geoservice.example.com/services/directions/isochrone" \
  -d point=48.853401,2.348792 \
  -d time_limit=120 -d vehicule=foot
200 OK
{
  "polygons": [{
    "geometry": {
      "coordinates": [[
        [2.349792, 48.855144], [2.347792, 48.854954], [2.346638, 48.853554],
        [2.348792, 48.851993], [2.350097, 48.852401], [2.351211, 48.853401],
        [2.349792, 48.855144]
      ]],
      "type": "Polygon"
    },
    "type": "Feature",
    "properties": {"bucket": 0}
  }],
  "copyrights": ["Valhalla", "OpenStreetMap contributors"]
}

Matrice

POST/services/directions/matrixÉquivalent v2

Points en [lon, lat] ; distances en mètres, durées en secondes, indexées [origine][destination].

curl "https://geoservice.example.com/services/directions/matrix" \
  -H "Content-Type: application/json" \
  -d '{
    "from_points": [[2.358052, 48.824101]],
    "to_points": [
      [2.364601, 48.833535],
      [2.374128, 48.815678],
      [2.342628, 48.845737]
    ],
    "vehicle": "car",
    "out_arrays": ["distances", "times"]
  }'
200 OK
{
  "distances": [[1484, 2300, 3028]],
  "times": [[216, 293, 485]],
  "info": {"copyrights": ["Valhalla", "OpenStreetMap contributors"]}
}
Changements

Ce qui a changé depuis l'ancien serveur

Les chemins, les paramètres et la structure des réponses sont conservés. Les moteurs, eux, ont changé : les valeurs peuvent différer, et quelques comportements ont été corrigés.

Toutes les routes

  • Une erreur répond avec le code HTTP attendu et un corps JSON au format du GeoService (ci-dessous), au lieu d'une page HTML d'erreur ou d'une connexion coupée.
  • Une requête qu'un moteur refuserait est refusée d'emblée, en 400, avec un detail qui nomme le paramètre en cause.

Géocodage BAN (ban/search, ban/reverse)

  • Chaque résultat porte en plus properties.banId, l'identifiant de l'adresse dans les données récentes de la BAN.
  • Une longitude aberrante, très loin au-delà de ±180, est refusée (400).

Géocodage OSM (geocode, reverse)

  • Le premier résultat peut changer, au même endroit : par exemple l'avenue elle-même plutôt qu'un point d'intérêt situé sur l'avenue. L'ordre et le nombre des résultats diffèrent aussi.
  • Les paramètres osm_tag, layer, bbox, countrycode, zoom, location_bias_scale et dedupe sont ignorés : les résultats ne sont plus filtrés. lat et lon ne favorisent plus les résultats proches.
  • reverse renvoie un seul résultat, quel que soit limit ; radius est ignoré.

Itinéraire (directions/route)

  • vehicule est désormais pris en compte. L'ancien serveur l'ignorait et calculait tout en voiture : vehicule=foot donne maintenant un itinéraire à pied. bike est servi ; une valeur inconnue répond 400.
  • Les durées en voiture sont nettement plus longues en ville (près de deux fois sur un trajet court dans Paris) : le nouveau moteur compte les virages, les feux et les intersections. À pied, elles sont quasiment identiques.
  • Un point mal formé, y compris lat,lon,altitude, est refusé (400) au lieu d'être ignoré en silence. Au-delà d'un nombre maximal de points, la requête est refusée (400).
  • Les autres paramètres de l'ancien moteur sont ignorés : instructions, calc_points, elevation, type=gpx… Les instructions sont toujours renvoyées, en JSON.
  • hints est vide, weight n'est qu'une approximation et info.copyrights nomme Valhalla.
  • Instructions : une arrivée à chaque étape intermédiaire, un rond-point en deux instructions (entrée, puis sortie), des textes reformulés. Douze langues ne sont plus traduites (ast, eo, fa, fil, gl, he, hr, hsb, lt, ne, sr, zh) et passent à l'anglais.
  • Un point peut être recalé sur une autre voie proche qu'auparavant.

Isochrone (directions/isochrone)

  • vehicule est désormais pris en compte, comme pour l'itinéraire : vehicule=foot donne une isochrone à pied, et non plus en voiture. bike est servi.
  • Les zones sont plus larges et plus anguleuses : le nouveau moteur trace ses contours sur une grille.
  • Le nombre de buckets, la durée et la distance sont limités : au-delà, la requête est refusée (400). Le nombre maximal de buckets est plus bas qu'auparavant.
  • Un time_limit décimal (120.5) est respecté, au lieu de valoir 600 secondes.
  • result=pointlist et reverse_flow sont ignorés : la réponse contient toujours des polygones.
  • Un point hors des données couvertes reçoit une petite zone autour de lui, en 200, au lieu d'une erreur.

Matrice (directions/matrix)

  • Les durées en voiture sont plus longues, pour la même raison que l'itinéraire ; les distances diffèrent case par case, le chemin emprunté n'étant pas toujours le même. À pied, les valeurs sont quasiment identiques.
  • weights n'est qu'une approximation : la durée en secondes.
  • Sont désormais servis : out_arrays absent (qui donne weights), vehicle entouré d'espaces, et le profil bike. Un champ inconnu est ignoré au lieu d'être refusé.
  • fail_fast: false est accepté : une case sans itinéraire vaut alors null, au lieu de faire échouer toute la matrice (422).
  • Le nombre de couples origine × destination et la distance à vol d'oiseau entre deux points sont limités : au-delà, la matrice est refusée (400). Un corps de requête trop volumineux est refusé (413), et une longitude hors de [−180, 180] aussi (400).
Erreurs

Les erreurs de l'ancienne API

Toutes les erreurs de /services sont au format du GeoService, application/problem+json (description du format), y compris celles des moteurs, traduites. Testez le membre code.

HTTPcodeCauseQue faire
400invalid_parameterParamètre absent ou mal formé, profil inconnu, requête au-delà d'une limiteCorriger la requête : detail nomme le paramètre.
404unknown_endpointRoute inexistante sous /servicesCorriger l'URL.
405method_not_allowedMéthode non acceptée, par exemple POST sur geocodeUtiliser la méthode de l'en-tête Allow.
413payload_too_largeCorps de la matrice trop volumineuxDécouper la matrice.
422route_impossiblePoint trop loin de toute voie ou hors des données, points non reliés ou trop éloignés, case de matrice sans itinéraireChanger de point ou de profil.
429—Trop de requêtes en peu de temps. Réponse produite en amont du GeoService : ni corps Problem Details, ni en-têtes de dépréciation.Ralentir, puis réessayer.
500internal_errorErreur inattendue du GeoServicePrévenir Galigeo.
502upstream_invalid_responseRéponse du moteur inexploitableRéessayer après un délai ; prévenir Galigeo si l'erreur persiste.
503upstream_unavailableMoteur momentanément injoignableRéessayer après un délai.
504upstream_timeoutLe moteur a mis trop de temps à répondreRéessayer, ou alléger la requête.
422 Unprocessable Content · application/problem+json
{
  "type": "tag:galigeo.com,2026:geoservice:route_impossible",
  "title": "Itinéraire impossible",
  "status": 422,
  "detail": "Un des points est trop loin de toute voie praticable.",
  "instance": "/services/directions/route",
  "code": "route_impossible"
}
Dépréciation

Détecter la dépréciation dans vos réponses

Les réponses de /services, erreurs comprises, portent des en-têtes standard : Deprecation et Link (RFC 9745) pour la dépréciation, Sunset (RFC 8594) pour la date de retrait. Seule exception : le 429 de limitation du débit, produit en amont du GeoService, ne les porte pas.

En-têteContenu
DeprecationLa date de dépréciation, en secondes Unix précédées de @ : @1767225600 désignerait le 1er janvier 2026 à 0 h UTC.
LinkLe lien vers le guide de migration : <https://…/migration>; rel="deprecation"; type="text/html".
SunsetLa date de retrait, au format date HTTP : Thu, 01 Apr 2027 00:00:00 GMT. À partir de cet instant, /services ne répond plus.

Faites-les remonter dans vos journaux ou votre supervision : vous saurez ainsi quelles parties de votre code appellent encore l'ancienne API. Ces en-têtes sont lisibles depuis un navigateur.

const res = await fetch(url);
if (res.headers.has("Deprecation") || res.headers.has("Sunset")) {
  // Route dépréciée : à migrer vers /v2 avant la date de retrait
  console.warn(`Route dépréciée : ${url}`, res.headers.get("Sunset"), res.headers.get("Link"));
}