Convert a Batch of Files
POST/api/geoconvert/convert/batch
Convert several files in a single request. Each file is validated, counted against the allowance, and converted independently — exactly like /convert/file — so a failure or an exhausted allowance on one file does not affect the others. Each file's input is detected from its extension — any format /convert/file accepts, including a .zip wrapping a single convertible file (unwrapped automatically); its output is chosen per file via the parallel outputFormats array (see below), defaulting to the input's default direction when omitted.
Allowance: every file that converts successfully counts as one conversion and its size counts toward the month's data allowance; each is recorded as its own transaction. Files are counted one at a time; once a plan limit is reached, the remaining files come back with success: false, needsUpgrade: true and limit naming the limit instead of being converted.
Headers
X-API-Key(required for authentication)
Request (multipart/form-data)
files file[] (required)
One or more input files, each repeated under the field name files. A batch may contain at most MaxBatchFiles files (default 20), and the whole request body is capped at MaxBatchTotalBytes (default 200 MB); each individual file is still capped at the upload ceiling (100 MB) and at the plan's own per-file cap.
outputFormats string[] (optional)
Per-file target formats, repeated under the field name outputFormats and index-aligned with files (the n-th outputFormats value applies to the n-th files entry). Use an empty string for a file that should keep its default direction. Accepts the same values as the single-file endpoint's outputFormat (GeoJson, Shapefile, Csv, GeoPackage, Kml, Gpx, Xlsx, GeoParquet, …). Omit the field entirely to convert every file in its default direction.
targetEpsg number (optional)
Target EPSG code applied to every file. Defaults to 4326. GeoJSON output is always WGS84 (EPSG:4326) per RFC 7946.
sourceEpsgs string[] (optional)
Per-file source coordinate systems, sent as a parallel array index-aligned with files exactly like outputFormats. Leave an entry empty for any file that records its own CRS — most do. See sourceEpsg for when a value is required (DXF, plain tables, a shapefile ZIP with no .prj).
Response 200
success boolean
True when at least one file in the batch converted successfully.
results array
One entry per submitted file, in request order. Each entry contains fileName, success, jobId, status, downloadUrl, downloadExpiresAt, featureCount, outputSizeBytes, processingTimeMs, truncationReport (data-loss report when the target is Shapefile, otherwise null), error (when that file failed), needsUpgrade (true when a plan limit skipped the file) and limit (fileSize, data, conversions or wallet; null when no limit was hit).
remainingConversions / remainingBytes number | null
What is left of the month's conversion and data allowances after the whole batch; null on an account still spending legacy prepaid credit.
newWalletBalanceCents number | null
Only for accounts still spending legacy prepaid credit: the balance in USD cents after the batch. null on every plan.
curl -X POST https://cadshift.com/api/geoconvert/convert/batch -H "X-API-Key: $API_KEY" -F "[email protected]" -F "outputFormats=GeoPackage" -F "[email protected]" -F "outputFormats=" -F "[email protected]" -F "outputFormats=Kml" -F "targetEpsg=4326"roads → GeoPackage, parcels → default (Shapefile), survey → KML.
{
"success": true,
"results": [
{
"fileName": "roads.geojson",
"success": true,
"jobId": "00000000-0000-0000-0000-000000000000",
"status": "Completed",
"downloadUrl": "https://...",
"downloadExpiresAt": "2026-01-01T00:00:00Z",
"featureCount": 512,
"outputSizeBytes": 240118,
"processingTimeMs": 1320,
"truncationReport": null,
"error": null,
"needsUpgrade": false,
"limit": null
},
{
"fileName": "survey.zip",
"success": true,
"jobId": "00000000-0000-0000-0000-000000000001",
"status": "Completed",
"downloadUrl": "https://...",
"featureCount": 88,
"outputSizeBytes": 41022,
"processingTimeMs": 610,
"truncationReport": null,
"error": null,
"needsUpgrade": false,
"limit": null
}
],
"remainingConversions": 498,
"remainingBytes": 1073460684,
"newWalletBalanceCents": null
}