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
https://api.mapkmltools.com
/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:
Authorization: Bearer gm_YOUR_API_KEY
| Method | Header Value | Use Case |
|---|---|---|
Developer API Key | Bearer gm_xxxx | External integrations, SDKs, scripts |
Firebase ID Token | Bearer eyJhbGci... | Logged-in mapkmltools.com users |
Errors
All errors return a JSON body with an error string and an HTTP status code.
{
"error": "Rate limit exceeded: max 30 requests/minute",
"status": 429,
"timestamp": "2024-07-17T15:30:00.000Z"
}
| Status | Meaning |
|---|---|
400 | Bad request — missing or invalid parameters |
401 | Unauthorized — missing or invalid API key / token |
404 | Job not found |
429 | Rate limit exceeded |
500 | Internal server error |
502 | Upstream 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.
segment, detect) must be submitted to POST /v1/cv/jobs instead.Request Body
| Field | Type | Required | Description |
|---|---|---|---|
action | string | required | The GIS operation to perform. See Actions Reference. |
object_key | string | required* | The R2 storage key of the input file. Not required for ai_plan. |
params | object | optional | Action-specific parameters. See each action for details. |
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" }
}'
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
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
{
"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.
curl https://api.mapkmltools.com/v1/jobs/abc123-runpod-job-id \ -H "Authorization: Bearer gm_YOUR_API_KEY"
Response (Completed)
{
"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.
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.
{ "filename": "roads.shp" }
{
"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.
{ "object_key": "outputs/uuid_roads.geojson" }
{
"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.
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.
| Param | Type | Required | Description |
|---|---|---|---|
| No additional params required. | |||
| Param | Type | Required | Description |
|---|---|---|---|
target_format | string | required | "GeoJSON", "GPKG", "Shapefile", "KML", "GTiff" |
{ "action": "convert", "object_key": "inputs/areas.geojson", "params": { "target_format": "GPKG" } }
| Param | Type | Required | Description |
|---|---|---|---|
target_crs | string | required | Any EPSG code or proj string, e.g. "EPSG:3857" |
| Param | Type | Required | Description |
|---|---|---|---|
operation | string | required | "buffer", "intersect", "union", "spatial_join" |
distance | number | buffer only | Buffer distance in the file's CRS units |
overlay_file | string | intersect/union | R2 object key of the overlay layer |
join_file | string | spatial_join | R2 object key of the join layer |
| Param | Type | Required | Description |
|---|---|---|---|
index | string | required | "ndvi", "ndwi", "ndbi" |
band_map | object | optional | Map band names to 1-based band indices. Default: {"red":3,"nir":4,"green":2,"swir":5} |
{ "action": "bandmath", "object_key": "inputs/sentinel.tif", "params": { "index": "ndvi", "band_map": { "red": 4, "nir": 8 } } }
| Param | Type | Required | Description |
|---|---|---|---|
operation | string | required | "slope" (output in degrees) or "hillshade" (output 0–255 uint8) |
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.
| Param | Type | Required | Description |
|---|---|---|---|
prompt | string | required | Plain English description of what you want to achieve |
metadata | object | optional | File metadata from a previous analyze job to help the AI understand your data |
[
{ "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" } }
]
POST /v1/cv/jobs, NOT /v1/jobs| Param | Type | Required | Description |
|---|---|---|---|
points | array | one of | Pixel coordinate prompts: [[x,y], [x,y]] |
labels | array | with points | 1 = foreground, 0 = background, per point |
boxes | array | one of | Bounding box prompts: [[x1,y1,x2,y2]] |
Returns a GeoJSON file containing geographic polygons of the segmented objects.
POST /v1/cv/jobs, NOT /v1/jobs| Param | Type | Required | Description |
|---|---|---|---|
prompt | string | required | Text description of objects to find. End with a period: "solar panels." |
box_threshold | number | optional | Detection confidence threshold (default: 0.3) |
text_threshold | number | optional | Text 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.
{
"status": "ok",
"service": "GeoMiner API",
"version": "1.0.0",
"docs": "https://api.mapkmltools.com/docs"
}