Avvio rapido: pilotare una stanza con cURL
Questa è la guida «dammi solo i comandi» per fare tutto in una sola stanza via HTTP con un token
limitato a quella stanza (cmap_…) — senza sessione di browser, senza login utente. Per l’elenco
completo degli endpoint vedi il Riferimento.
1. Ottenere un token
Sezione intitolata “1. Ottenere un token”Emetti un token come proprietario della stanza — nell’app (Le mie stanze → pulsante API sulla scheda della stanza) oppure via HTTP con il tuo JWT da proprietario. Vedi Token API della stanza per i dettagli.
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. Preparare la shell
Sezione intitolata “2. Preparare la 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"(Gli esempi passano per jq per leggibilità — facoltativo.)
3. Verifica rapida
Sezione intitolata “3. Verifica rapida”curl -s "$API/api/rooms/$ROOM" -H "$AUTH" | jq . # → room metadata (200) for a read token- 200 → è tutto collegato.
- 403 «API token is not scoped to this room» →
$ROOMnon corrisponde alla stanza del token. - 403 «API token lacks ‘read’ permission» → riemetti il token includendo
read.
4. Inviare dati nella stanza
Sezione intitolata “4. Inviare dati nella stanza”Caricare un livello vettoriale upload
Sezione intitolata “Caricare un livello vettoriale ”GeoJSON, shapefile compresso o GeoPackage. L’elaborazione vettoriale più grande è asincrona → ricevi 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}'Caricare un GeoTIFF upload
Sezione intitolata “Caricare un GeoTIFF ”Stesso endpoint; un .tif/.tiff viene instradato alla pipeline raster. Imposta subito la resa:
# 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]}'Aggiungere un singolo segnaposto write
Sezione intitolata “Aggiungere un singolo segnaposto ”Sincrono — restituisce il segnaposto creato con il suo id.
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-…", ... } }Solo latitude/longitude sono obbligatori. Facoltativi: title, description, color
(esadecimale), tags, eventDate (epoch ms), markerIconId, markerIconSize,
imageKey/thumbnailKey, embeddedMediaUrl, mediaSize.
Aggiornare o eliminare un segnaposto write
Sezione intitolata “Aggiornare o eliminare un segnaposto ”# 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 e color possono essere modificati ma non azzerati; imageKey e
thumbnailKey vanno inviati insieme. Un corpo vuoto viene rifiutato come empty_update. Entrambe le
chiamate compaiono dal vivo nei browser aperti e finiscono nella cronologia della stanza.
Aggiungere segnaposto in blocco da un GeoJSON di punti write
Sezione intitolata “Aggiungere segnaposto in blocco da un GeoJSON di punti ”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 .Creare un livello da GeoJSON in linea write
Sezione intitolata “Creare un livello da GeoJSON in linea ”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. Rileggere i dati
Sezione intitolata “5. Rileggere i dati”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. Commenti readwrite
Sezione intitolata “6. Commenti ”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. Cambiare la resa di un raster write
Sezione intitolata “7. Cambiare la resa di 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. Esportazione / importazione readwrite
Sezione intitolata “8. Esportazione / importazione ”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 GiBStanze grandi: sonda con GET /api/rooms/$ROOM/export-size, poi usa le
attività di esportazione asincrone.
9. La via facile: lo script di importazione
Sezione intitolata “9. La via facile: lo script di importazione”scripts/import_geo_data.mjs riconosce i formati, suddivide i file grandi e interroga le attività per
te:
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. Risoluzione dei problemi
Sezione intitolata “10. Risoluzione dei problemi”| Sintomo | Causa → soluzione |
|---|---|
403 api_token_not_allowed su un endpoint dati |
Hai colpito un endpoint da proprietario/amministratore (vedi che cosa un token non può fare); in produzione un nuovo deploy potrebbe non essere ancora attivo |
403 «API token is not scoped to this room» |
roomName/$ROOM ≠ stanza del token |
403 «API token lacks 'X' permission» |
Riemetti il token includendo il permesso X |
401 Invalid or expired API token |
Token revocato/scaduto — emettine uno nuovo |
413 quota_exceeded |
Il limite di spazio del proprietario della stanza è esaurito — libera spazio o passa a un piano superiore |
413 file_too_large |
File > 50 MB in una sola richiesta — usa lo script di importazione / il caricamento a blocchi |

