L'URL de base
Tous les services sont servis en HTTPS, sous un même préfixe versionné :
https://geoservice.example.com/v2
L'adresse définitive vous sera communiquée par Galigeo. Dans cette documentation, geoservice.example.com la remplace dans tous les exemples.
Les routes de l'ancien GeoService, sous /services/…, sont dépréciées : n'y branchez pas de nouvelle intégration, et suivez le guide de migration pour les autres.
| Préfixe | Service | Moteur |
|---|---|---|
/v2/routing/… | Itinéraires, matrices, isochrones | Valhalla |
/v2/geocoding/osm/… | Géocodage OpenStreetMap | Nominatim |
/v2/geocoding/ban/… | Géocodage Base Adresse Nationale | addok |
/v2/health | État du service | — |
Authentification par clé d'API
Chaque appel doit porter votre clé d'API, fournie par Galigeo. Deux façons de la transmettre :
| Méthode | Exemple | Quand l'utiliser |
|---|---|---|
En-tête X-API-Key | X-API-Key: votre-clé | Recommandé dans tous les cas où vous maîtrisez les en-têtes. |
Paramètre api_key | ?api_key=votre-clé | Quand l'outil appelant ne permet pas d'ajouter d'en-tête. La clé est retirée avant l'appel au moteur. |
Sans clé, ou avec une clé invalide, le service répond 401 avec le code unauthorized. Seul /v2/health est accessible sans clé.
Gardez votre clé côté serveur. Une clé placée dans le code d'une page web ou d'une application mobile est lisible par n'importe qui. Faites transiter les appels par votre propre serveur, et ne versionnez jamais la clé dans un dépôt de code.
Clé exposée par erreur ? Prévenez Galigeo pour la remplacer.
Préférez l'en-tête au paramètre. Une URL finit souvent dans les journaux, l'historique du navigateur ou les outils de supervision ; un en-tête, rarement.
Votre première requête
Calculons un itinéraire en voiture entre l'Hôtel de Ville de Paris et le parvis de Notre-Dame. Définissez d'abord votre clé dans une variable d'environnement, par exemple export GEOSERVICE_KEY=votre-clé.
curl "https://geoservice.example.com/v2/routing/route" \
-H "X-API-Key: $GEOSERVICE_KEY" \
-H "Content-Type: application/json" \
-d '{
"locations": [
{"lat": 48.855199, "lon": 2.354035},
{"lat": 48.853138, "lon": 2.349185}
],
"costing": "auto",
"directions_options": {"units": "kilometers", "language": "fr-FR"}
}'
const res = await fetch("https://geoservice.example.com/v2/routing/route", {
method: "POST",
headers: { "X-API-Key": process.env.GEOSERVICE_KEY, "Content-Type": "application/json" },
body: JSON.stringify({
locations: [
{ lat: 48.855199, lon: 2.354035 },
{ lat: 48.853138, lon: 2.349185 },
],
costing: "auto",
directions_options: { units: "kilometers", language: "fr-FR" },
}),
});
const { trip } = await res.json();
console.log(`${trip.summary.length} km, ${Math.round(trip.summary.time / 60)} min`);
import os
import httpx
r = httpx.post(
"https://geoservice.example.com/v2/routing/route",
headers={"X-API-Key": os.environ["GEOSERVICE_KEY"]},
json={
"locations": [
{"lat": 48.855199, "lon": 2.354035},
{"lat": 48.853138, "lon": 2.349185},
],
"costing": "auto",
"directions_options": {"units": "kilometers", "language": "fr-FR"},
},
)
r.raise_for_status()
summary = r.json()["trip"]["summary"]
print(f"{summary['length']} km, {round(summary['time'] / 60)} min")
{
"trip": {
"locations": [
{"type": "break", "lat": 48.855199, "lon": 2.354035, "original_index": 0},
{"type": "break", "lat": 48.853138, "lon": 2.349185, "original_index": 1}
],
"legs": [{
"maneuvers": [
{"type": 2, "instruction": "Conduisez vers le nord-ouest sur Rue de l'Hôtel de Ville.", "time": 5.651, "length": 0.015},
{"type": 10, "instruction": "Tournez à droite dans Rue de Brosse.", "time": 34.211, "length": 0.079},
…
],
"shape": "me{d|AortnCsAzDcA~CaB{AuNaM}BHkBBwIaEyAe…"
}],
"summary": {"time": 321.438, "length": 1.185, "has_toll": false, "has_highway": false},
"status_message": "Found route between points",
"status": 0,
"units": "kilometers",
"language": "fr-FR"
}
}
1,185 km, parcourus en 321 secondes (environ 5 minutes 21 secondes). La géométrie shape est une polyligne encodée : voir décoder la géométrie.
Lire les réponses
Le GeoService transmet la réponse du moteur telle quelle : corps, code HTTP et type de contenu. Le format de chaque service est celui documenté par son moteur, et les exemples de cette documentation sont des réponses réelles.
En-têtes utiles
| En-tête | Rôle |
|---|---|
Content-Type | Celui du moteur : application/json le plus souvent, text/csv pour le géocodage de fichiers, application/problem+json pour les erreurs du service. |
X-GGO-Upstream | Identifie le moteur qui a répondu, par exemple routing:a. À joindre à toute demande de support. |
Content-Encoding | Les réponses sont compressées (gzip ou brotli) si votre client l'accepte via Accept-Encoding. curl : option --compressed. |
Deux familles d'erreurs
Une erreur du service (clé invalide, route inconnue, moteur indisponible) arrive au format standard application/problem+json. Une erreur du moteur (paramètre invalide, itinéraire introuvable) arrive dans le format propre au moteur. Tout est détaillé dans Erreurs.
Coordonnées et unités
Chaque moteur suit ses propres conventions. La principale source d'erreurs est l'ordre latitude / longitude : en GeoJSON, la longitude vient en premier.
| Où | Forme | Exemple |
|---|---|---|
| Requêtes d'itinéraires | Objets nommés | {"lat": 48.8552, "lon": 2.3540} |
| Paramètres d'URL | Deux paramètres | lat=48.8240&lon=2.3584 |
GeoJSON (BAN, isochrones, OSM format=geojson) | Longitude d'abord | "coordinates": [2.358434, 48.824031] |
Réponses OSM jsonv2 | Chaînes de caractères | "lat": "48.8240267", "lon": "2.3584248" |
Géométrie d'itinéraire shape | Polyligne encodée, précision 6 | "me{d|AortnC…" |
Toutes les coordonnées sont en WGS 84 (EPSG:4326). Les réponses de la BAN ajoutent aussi x et y en Lambert 93 (EPSG:2154).
| Grandeur | Unité |
|---|---|
Durées des itinéraires et matrices (time) | secondes |
Distances des itinéraires et matrices (length, distance) | kilomètres par défaut, miles avec "units": "miles" |
Contours d'isochrone (contours[].time) | minutes |
Contours d'isodistance (contours[].distance) | kilomètres |
Distance au point en géocodage inverse BAN (distance) | mètres |
Vérifier l'état du service
Interroge les trois moteurs (et hexodos là où il est ouvert) et renvoie 200 si tous répondent, 503 sinon, avec "status": "degraded" et le détail par service. Pratique pour une sonde de supervision ou pour vérifier une panne avant de contacter le support.
{
"status": "up",
"services": {
"routing": {"instance": "a", "status": "up", "http_status": 200, "latency_ms": 3},
"geocoding_osm": {"instance": "a", "status": "up", "http_status": 200, "latency_ms": 3},
"geocoding_ban": {"instance": "a", "status": "up", "http_status": 200, "latency_ms": 37}
}
}