Démarrage rapide : piloter une salle avec cURL
Voici le guide « donnez-moi juste les commandes » pour tout faire dans une seule salle en HTTP avec
un jeton limité à cette salle (cmap_…) — sans session de navigateur ni connexion utilisateur. Pour la
liste complète des points de terminaison, voir la Référence.
1. Obtenir un jeton
Section intitulée « 1. Obtenir un jeton »Émettez un jeton en tant que propriétaire de la salle — dans l’application (Mes salles → bouton API sur la carte de la salle) ou en HTTP avec votre JWT de propriétaire. Voir Jetons d’API de salle pour les détails.
curl -X POST "$API/api/rooms/$ROOM/api-tokens" \ -H "Authorization: Bearer $JWT" -H "Content-Type: application/json" \ -d '{"name":"my-script","permissions":["read","write","upload"],"expiresInDays":30}'# → { "token": "cmap_…", "id": "…" }2. Préparer votre shell
Section intitulée « 2. Préparer votre shell »export API=https://collmap.com # production (use http://localhost:3001 for local dev)export ROOM=aB3dEfGhIj # the 10-char room id — it's in the map URL: /map/<ROOM>export TOKEN=cmap_xxxxxxxxxxxx # your room tokenAUTH="Authorization: Bearer $TOKEN"(Les exemples passent par jq pour la lisibilité — facultatif.)
3. Vérification rapide
Section intitulée « 3. Vérification rapide »curl -s "$API/api/rooms/$ROOM" -H "$AUTH" | jq . # → room metadata (200) for a read token- 200 → tout est branché.
- 403 « API token is not scoped to this room » →
$ROOMne correspond pas à la salle du jeton. - 403 « API token lacks ‘read’ permission » → réémettez le jeton en incluant
read.
4. Envoyer des données dans la salle
Section intitulée « 4. Envoyer des données dans la salle »Importer une couche vectorielle upload
Section intitulée « Importer une couche vectorielle »GeoJSON, shapefile compressé ou GeoPackage. Le traitement vectoriel volumineux est asynchrone → vous
recevez un jobId.
curl -X POST "$API/api/layers/upload" -H "$AUTH" \ -F "roomName=$ROOM" -F "layerName=my-layer" -F "file=@data/my-layer.geojson"# → { "jobId": "job-…", ... } then poll:curl -s "$API/api/layers/jobs/<jobId>" -H "$AUTH" | jq '{stage,progress,message}'Importer un GeoTIFF upload
Section intitulée « Importer un GeoTIFF »Même point de terminaison ; un .tif/.tiff est dirigé vers le pipeline raster. Définissez le rendu
dès le départ :
# single-band: colormap + stretchcurl -X POST "$API/api/layers/upload" -H "$AUTH" \ -F "roomName=$ROOM" -F "layerName=elevation" -F "file=@data/dem.tif" \ -F 'display={"colormap":"terrain","band":1,"vmin":0,"vmax":1500,"opacity":0.8}'
# multi-band: an RGB compositecurl -X POST "$API/api/layers/upload" -H "$AUTH" \ -F "roomName=$ROOM" -F "layerName=truecolor" -F "file=@data/scene.tif" \ -F 'display={"renderMode":"rgb","rgbBands":[1,2,3]}'Ajouter un repère unique write
Section intitulée « Ajouter un repère unique »Synchrone — renvoie le repère créé avec son identifiant.
curl -X POST "$API/api/rooms/$ROOM/markers" -H "$AUTH" -H "Content-Type: application/json" \ -d '{"latitude":47.5596,"longitude":7.5886,"title":"Site A","description":"first visit","tags":["survey"]}'# → 201 { "success": true, "marker": { "id": "marker-…", ... } }Seuls latitude/longitude sont obligatoires. Facultatifs : title, description, color
(hexadécimal), tags, eventDate (epoch ms), markerIconId, markerIconSize,
imageKey/thumbnailKey, embeddedMediaUrl, mediaSize.
Modifier ou supprimer un repère write
Section intitulée « Modifier ou supprimer un repère »# read one backcurl -s "$API/api/rooms/$ROOM/markers/$MARKER" -H "$AUTH" | jq '.marker.title'
# change only what you name; null clears a fieldcurl -X PATCH "$API/api/rooms/$ROOM/markers/$MARKER" -H "$AUTH" -H "Content-Type: application/json" \ -d '{"title":"Site A (revisited)","description":null,"color":"#ef4444"}'
curl -X DELETE "$API/api/rooms/$ROOM/markers/$MARKER" -H "$AUTH"# → 200 { "success": true, "markerId": "marker-…" }latitude, longitude, title et color peuvent être modifiés mais pas effacés ; imageKey et
thumbnailKey doivent être envoyés ensemble. Un corps vide est rejeté avec empty_update. Les deux
appels se voient en direct dans les navigateurs ouverts et atterrissent dans l’historique de la salle.
Ajouter des repères en masse depuis un GeoJSON de points write
Section intitulée « Ajouter des repères en masse depuis un GeoJSON de points »curl -X POST "$API/api/rooms/$ROOM/bulk-import" -H "$AUTH" -F "file=@data/points.geojson"# → { "jobId": "bulk-import-…" }; poll: curl -s "$API/api/jobs/<jobId>" -H "$AUTH" | jq .Créer une couche depuis un GeoJSON en ligne write
Section intitulée « Créer une couche depuis un GeoJSON en ligne »curl -X POST "$API/api/rooms/$ROOM/layers" -H "$AUTH" -H "Content-Type: application/json" \ -d '{"name":"drawn","description":"study area","geojson":{"type":"FeatureCollection","features":[]}, "color":"e11d48","opacity":0.35,"strokeWeight":3,"visible":true}'5. Relire les données
Section intitulée « 5. Relire les données »curl -s "$API/api/layers/$ROOM" -H "$AUTH" | jq '.layers[].name' # layerscurl -s "$API/api/rooms/$ROOM/markers" -H "$AUTH" | jq '.count' # markerscurl -s "$API/api/rooms/$ROOM/raster-layers" -H "$AUTH" | jq '.rasterLayers[] | {id,name,display}'6. Commentaires readwrite
Section intitulée « 6. Commentaires »curl -s "$API/api/rooms/$ROOM/comments?resolved=false" -H "$AUTH" | jq '.comments[].body'curl -X POST "$API/api/rooms/$ROOM/comments" -H "$AUTH" -H "Content-Type: application/json" \ -d '{"objectId":"marker-1","objectType":"marker","body":"needs review","lat":47.56,"lng":7.59}'7. Changer le rendu d’un raster write
Section intitulée « 7. Changer le rendu d’un raster »curl -X PATCH "$API/api/rooms/$ROOM/raster-layers/<layerId>/display" \ -H "$AUTH" -H "Content-Type: application/json" \ -d '{"colormap":"viridis","band":1,"vmin":0,"vmax":3000}'8. Export / import readwrite
Section intitulée « 8. Export / import »curl -X POST "$API/api/rooms/$ROOM/export" -H "$AUTH" -H "Content-Type: application/json" -d '{}' -o room.gpkgcurl -X POST "$API/api/rooms/$ROOM/import" -H "$AUTH" -F "file=@room.gpkg" # ≤ 2 GiBGrandes salles : sondez avec GET /api/rooms/$ROOM/export-size, puis utilisez les
tâches d’export asynchrones.
9. La solution de facilité : le script d’import
Section intitulée « 9. La solution de facilité : le script d’import »scripts/import_geo_data.mjs détecte les formats, découpe les gros fichiers et suit les tâches pour
vous :
COMAP_API_TOKEN=$TOKEN node scripts/import_geo_data.mjs --room $ROOM data/my-folderCOMAP_API_TOKEN=$TOKEN node scripts/import_geo_data.mjs --room $ROOM points.csv imagery.tiffnode scripts/import_geo_data.mjs --room $ROOM --dry-run data/my-folder # preview only10. Dépannage
Section intitulée « 10. Dépannage »| Symptôme | Cause → correctif |
|---|---|
403 api_token_not_allowed sur un point de terminaison de données |
Vous avez appelé un point de terminaison propriétaire/admin (voir ce qu’un jeton ne peut pas faire) ; en production, un nouveau déploiement peut ne pas être encore actif |
403 « API token is not scoped to this room » |
roomName/$ROOM ≠ la salle du jeton |
403 « API token lacks 'X' permission » |
Réémettez le jeton en incluant la permission X |
401 Invalid or expired API token |
Jeton révoqué/expiré — émettez-en un nouveau |
413 quota_exceeded |
Le plafond de stockage du propriétaire de la salle est atteint — libérez de l’espace ou changez de forfait |
413 file_too_large |
Fichier > 50 Mo en une requête — utilisez le script d’import / l’envoi par blocs |

