Aller au contenu

Lieux

Chaque requête nécessite une clé API; voir Authentification.

curl "https://api.unmap.dev/places/nearby?category=boulangerie&near=-114.07,51.04&key=$UNMAP_API_KEY"
GET /places/searchtrouver des lieux par nom
GET /places/nearbylieux d'une catégorie près d'un point
GET /places/{id}un lieu, par un identifiant que vous détenez déjà

/geocode/nearby est un point de terminaison distinct sur les mêmes enregistrements. Lieux est une présentation de premier plan des enregistrements de points d'intérêt que le corpus de géocodage porte déjà, non un second entrepôt.

La couverture reste le Canada. Un q absent sur /places/search donne un 400 { "error": "q is required", "code": "bad_request" }. Un coin de bbox hors du WGS84 donne un 400 { "error": "longitude is -180..180 and latitude -90..90", "code": "bad_request" }. Un cadre hors du Canada reste un filtre : aucun résultat donne une liste vide, et non outside_coverage. Sur /places/nearby, ce contrôle WGS84 est le même 400, et un ancrage hors du Canada, ou un bbox dont le centre est hors du Canada, donne un 422 { "error": "outside Canadian coverage", "code": "outside_coverage" }. Le corpus n'est pas interrogé.

Paramètres

GET /places/search

ParamètreObligatoireSignification
qouiRequête de nom de lieu non vide.
limitnonEntier de 1 à 50, défaut 10. Une valeur invalide donne 400 bad_request.
langnonLangue préférée de name, défaut en. names conserve toutes les langues disponibles.
bboxnonminlng,minlat,maxlng,maxlat. Filtre strict : les résultats hors du cadre sont exclus.

GET /places/nearby

ParamètreObligatoireSignification
categoryoui1 à 8 identifiants de taxonomie ou alias anglais/français, séparés par des virgules.
nearun ancragelng,lat. Envoyez exactement un de near ou bbox.
bboxun ancrageminlng,minlat,maxlng,maxlat. Utilise le centre et un rayon couvrant le cadre, sans découper les résultats au rectangle.
radiusnonMètres, ramenés à 50–50 000. Défaut 5 000 avec near, ou rayon dérivé du cadre avec bbox. Un rayon explicite remplace la valeur dérivée.
limitnonEntier de 1 à 50, défaut 10. Une valeur invalide donne 400 bad_request.
langnonLangue préférée de name, défaut en.

GET /places/{id}

id est l'identifiant opaque retourné par une réponse Lieux. Encodez-le comme segment de chemin. lang est optionnel, avec défaut en. Retourne { data: place, meta }; search et nearby retournent { data: place[], meta }, dont un tableau vide si aucun lieu ne correspond. Voir Réponse pour les champs et Lacunes connues pour la stabilité des identifiants.

Ce que /places/search ajoute à /geocode/search

Il retourne des lieux. /geocode/search trouve ce qui correspond le mieux à votre requête, ce qui pour « Calgary » est la ville elle-même : la bonne réponse pour un géocodeur, la mauvaise quand vous cherchiez un endroit où aller.

/places/{id} est nouveau

Le géocodeur n'avait aucune recherche par identifiant. Si vous conserviez un résultat, vous n'aviez aucun moyen de le rafraîchir. Maintenant si :

curl "https://api.unmap.dev/places/um:place:1234?key=$UNMAP_API_KEY"

Un identifiant malformé donne un 404 { "error": "not found", "code": "not_found" }, pas un 400. Un identifiant bien formé qui n'est pas dans le corpus est aussi un 404 not_found. Ce message est no such place, or the geocoding container predates /places/{id}. Le statut ne distingue pas les deux cas.

L'identifiant est opaque, et il est stable à l'intérieur d'une version du corpus, pas pour toujours. N'analysez pas sa fin, et ne le traitez pas comme une clé étrangère durable : une reconstruction du corpus peut renuméroter la ligne sous-jacente, donc un identifiant conservé il y a des mois peut cesser de résoudre ou, pire, résoudre vers un autre lieu. Ré-résolvez par nom et coordonnée à intervalle régulier, ou conservez la coordonnée et le nom à côté de l'identifiant pour pouvoir le faire. Une identité de lieu persistante qui survit à une reconstruction n'est pas encore construite; elle figure dans Lacunes connues.

Depuis le SDK

import { Unmap } from "@unmap/sdk";
const unmap = new Unmap({ key: process.env.UNMAP_API_KEY! });
 
