API Reference

This is the complete reference for the GeoMiner REST API. All requests and responses are JSON. All GIS processing operations are asynchronous — you submit a job and poll for the result.

Base URL

http
https://api.mapkmltools.com
ℹ️ All GIS processing endpoints are under /v1/. The Cloudflare Worker proxy routes CPU jobs to one RunPod endpoint and GPU jobs to another — transparently.

Authentication

Pass your API key in the Authorization header as a Bearer token on every request:

http
Authorization: Bearer gm_YOUR_API_KEY
MethodHeader ValueUse Case
Developer API KeyBearer gm_xxxxExternal integrations, SDKs, scripts
Firebase ID TokenBearer eyJhbGci...Logged-in mapkmltools.com users

Errors

All errors return a JSON body with an error string and an HTTP status code.

json — Error Response
{
  "error": "Rate limit exceeded: max 30 requests/minute",
  "status": 429,
  "timestamp": "2024-07-17T15:30:00.000Z"
}
StatusMeaning
400Bad request — missing or invalid parameters
401Unauthorized — missing or invalid API key / token
404Job not found
429Rate limit exceeded
500Internal server error
502Upstream RunPod error

POST /v1/jobs

Submit a new async GIS processing job. Returns a job ID immediately. Poll GET /v1/jobs/:id for the result.

⚠️ GPU actions (segment, detect) must be submitted to POST /v1/cv/jobs instead.

Request Body

FieldTypeRequiredDescription
actionstringrequiredThe GIS operation to perform. See Actions Reference.
object_keystringrequired*The R2 storage key of the input file. Not required for ai_plan.
paramsobjectoptionalAction-specific parameters. See each action for details.
bash
curl -X POST https://api.mapkmltools.com/v1/jobs \
  -H "Authorization: Bearer gm_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "action": "convert",
    "object_key": "inputs/roads.shp",
    "params": { "target_format": "GeoJSON" }
  }'
javascript
const res = await fetch('https://api.mapkmltools.com/v1/jobs', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer gm_YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    action: 'convert',
    object_key: 'inputs/roads.shp',
    params: { target_format: 'GeoJSON' }
  }),
});
const { output } = await res.json();
console.log(output.id); // RunPod job ID
python
import requests

resp = requests.post(
    'https://api.mapkmltools.com/v1/jobs',
    headers={'Authorization': 'Bearer gm_YOUR_API_KEY'},
    json={
        'action': 'convert',
        'object_key': 'inputs/roads.shp',
        'params': {'target_format': 'GeoJSON'},
    }
)
job_id = resp.json()['output']['id']

Response

json
{
  "id": "abc123-runpod-job-id",
  "status": "IN_QUEUE",
  "output": null
}

GET /v1/jobs/:id

Poll the status of a previously submitted CPU job. Call this every 2–5 seconds until status is COMPLETED or FAILED.

bash
curl https://api.mapkmltools.com/v1/jobs/abc123-runpod-job-id \
  -H "Authorization: Bearer gm_YOUR_API_KEY"

Response (Completed)

json
{
  "id": "abc123-runpod-job-id",
  "status": "COMPLETED",
  "output": {
    "job_id": "abc123-runpod-job-id",
    "action": "convert",
    "status": "success",
    "progress": 100.0,
    "download_url": "https://your-r2-bucket.r2.dev/outputs/uuid_roads.geojson?...",
    "data": { "status": "success", "format": "GeoJSON" }
  }
}

POST /v1/cv/jobs

Submit a Computer Vision job to the dedicated GPU endpoint. Only segment and detect actions are accepted here.

⚠️ GPU jobs may take 30–120 seconds to complete as models are loaded into VRAM. Recommended polling interval: 5 seconds.
bash
curl -X POST https://api.mapkmltools.com/v1/cv/jobs \
  -H "Authorization: Bearer gm_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "action": "detect",
    "object_key": "inputs/satellite.tif",
    "params": {
      "prompt": "solar panels.",
      "box_threshold": 0.3
    }
  }'

POST /v1/presigned-upload

Generate a presigned URL to upload a file directly from the browser to Cloudflare R2. This avoids routing large files through the API server.

json — Request Body
{ "filename": "roads.shp" }
json — Response
{
  "upload_url": "https://...r2.cloudflarestorage.com/inputs/uuid_roads.shp?X-Amz-Signature=...",
  "object_key": "inputs/uuid_roads.shp",
  "expires_in": 3600
}

POST /v1/presigned-download

Generate a presigned GET URL for a file already in R2. Use the object_key returned by any completed job.

json — Request Body
{ "object_key": "outputs/uuid_roads.geojson" }
json — Response
{
  "download_url": "https://...r2.cloudflarestorage.com/outputs/uuid_roads.geojson?X-Amz-Signature=...",
  "expires_in": 3600
}

Actions Reference

