Developer API
Create and manage DropMaps layers and maps programmatically over a simple REST API.
DropMaps has a small REST API for creating and managing layers and maps from your own code — handy for syncing a database to a map, bulk-importing features, or wiring DropMaps into a pipeline.
The API is a Pro/Team feature. Reads work on any plan, but creating cloud layers and maps requires a paid plan (it uses your cloud storage quota).
- Base URL:
https://api.dropmaps.net/v1 - Format: JSON in, JSON out (
application/json) - All data is stored and returned in WGS84 (EPSG:4326) — see Coordinate systems.
Authentication
Authenticate with a Personal Access Token in the Authorization header:
Authorization: Bearer dmp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Create a token in the DropMaps app under Account → Access tokens. The token is shown once — store it securely. A token has the same access as your account; revoke it any time from the same screen.
Create a layer
POST /v1/layers — send GeoJSON; DropMaps encodes and stores it for you.
curl -X POST https://api.dropmaps.net/v1/layers \
-H "Authorization: Bearer dmp_…" \
-H "Content-Type: application/json" \
-d '{
"name": "Sites",
"geojson": {
"type": "FeatureCollection",
"features": [
{ "type": "Feature",
"geometry": { "type": "Point", "coordinates": [151.2, -33.86] },
"properties": { "label": "HQ" } }
]
},
"metadata": { "category": "Facilities" }
}'
Returns the created layer:
{ "id": "lyr_…", "name": "Sites", "geometryType": "Point", "sourceKind": "geojson",
"featureCount": 1, "sizeBytes": 312, "version": 0, "snapshotSeq": 1, "hasData": true,
"style": null, "schema": null, "metadata": { "category": "Facilities" },
"createdAt": "…", "updatedAt": "…" }
GeoJSON must be WGS84 lon/lat (the GeoJSON standard). The request body is capped at 12 MB —
for larger datasets, create the layer then upload pre-encoded FlatGeobuf to PUT /v1/layers/{id}/data
(see below).
Layer endpoints
| Method | Path | Description |
|---|---|---|
GET | /v1/layers | List your layers |
POST | /v1/layers | Create a layer from GeoJSON |
GET | /v1/layers/{id} | Layer metadata |
PATCH | /v1/layers/{id} | Update name, style, or metadata |
DELETE | /v1/layers/{id} | Delete the layer and its data |
GET | /v1/layers/{id}/data?format=geojson|fgb | Download features (GeoJSON default, or FlatGeobuf) |
PUT | /v1/layers/{id}/data | Replace features — GeoJSON body, or raw FlatGeobuf with Content-Type: application/octet-stream |
Styling and labels
A layer’s appearance is the style object you pass to POST /v1/layers or
PATCH /v1/layers/{id}. It’s the same style DropMaps uses internally, so the easiest way to get a
valid object is to style a layer in the app, Export → GeoJSON, and copy the dropmaps member out
of the file. The common fields:
- Fill & stroke:
color,fillOpacity,strokeColor,strokeOpacity,strokeWidth,noFill,noOutline,lineDashArray; for pointspointSizeandpointShape. - Labels:
labelField(the property to show),labelSize,labelColor,labelHaloColor,labelHaloWidth,labelAnchor,labelPlacement(point|line),labelOffsetX/labelOffsetY, andlabelMinZoom/labelMaxZoom. - Thematic styling:
styleMode(single|categorized|graduated) withcategoryField+categoryBreaks, orrangeBreaksfor graduated. - Popups & table:
popupsEnabled,popupTitle,popupFields,tableFields.
curl -X PATCH https://api.dropmaps.net/v1/layers/lyr_… \
-H "Authorization: Bearer dmp_…" -H "Content-Type: application/json" \
-d '{ "style": {
"color": "#1f78b4", "strokeColor": "#08519c", "strokeWidth": 1.5,
"labelField": "name", "labelSize": 12, "labelColor": "#222"
} }'
PATCH updates only the fields you send (name, style, metadata); omit the rest.
Create and manage maps
A map composes layers you’ve already created (by id), with per-layer order, visibility, opacity and style overrides.
curl -X POST https://api.dropmaps.net/v1/maps \
-H "Authorization: Bearer dmp_…" -H "Content-Type: application/json" \
-d '{
"name": "Field map",
"basemapId": "dropmaps-voyager",
"layers": [ { "layerId": "lyr_…", "ord": 0, "visible": true } ]
}'
| Method | Path | Description |
|---|---|---|
GET | /v1/maps | List your maps |
POST | /v1/maps | Create a map |
GET | /v1/maps/{id} | Map + layer composition |
PUT | /v1/maps/{id} | Create or replace a map by id (composition is the whole layers array) |
DELETE | /v1/maps/{id} | Delete the map (its layers are kept — they’re independent) |
Layers referenced by a map must belong to your account, or the request is rejected.
Layer order, visibility and per-map style are set on each entry of the map’s layers array:
ord (stacking order — lowest draws first / sits at the bottom), visible, opacity, and
styleOverride (a partial style object that overrides the layer’s own style just on this map).
PUT /v1/maps/{id} replaces the whole composition, so to reorder, re-send layers with new ord
values:
curl -X PUT https://api.dropmaps.net/v1/maps/map_… \
-H "Authorization: Bearer dmp_…" -H "Content-Type: application/json" \
-d '{ "name": "Field map", "layers": [
{ "layerId": "lyr_roads", "ord": 0 },
{ "layerId": "lyr_sites", "ord": 1, "opacity": 0.8,
"styleOverride": { "color": "#e31a1c" } }
] }'
Fields (attributes)
Feature attributes are GeoJSON properties. Add, rename or drop them across every feature in one
call with POST /v1/layers/{id}/fields, passing an ops array applied in order:
curl -X POST https://api.dropmaps.net/v1/layers/lyr_…/fields \
-H "Authorization: Bearer dmp_…" -H "Content-Type: application/json" \
-d '{ "ops": [
{ "op": "add", "name": "status", "default": "new", "type": "string" },
{ "op": "rename", "from": "lbl", "to": "label" },
{ "op": "drop", "name": "temp" }
] }'
- add —
name, optionaldefault(set only where the field is missing, so it never overwrites real data) and optionaltype(recorded infieldTypes). - rename —
from→to. - drop —
name.
The layer’s field config (fieldTypes, fieldFormats, tableFields, popupFields) is updated to
match, so the app shows the right columns afterwards. Reserved internal fields (names starting with
__) can’t be modified. This decodes and re-encodes the layer in memory, so it’s limited to layers
up to ~8 MB stored — for larger datasets, re-upload the whole set via PUT /v1/layers/{id}/data
(add a property key to add a field, drop it to remove, rename it to rename).
You can also describe fields without changing the data, via the layer’s style object:
fieldTypes— advisory typing, e.g.{ "height": "number", "surveyed": "date" }(drives editors, sorting and new-feature defaults).fieldFormats— display formatting for numbers/dates/booleans (the stored value is untouched).tableFields/popupFields— which columns appear (and their order) in the attribute table and popups.
Errors
Errors use a single shape and standard HTTP status codes:
{ "error": { "code": "subscription_required",
"message": "A paid DropMaps plan is required to create cloud layers and maps via the API." } }
Common codes: unauthorized (401), subscription_required (402), not_found (404),
payload_too_large (413), quota_exceeded (413), limit_reached (409), invalid_request /
invalid_geojson (400).
Limits
- Body size for GeoJSON ingestion: 12 MB (upload FlatGeobuf for larger).
- Storage is metered against your plan’s quota, the same as layers created in the app.
- Tokens, layers and maps have per-account ceilings (you’ll get a
limit_reachederror well beyond normal use).
Notes
- Server-side ingestion is GeoJSON today. Shapefile / GeoPackage / File Geodatabase conversion isn’t available over the API — convert to GeoJSON or FlatGeobuf first (the app and QGIS plugin can do this), then upload.
- Anything you create via the API appears in the DropMaps app and the QGIS plugin like any other cloud layer or map.