const { data, meta } = await unmap.places.nearby("boulangerie", { near: [-73.57, 45.5] });
await unmap.places.search("calgary tower");
await unmap.places.get("um:place:1234");

meta est retourné plutôt qu'escamoté : sans attribution, vous ne pouvez pas respecter la licence sous laquelle les données vous parviennent. Places est aussi exporté par @unmap/geocoding, si vous le voulez sans le reste du SDK.

Les champs que nous n'avons pas

La réponse porte un identifiant, des noms dans chaque langue du corpus, une catégorie, des coordonnées et une adresse. Elle ne porte pas phone, website, opening_hours, accessibility, operator ni un sac d'attributs structuré.

Ces champs sont absents de la réponse, non présents et nuls. La différence est délibérée :

  • "phone": null est une affirmation sur le lieu, et généralement fausse.
  • Une clé absente est une affirmation sur notre couverture, et elle est vraie.

Les chargeurs ne les extraient pas aujourd'hui. Les remplir exige du travail sur les chargeurs et une reconstruction complète du corpus. Couverture dit la même chose.

Réponse

{
  "data": [
    {
      "id": "um:place:1234",
      "source_id": "1234",
      "name": "RBC Royal Bank",
      "names": { "en": "RBC Royal Bank", "fr": "Banque Royale" },
      "category": "finance.bank",
      "category_group": "finance",
      "coordinates": [-114.0676, 51.0447],
      "address": { "housenumber": "339", "street": "8 Avenue SW", "city": "Calgary", "region": "AB" },
      "distance": 313,
      "source": "places.osm-poi"
    }
  ],
  "meta": { "attribution": "(c) OpenStreetMap contributors", "status": "current" }
}

distance n'apparaît que sur /places/nearby. Les parties d'adresse absentes sont omises pour la même raison que les champs absents plus haut.

Catégories

La même taxonomie de 89 catégories qu'utilise /geocode/nearby, avec les alias anglais et français résolus à la passerelle : ?category=boulangerie fonctionne depuis un simple curl. Voir Géocodage pour le tableau complet.

Recharge de véhicules électriques

Les bornes de recharge sont une catégorie de Lieux, non une API distincte :

curl "https://api.unmap.dev/places/nearby?category=ev+charger&near=-114.07,51.05&key=$UNMAP_API_KEY"

transport.charging_station est l'identifiant canonique; ev charger et charging station sont des alias.

La couverture est mince hors des villes, et nous l'avons mesurée plutôt que devinée. Le 2026-09-17, dans un rayon de 25 km autour d'un point du centre-ville : les grandes villes ont atteint le plafond de 50 résultats; Halifax en a retourné 27; le long de la Transcanadienne, Banff 16, Swift Current 3, Kenora 2; Whitehorse 2; Yellowknife et Iqaluit zéro.

L'absence de résultat à Yellowknife relève plus probablement d'un enregistrement manquant que d'une borne manquante, et ce sera la première chose vérifiée contre un inventaire faisant autorité. Le zéro d'Iqaluit est peut-être exact : la ville est hors du réseau routier.

Aucun réseau, type de connecteur, puissance, nombre de bornes, accès ni état. Même raison que les champs ci-dessus : le corpus n'a pas de colonnes pour cela, ils sont donc absents plutôt que nuls.

Aucun inventaire canadien faisant autorité ne se trouve derrière ceci. Le localisateur de RNCan n'est pas publié comme jeu de données sur open.canada.ca, et les jeux de données fédéraux de projets financés listent des projets subventionnés plutôt que des bornes existantes : ils ne servent donc délibérément pas de substitut.

Lacunes connues

  • Aucune déduplication entre sources. Le corpus fusionne les localités, pas les commerces. Une chaîne présente dans deux sources peut apparaître deux fois, et une identité de lieu persistante qui y survivrait n'est pas construite.
  • La couverture est celle d'OpenStreetMap. Dense en ville, mince en milieu rural, et variable d'une rue à l'autre plutôt que selon une règle publiée.
  • /places/{id} exige un conteneur de géocodage à jour. Face à un conteneur plus ancien, il répond 404 et le corps indique que la route peut précéder le déploiement, plutôt que de prétendre que le lieu n'existe pas.

Vous avez trouvé une erreur ? Signalez-la : POST /places/{id}/feedback accepte un signalement portant sur un seul lieu.

Prochaines étapes