API Documentation
Convert geospatial data programmatically using the ConvertGeoData REST API. Available on Pro and Business plans.
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
/api/v1/conversions/upload/
Upload one or more geospatial files for conversion. Supports individual files and ZIP archives.
Request
Content-Type: multipart/form-data
| Field | Type | Description |
|---|---|---|
files | File(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
/api/v1/conversions/{task_id}/convert/
Start converting an uploaded file to the specified output format.
Request Body (JSON)
| Field | Type | Required | Description |
|---|---|---|---|
output_format | string | Yes | Target format (e.g., "ESRI Shapefile", "GPKG", "KML") |
target_crs | string | No | Target 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
/api/v1/conversions/{task_id}/
Poll this endpoint to check conversion progress. The task progresses through statuses: pending → processing → completed (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
/api/v1/conversions/formats/?input_format={driver_name}
Get available output formats for a given input format, ranked by popularity.
Query Parameters
| Param | Description |
|---|---|
input_format | GDAL/OGR driver name (e.g., "GeoJSON", "ESRI Shapefile") |
Search EPSG Codes
/api/v1/conversions/epsg-search/?q={query}
Search for EPSG coordinate reference system codes by code number, name, or geographic area.
Response
[
{"code": "EPSG:4326", "name": "WGS 84", "area": "World"},
{"code": "EPSG:32632", "name": "WGS 84 / UTM zone 32N", "area": "Between 6°E and 12°E"}
]
Additional Endpoints
Set CSV Coordinate Columns
/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
/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
| Plan | Conversions/Month | Max File Size | API Access |
|---|---|---|---|
| Free | 5 | 50 MB | No |
| Pro ($12/mo) | 200 | 500 MB | Yes |
| Business ($39/mo) | 2,000 | 5 GB | Yes |
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'."}
| Status | Meaning |
|---|---|
400 | Bad request (invalid parameters) |
401 | Authentication required or invalid API key |
404 | Task not found |
429 | Rate limit exceeded |