API de cartes
Une carte rendue utilise trois choses de la passerelle : des tuiles vectorielles, un document de style qui explique comment les dessiner, et les polices/icônes référencées par ce style. @unmap/sdk et @unmap/maps récupèrent tout cela pour vous. Cette page sert à appeler la passerelle directement, ou à comprendre ce que fait votre carte en coulisse. Si tuile, style et zoom sont des mots nouveaux, le glossaire d'une minute les définit d'abord.
Chaque point de terminaison décrit ici exige une clé. Les tuiles, les glyphes et les sprites l'acceptent uniquement en ?key=, car MapLibre ne peut pas envoyer d'en-têtes sur ces requêtes. Voir Authentification.
Si c'est la carte qui vous intéresse et non les points de terminaison, rien de ceci n'est obligatoire :
Tuiles
GET /tiles/{z}/{x}/{y}
Un carré de données cartographiques. z est le niveau de zoom, x et y sont la colonne et la ligne du carré à ce zoom, donc /tiles/11/375/685 est un morceau du centre-ville de Calgary. Les carrés contiennent des données plutôt qu'une image de carte, au format Mapbox Vector Tile (application/x-protobuf), découpés dans une archive unique couvrant tout le pays des zooms 0 à 14. Un suffixe .pbf ou .mvt sur y est accepté et retiré, car les clients l'ajoutent de façon inconsistante.
curl "https://api.unmap.dev/tiles/11/375/685.mvt?key=$UNMAP_API_KEY" -o tile.mvtconst res = await fetch(`https://api.unmap.dev/tiles/11/375/685.mvt?key=${key}`);
const tile = new Uint8Array(await res.arrayBuffer());Trois choses à savoir :
- Une réponse vide est
204 No Content, pas404. Vous obtenez un 204 au-delà du zoom 14, et aussi à l'intérieur de la plage de zooms partout où l'archive ne contient aucune tuile, c'est-à-dire l'essentiel de l'océan et tout ce qui se trouve hors du Canada. Les deux cas sont un vide légitime et non un échec. Au-delà du zoom 14, MapLibre continue de dessiner en agrandissant la tuile la plus profonde dont il dispose, ce qu'on appelle le surzoom, donc un404serait à la fois faux et bruyant. - Des coordonnées mal formées (
z,xouynon entiers) retournent400avec un corps texte,invalid tile coordinates, et non du JSON. Les requêtes de tuiles, de terrain, de courbes de niveau, de glyphes et de sprites rejettent toutes une entrée mal formée en texte brut; tout le reste de la passerelle répond en JSON. Voir Erreurs. - Une tuile est servie avec
Cache-Control: public, max-age=86400.
Les tuiles sont mises en cache en périphérie avec la chaîne de requête (donc la clé) retirée de la clé de cache, donc la même tuile identique octet pour octet est partagée entre tous les clients plutôt que chacun réchauffant sa copie privée.
Styles
GET /styles/{style}.json?mode=&lang=&theme=&overlays=&profile=
Retourne un document de style MapLibre GL complet (version 8) : sources, couches, et des URL tiles, glyphs et sprite autoréférentielles qui pointent déjà vers cette passerelle, avec votre clé dans leurs chaînes de requête. Pointez MapLibre sur cette seule URL et il découvre le reste tout seul. Passez overlays= pour composer des couches du catalogue canadien, ou une superposition GeoJSON
byod:<id> que vous avez téléversée (voir Apportez vos propres données), ou profile=energy / agriculture / remote / mining pour un préréglage de composition (overlays= explicite remplace la liste du profil). Couches est le catalogue; Énergie, Agriculture, Éloigné et Minier sont les préréglages.
Le voici, animant une vraie carte. Chaque contrôle modifie un seul élément de l'URL :
import { Unmap } from "@unmap/sdk";
const unmap = new Unmap({
key: "um_live_...",
container: "map",
style: "base",
mode: "light",
lang: "fr",
center: [-114.0719, 51.0447],
zoom: 11,
});curl "https://api.unmap.dev/styles/outdoor.json?mode=dark&key=$UNMAP_API_KEY"const res = await fetch(`https://api.unmap.dev/styles/outdoor.json?mode=dark&key=${key}`);
const style = await res.json();{style} est l'un des douze styles ci-dessous. Un nom composé <style>-<mode> fonctionne aussi :
/styles/outdoor-dark.json et /styles/outdoor.json?mode=dark sont la même requête. Un nom non
reconnu retourne 404, en énumérant les noms qui existent :
{
"error": "unknown style",
"styles": ["base", "muted", "outdoor", "blueprint", "blush", "orchid", "canopy", "lagoon", "tropic", "sunset", "bold", "pastel"],
}La forme « ville de démonstration »
Avant que les styles ne soient adressés par leur nom, ce point de terminaison acceptait l'une des
trois villes de lancement et un paramètre ?flavor=. Cette forme fonctionne toujours, et démarre
toujours la carte sur le cadrage de cette ville, afin qu'une URL créée à l'époque continue de
servir une carte :
GET /styles/{city}.json?flavor=&mode=&lang=&theme=
{city} vaut calgary, montreal ou iqaluit. ?flavor= n'est lu que sur cette forme : sur
/styles/{style}.json, le chemin nomme déjà le style et un paramètre flavor y est ignoré.
Préférez la forme par style pour toute nouveauté, et réglez la caméra avec les propres center et
zoom de MapLibre; une ville est un cadrage, pas une autre carte.
Ce que vous recevez
{
"version": 8,
"glyphs": "https://api.unmap.dev/glyphs/2/{fontstack}/{range}.pbf?key=...",
"sprite": "https://api.unmap.dev/sprite/2/light?key=...",
"sources": {
"unmap": {
"type": "vector",
"tiles": ["…/tiles/{z}/{x}/{y}?key=..."],
"maxzoom": 14,
},
"unmap_dem": {
"type": "raster-dem",
"encoding": "terrarium",
"maxzoom": 12,
},
"unmap_contours": { "type": "vector", "minzoom": 9, "maxzoom": 14 },
},
"layers": [
/* la cartographie, dans l'ordre de dessin */
],
"center": [-114.0719, 51.0447],
"zoom": 11,
}unmap est toujours présente. unmap_dem et unmap_contours n'apparaissent que pour outdoor (ce à quoi se résout l'ancien nom relief), et seulement une fois qu'une archive est configurée derrière chacune sur la passerelle ; un style n'annonce jamais une source sans rien derrière. center et zoom donnent une vue de départ (Calgary sur la forme par style, ou la ville nommée sur la forme « ville de démonstration »), donc un document de style est un plan d'ouverture complet et pas seulement une cartographie.
Le document de style lui-même est généré à chaque requête et n'est pas mis en cache en périphérie. Tout ce vers quoi il pointe l'est.
Les douze styles
Un style est l'une des douze cartes structurelles; un mode vaut light ou dark. Chaque style est livré dans les deux, et les deux axes sont indépendants : un nom composé <style>-<mode> et un nom nu accompagné de ?mode= veulent dire la même chose.
base-light(défaut),base-dark: usage général. Hiérarchie routière complète, bâtiments visibles, couverture du sol assez différenciée pour se lire comme un terrain.base-darkrend l'eau plus sombre que la terre, ce qui empêche une carte sombre de s'effondrer en bouillie.muted-light,muted-dark: niveaux de gris de bout en bout, eau et icônes comprises. Conçu pour disparaître sous les données que vous dessinez par-dessus.outdoor-light,outdoor-dark: terrain d'abord, avec un ombrage DEM, des courbes de niveau et des sentiers.blueprint-light,blueprint-dark: une seule famille de bleus. Un champ bleu roi aux routes marine en sombre, des lignes bleues sur papier bleu-blanc en clair.blush-light,blush-dark: terre rose sur fond pêche, bâtiments rose foncé ; lie-de-vin la nuit.orchid-light,orchid-dark: terre lavande, parcs sarcelle, bois menthe et eau ciel.canopy-light,canopy-dark: terre fauve sous des verts de forêt profonds, routes quasi noires, bâtiments argile et eau bleu franc.lagoon-light,lagoon-dark: terre vert pâle, eau aqua, parcs sarcelle, étiquettes grises.tropic-light,tropic-dark: eau sarcelle à pleine force, parcs vert printemps, terre crème, autoroute corail. D'après les palettes Tropic et Temps de CARTO.sunset-light,sunset-dark: un bichrome chaud. Terre crème, végétation pêche, routes corail, eau indigo ; crépuscule en sombre. D'après Sunset de CARTO.bold-light,bold-dark: la carte de rues saturée. Eau bleu franc, parcs vert feuille, bois émeraude, autoroute ambre. D'après Bold et Vivid de CARTO.pastel-light,pastel-dark: terre blanc lavande, eau pervenche, parcs menthe, autoroute saumon. D'après Pastel de CARTO.
Un nom de style nu signifie ce style en mode clair, donc /styles/muted.json est une requête valide.
Les anciens noms se résolvent toujours, au cas où ils seraient déjà codés en dur chez vous : light → base-light, dark → base-dark, street → base-light, relief → outdoor-light, ainsi que les noms Protomaps d'origine white → base-light, grayscale → muted-light et black → base-dark. Ils se résolvent aussi bien dans le chemin que dans ?flavor=.
block, le style pixel art, a été retiré en septembre 2026 et n'a aucun alias : c'est un 404 comme tout autre nom non reconnu, plutôt qu'une carte différente servie silencieusement. street et relief ont été retirés plus tard et s'aliasent sur base et outdoor pour que les URL existantes restent valides.
Mode
Le style et le mode sont deux axes distincts, vous pouvez donc aussi les envoyer séparément :
GET /styles/base.json?mode=dark&lang=en
?mode= choisit la moitié claire ou sombre de ce que le chemin a nommé, et il l'emporte sur un mode porté par le chemin : /styles/base-light.json?mode=dark donne base-dark. Préférez le nom nu accompagné de ?mode= si votre application a une bascule de thème, car changer un seul paramètre vaut mieux que recomposer un nom composé à chaque bascule. Un mode non reconnu est ignoré plutôt que rejeté.
Terrain et courbes de niveau
Le style outdoor, et donc l'ancien nom relief qui s'y résout, ajoute une source raster-dem et, par-dessus, une source vectorielle de courbes de niveau. Vous n'avez normalement pas à les demander vous-même : le document de style porte déjà leurs URL avec votre clé, et MapLibre les requiert au fil du dessin. Elles sont indiquées ici pour que vous puissiez les reconnaître dans un journal réseau :
GET /terrain/4/{z}/{x}/{y}.png?key=... # élévation encodée en terrarium, z0-12
GET /contours/4/{z}/{x}/{y}?key=... # courbes de niveau vectorielles, z9-13
Le nombre est un segment de version d'archive, le même dispositif d'invalidation de cache que celui des chemins de glyphes et de sprites plus bas. Les formes non versionnées, /terrain/{z}/{x}/{y}.png et /contours/{z}/{x}/{y}, restent servies pour les styles intégrés avant l'existence du segment ; un style récupéré aujourd'hui émet la paire versionnée.
Le terrain répond en image/png, les courbes de niveau en application/x-protobuf, et les deux sont mises en cache comme les tuiles. Hors de leur plage de zooms, et partout à l'intérieur sans données, elles répondent 204 pour la même raison qu'une tuile vectorielle. Un 404, dont le corps JSON nomme l'archive manquante, signifie que l'archive derrière cette source n'est pas configurée du tout, ce qui est un problème côté serveur et non une lacune de couverture.
La couverture du terrain est pancanadienne. L'élévation derrière outdoor est le MRDEM de 30 m
de RNCan, tuilé jusqu'au z12 et sur-zoomé au-delà ; il atteint l'archipel arctique et, parce que
la source suit les bassins versants, déborde un peu de l'autre côté de la frontière américaine.
Ce débordement n'est pas une couverture des États-Unis.
Les courbes de niveau sont une aide à la lecture du terrain dérivée d'un modèle d'élévation d'environ 20 m. Ce n'est pas un produit d'arpentage, et cela ne convient pas à la navigation.
Thèmes personnalisés
?theme= transporte un code de thème produit par le créateur de thèmes. Un thème est purement des données : des couleurs, quelques nombres bornés et un nom de style. Il remplace les couleurs qu'aurait utilisées le style, donc il l'emporte sur le style nommé par le chemin.
Les codes existent sous deux formes. Un style, un préréglage nommé ou des couleurs de départ personnalisées tiennent dans un code court u… de quelques caractères ; un thème dont les couleurs ont été retouchées à la main au-delà de cela retombe sur un document ut1., du base64url d'un corps JSON compressé en deflate.
GET /styles/base.json?theme=ut1.eJyrVipTsjLUUcpLzE1VslIqLilKTS1R0lFKSixG4tcCAOvhDGQ&key=...
Les deux formes se passent dans le même paramètre, et les deux arrivent à @unmap/sdk comme l'option theme :
import { Unmap } from "@unmap/sdk";
const unmap = new Unmap({
key: "um_live_...",
container: "map",
theme: "u4e",
center: [-114.0719, 51.0447],
zoom: 12,
});?mode= choisit toujours la moitié du thème que vous recevez, et un mode non reconnu retombe sur light. Le terrain et les sprites suivent le style sous-jacent du thème, donc un thème bâti sur outdoor conserve son ombrage.
Un thème peut aussi masquer ou réordonner les sept grands groupes de couches (sol, eau, bâtiments, routes, frontières, bâtiments 3D, étiquettes) pour les deux modes à la fois. C'est le panneau Couches de la carte du créateur ; sur le fil, c'est un seul champ layers fait de booléens et d'une liste ordonnée, et les groupes masqués sont simplement absents du style que vous recevez. Les bâtiments 3D sont le seul groupe désactivé par défaut : une fill-extrusion composée à partir des hauteurs de bâtiments des tuiles, dans la couleur des bâtiments du thème.
Un code invalide est rejeté franchement avec un 400, contrairement à un ?mode= non reconnu :
{
"error": "invalid theme",
"code": "invalid_theme",
"detail": ["code is not valid base64url deflate data"],
}C'est délibéré. Les thèmes sont assez récents pour n'avoir aucune URL codée en dur à préserver, et un thème ignoré en silence est la pire réponse possible pour quelqu'un qui itère dans le créateur. detail nomme les chemins de champs fautifs lorsque le code se décode mais échoue à la validation.
Un style thématisé porte aussi le style résolu du marqueur et de l'itinéraire dans ses metadata, pour qu'un client ayant déjà chargé le style puisse dessiner ses calques aux couleurs du thème sans décoder le code lui-même :
"metadata": {
"unmap:theme": {
"marker": { "color": "#FF3E9A", "scale": 1 },
"route": { "color": "#FF3E9A", "width": 3, "opacity": 1,
"casingColor": "#FF3E9A", "casingWidth": 10, "casingOpacity": 0.2 }
}
}metadata est absent lorsque vous demandez un style plutôt qu'un thème.
Langue des libellés
Le paramètre ?lang= définit la langue des libellés :
GET /styles/base.json?mode=light&lang=fr&key=...
Sans lang, la passerelle lit Accept-Language, donc une carte intégrée s'affiche dans la langue du lecteur sans que la page hôte ait à le demander. Un tag complet se résout par son sous-tag principal, donc fr-CA vous donne le français. Un code non pris en charge retombe sur l'anglais plutôt que d'émettre en silence un tag que les tuiles ne portent pas.
L'anglais et le français sont tous deux présents dans l'extrait canadien : 31 entités diffèrent dans une seule tuile de Montréal, dont Nuns' Island et L'Île-des-Sœurs.
Les noms autochtones ne sont pas un code lang, et il ne faut pas en demander un. Il n'y a pas de name:iu dans les tuiles. Ces noms voyagent sur l'entité elle-même, donc Iqaluit arrive comme Iqaluit avec ᐃᖃᓗᐃᑦ à côté, et le libellé rend les deux lignes quelle que soit la langue demandée. Ailleurs, le nom syllabique est le principal et l'anglais le secondaire. Rien n'a besoin d'être activé.
Polices et sprites
Les glyphes sont les formes de lettres avec lesquelles MapLibre dessine les étiquettes, et une feuille de sprites est l'image unique qui contient toutes les icônes d'un style. Les URL glyphs et sprite du style pointent elles aussi vers la passerelle, pas vers un hébergeur d'actifs tiers. Vous ne les appellerez normalement pas vous-même, MapLibre les demande automatiquement dès que vous fixez l'URL du style. Elles suivent la même règle d'authentification que les tuiles : la clé voyage en ?key=, car MapLibre ne peut pas non plus envoyer d'en-têtes sur ces requêtes.
GET /glyphs/{version}/{fontstack}/{range}.pbf?key=...
GET /sprite/{version}/{file}?key=... # file est <feuille>[@2x].(json|png)
Le style donne à MapLibre l'URL du sprite sans extension (/sprite/2/light) et MapLibre ajoute lui-même .json, .png et @2x. Quatre feuilles existent : light, dark, et les désaturées muted-light et muted-dark. Les icônes de POI sont des sprites matriciels colorés par feuille, donc muted, qui est en niveaux de gris jusqu'à ses icônes, a besoin de ses propres feuilles ; tout autre style emprunte la feuille correspondant à son mode, car les icônes varient autrement selon le mode et non selon le style.
Les polices sont les piles Noto Sans, et chacune fusionne plusieurs fontes sources plutôt que de couvrir une seule écriture. Noto Sans Regular contient déjà le syllabaire autochtone canadien unifié, donc ᐃᖃᓗᐃᑦ se rend en texte plutôt qu'en cases vides. Il n'existe pas de famille Noto Sans Canadian Aboriginal distincte à demander; en réclamer une retourne un 404, car rien n'est stocké sous ce nom.
Les chemins /glyphs/ et /sprite/ portent un segment de version d'actif. Il n'adresse rien, l'objet sous-jacent est le même, et il existe uniquement pour qu'une police réécrite obtienne une nouvelle URL, car ces réponses sont servies immutable pendant un an et le cache est indexé sur le chemin. La version est actuellement 2. Les formes non versionnées, /glyphs/{fontstack}/{range}.pbf et /sprite/{file}, restent servies pour les styles intégrés dans des pages avant l'existence du segment. Utilisez les chemins versionnés dans tout nouveau code; un style récupéré aujourd'hui le fait déjà.
Une plage de glyphes ou une feuille de sprites manquante retourne un 404 en texte brut, pas un 500 : MapLibre encaisse une lacune de couverture, mais un 5xx ici pourrait faire tomber toute la carte. Une pile de polices, une plage, un nom de sprite ou un segment de version mal formés retournent un 400 en texte brut.
Les glyphes et les sprites sont authentifiés et soumis à la limite de débit comme le reste, mais ils ne sont pas comptabilisés. Un seul chargement de carte tire de nombreuses plages de glyphes, et les compter noierait votre usage réel tout en pénalisant les cartes denses en libellés.
Prochaines étapes
- Le Guide de démarrage affiche une carte issue de ces points de terminaison en deux instructions.
- Composez votre propre cartographie sur /create et passez le code comme
?theme=. - L'API de géocodage et l'API d'itinéraires pour ce qui se pose par-dessus.