API Documentation

Convert geospatial data programmatically using the ConvertGeoData REST API. Available on Pro and Business plans.

Base URL: https://convertgeodata.com/api/v1

Authentication

All API requests require an API key. Generate keys from your account settings.

Include your API key in the request header:

X-API-Key: cgd_your_api_key_here

Or use the Authorization header:

Authorization: Api-Key cgd_your_api_key_here

Upload Files

POST
/api/v1/conversions/upload/

Upload one or more geospatial files for conversion. Supports individual files and ZIP archives.

Request

Content-Type: multipart/form-data

FieldTypeDescription
filesFile(s)One or more geospatial files or a ZIP archive

Response

{
  "id": 42,
  "status": "pending",
  "input_format": "GeoJSON",
  "detected_crs": "EPSG:4326",
  "detected_crs_name": "WGS 84",
  "layers": [
    {
      "name": "points",
      "feature_count": 150,
      "geometry_type": "Point",
      "attributes": [{"name": "id", "type": "Integer"}, ...]
    }
  ]
}

Code Samples

curl -X POST https://convertgeodata.com/api/v1/conversions/upload/ \
  -H "X-API-Key: cgd_your_api_key" \
  -F "files=@data.geojson"
import requests

response = requests.post(
    "https://convertgeodata.com/api/v1/conversions/upload/",
    headers={"X-API-Key": "cgd_your_api_key"},
    files={"files": open("data.geojson", "rb")},
)
task = response.json()
print(f"Task ID: {task['id']}")
const form = new FormData();
form.append("files", fs.createReadStream("data.geojson"));

const response = await fetch(
  "https://convertgeodata.com/api/v1/conversions/upload/",
  {
    method: "POST",
    headers: { "X-API-Key": "cgd_your_api_key" },
    body: form,
  }
);
const task = await response.json();

Start Conversion

POST
/api/v1/conversions/{task_id}/convert/

Start converting an uploaded file to the specified output format.

Request Body (JSON)

FieldTypeRequiredDescription
output_formatstringYesTarget format (e.g., "ESRI Shapefile", "GPKG", "KML")
target_crsstringNoTarget EPSG code (e.g., "EPSG:3857"). If omitted, source CRS is preserved.

Code Samples

curl -X POST https://convertgeodata.com/api/v1/conversions/42/convert/ \
  -H "X-API-Key: cgd_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"output_format": "ESRI Shapefile", "target_crs": "EPSG:3857"}'
response = requests.post(
    f"https://convertgeodata.com/api/v1/conversions/{task_id}/convert/",
    headers={
        "X-API-Key": "cgd_your_api_key",
        "Content-Type": "application/json",
    },
    json={
        "output_format": "ESRI Shapefile",
        "target_crs": "EPSG:3857",
    },
)
const response = await fetch(
  `https://convertgeodata.com/api/v1/conversions/${taskId}/convert/`,
  {
    method: "POST",
    headers: {
      "X-API-Key": "cgd_your_api_key",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      output_format: "ESRI Shapefile",
      target_crs: "EPSG:3857",
    }),
  }
);

Check Task Status

GET
/api/v1/conversions/{task_id}/

Poll this endpoint to check conversion progress. The task progresses through statuses: pendingprocessingcompleted (or failed).

Response

{
  "id": 42,
  "status": "completed",
  "progress": 100,
  "input_format": "GeoJSON",
  "output_format": "ESRI Shapefile",
  "output_files": [
    {
      "filename": "output.zip",
      "file_size": 24680,
      "download_url": "/media/outputs/task_42/output.zip"
    }
  ]
}

List Output Formats

GET
/api/v1/conversions/formats/?input_format={driver_name}

Get available output formats for a given input format, ranked by popularity.

Query Parameters

ParamDescription
input_formatGDAL/OGR driver name (e.g., "GeoJSON", "ESRI Shapefile")

Additional Endpoints

Set CSV Coordinate Columns

PATCH
/api/v1/conversions/{task_id}/columns/

For CSV inputs, specify which columns contain coordinates. Send {"x_column": "lon", "y_column": "lat"} or {"wkt_column": "geometry"}.

Set Source CRS

PATCH
/api/v1/conversions/{task_id}/source-crs/

Manually assign a source CRS when auto-detection fails. Send {"source_crs": "EPSG:4326"}.

Complete Workflow Example

Convert a GeoJSON file to Shapefile with reprojection to Web Mercator:

import requests
import time

API_KEY = "cgd_your_api_key"
BASE = "https://convertgeodata.com/api/v1/conversions"
HEADERS = {"X-API-Key": API_KEY}

# 1. Upload
resp = requests.post(
    f"{BASE}/upload/",
    headers=HEADERS,
    files={"files": open("data.geojson", "rb")},
)
task_id = resp.json()["id"]

# 2. Start conversion
requests.post(
    f"{BASE}/{task_id}/convert/",
    headers={**HEADERS, "Content-Type": "application/json"},
    json={"output_format": "ESRI Shapefile", "target_crs": "EPSG:3857"},
)

# 3. Poll until complete
while True:
    status = requests.get(f"{BASE}/{task_id}/", headers=HEADERS).json()
    if status["status"] in ("completed", "failed"):
        break
    time.sleep(2)

# 4. Download result
if status["status"] == "completed":
    url = status["output_files"][0]["download_url"]
    output = requests.get(f"https://convertgeodata.com{url}", headers=HEADERS)
    with open("output.zip", "wb") as f:
        f.write(output.content)
    print("Conversion complete!")

Rate Limits

PlanConversions/MonthMax File SizeAPI Access
Free550 MBNo
Pro ($12/mo)200500 MBYes
Business ($39/mo)2,0005 GBYes

When you exceed your monthly limit, the API returns 429 Too Many Requests.

Error Handling

All errors return a JSON object with an error field:

{"error": "Invalid output format 'XYZ' for input 'GeoJSON'."}
StatusMeaning
400Bad request (invalid parameters)
401Authentication required or invalid API key
404Task not found
429Rate limit exceeded