The action field in your job body determines what GeoMiner does. Here's the complete reference.

action analyze Extract metadata, statistics, and preview from any file ▼

Accepts both vector (Shapefile, GeoJSON, GeoPackage) and raster (GeoTIFF, COG) files. Returns detailed metadata, CRS info, bounding box, band statistics, and auto-generates a preview PNG.

ParamTypeRequiredDescription
No additional params required.
action convert Convert between vector/raster formats ▼
ParamTypeRequiredDescription
target_formatstringrequired"GeoJSON", "GPKG", "Shapefile", "KML", "GTiff"
example
{ "action": "convert", "object_key": "inputs/areas.geojson", "params": { "target_format": "GPKG" } }
action reproject Reproject to a different coordinate reference system ▼
ParamTypeRequiredDescription
target_crsstringrequiredAny EPSG code or proj string, e.g. "EPSG:3857"
action spatial_analysis Buffer, intersect, union, or spatial join ▼
ParamTypeRequiredDescription
operationstringrequired"buffer", "intersect", "union", "spatial_join"
distancenumberbuffer onlyBuffer distance in the file's CRS units
overlay_filestringintersect/unionR2 object key of the overlay layer
join_filestringspatial_joinR2 object key of the join layer
action bandmath Calculate NDVI, NDWI, or NDBI from satellite imagery ▼
ParamTypeRequiredDescription
indexstringrequired"ndvi", "ndwi", "ndbi"
band_mapobjectoptionalMap band names to 1-based band indices. Default: {"red":3,"nir":4,"green":2,"swir":5}
example — NDVI on Sentinel-2
{ "action": "bandmath", "object_key": "inputs/sentinel.tif", "params": { "index": "ndvi", "band_map": { "red": 4, "nir": 8 } } }
action terrain Generate slope map or hillshade from a DEM ▼
ParamTypeRequiredDescription
operationstringrequired"slope" (output in degrees) or "hillshade" (output 0–255 uint8)
action ai_plan Describe your GIS problem, get an executable workflow back ▼

Powered by Llama 3.1 70B via NVIDIA NIM. The model understands all GeoMiner actions and returns a structured array of steps you can execute sequentially.

ParamTypeRequiredDescription
promptstringrequiredPlain English description of what you want to achieve
metadataobjectoptionalFile metadata from a previous analyze job to help the AI understand your data
example response
[
  { "step": 1, "action": "reproject", "params": { "target_crs": "EPSG:4326" } },
  { "step": 2, "action": "spatial_analysis", "operation": "buffer", "params": { "distance": 500 } },
  { "step": 3, "action": "convert", "params": { "target_format": "GeoJSON" } }
]
action geocoding Address conversion and bulk geocoding ▼

Uses the Google Maps Geocoding API to convert between coordinates and formatted addresses.

ParamTypeRequiredDescription
operationstringrequiredOne of: geocode, reverse_geocode, batch_geocode, batch_reverse_geocode, extract_map_links
addressstring*Address text. Required if operation=geocode
lat / lonnumber*Coordinates. Required if operation=reverse_geocode

Batch Geocoding (CSV / XLSX Upload Required)

If using batch_geocode, batch_reverse_geocode, or extract_map_links, you must upload a CSV or XLSX file.

ParamTypeDefaultDescription
address_columnstring"address"Column to read for batch_geocode
lat_column / lon_columnstring"lat" / "lon"Columns to read for batch_reverse_geocode (also auto-detects common names like Latitude/Longitude)
url_columnstring"url"Column to read for extract_map_links

Batch operations will output a new GeoJSON (or CSV for extract_map_links) with the appended geocoding results, preserving your original attributes.

action segment GPU SAM2: Segment objects from satellite imagery using point/box prompts ▼
⚠️ Submit to POST /v1/cv/jobs, NOT /v1/jobs
ParamTypeRequiredDescription
pointsarrayone ofPixel coordinate prompts: [[x,y], [x,y]]
labelsarraywith points1 = foreground, 0 = background, per point
boxesarrayone ofBounding box prompts: [[x1,y1,x2,y2]]

Returns a GeoJSON file containing geographic polygons of the segmented objects.

action detect GPU GroundingDINO: Open-vocabulary object detection from text prompt ▼
⚠️ Submit to POST /v1/cv/jobs, NOT /v1/jobs
ParamTypeRequiredDescription
promptstringrequiredText description of objects to find. End with a period: "solar panels."
box_thresholdnumberoptionalDetection confidence threshold (default: 0.3)
text_thresholdnumberoptionalText matching threshold (default: 0.25)

Returns a GeoJSON file with bounding box polygons and confidence scores for each detected object.

GET /v1/health

Returns the API status. No authentication required.

json — Response
{
  "status": "ok",
  "service": "GeoMiner API",
  "version": "1.0.0",
  "docs": "https://api.mapkmltools.com/docs"
}