Everything needed to make the first call and read the answer: the base URL, both authentication forms, how a run is attributed to a member, and each endpoint's fields, response and curl.
Every call goes to this base URL with the tool's own segment appended — the last part of each path shown below. The curl samples carry the complete URL, ready to paste.
https://haiyz.net/api/enterprise/v1/gisResponses use the platform's standard envelope: ok says whether the call worked, code is a stable machine-readable identifier, message is human-facing text, and data carries the tool's own result.
{
"ok": true,
"statusCode": 200,
"code": "SUCCESS",
"data": {
"key": "gis/2026/08/… .geojson",
"inputKey": "gis/2026/08/… .zip",
"filename": "parcels.geojson"
},
"path": "/enterprise/v1/gis/validate-convert",
"method": "POST",
"timestamp": "2026-08-17T09:41:22.104Z"
}Tools that produce a file return a storage key for it rather than a public URL. The output is stored under the member the run was attributed to and appears in that member's file history in the app, where it can be downloaded or handed to the other Haiyz products.
Send your credentials as headers on every request:
X-Api-Key — your public key (starts with haiyz_pk_).X-Api-Secret — your secret key (starts with haiyz_sk_).X-Api-User — optional; the email of the assigned member to attribute the run to. Defaults to the org owner.The header pair can be replaced by a single Authorization header carrying the public key and the secret separated by a colon. It authenticates identically — pick whichever your client configures more cleanly.
curl -X POST https://haiyz.net/api/enterprise/v1/gis/validate-convert \
-H "Authorization: Bearer haiyz_pk_live_xxxxxxxxxxxx:haiyz_sk_live_xxxxxxxxxxxxxxxxxxxxxxxx" \
-F "[email protected]" \
-F "target_format=geojson"Keep the secret server-side
Which member of your organization a run belongs to.
All endpoints are POST under /enterprise/v1/gis. Request and response bodies match the in-app GIS tools.
Each section below gives the wire contract: the fields the request carries, what comes back, and a curl you can paste once you have replaced the placeholder credentials.
/enterprise/v1/gis/validate-convertValidate and convert a shapefile, GeoJSON or KML
Reads the uploaded vector file, checks that it is well formed, and writes it out in the format you asked for. This is what an intake pipeline calls first, so everything downstream can assume one format.
filetarget_formatReturns the storage key of the converted file, the key of the input it was produced from, and the output filename.
curl -X POST https://haiyz.net/api/enterprise/v1/gis/validate-convert \
-H "X-Api-Key: haiyz_pk_live_xxxxxxxxxxxx" \
-H "X-Api-Secret: haiyz_sk_live_xxxxxxxxxxxxxxxxxxxxxxxx" \
-F "[email protected]" \
-F "target_format=geojson"/enterprise/v1/gis/transform-crs/jsonReproject coordinate pairs (JSON in, JSON out)
Takes coordinate pairs in the request body and returns them in the target coordinate system. No file is produced, which makes it the lightest call on the surface: it counts as a single file against the window however many points it carries.
source_crstarget_crspointsReturns the reprojected pairs in the order they were sent, as transformedPoints.
curl -X POST https://haiyz.net/api/enterprise/v1/gis/transform-crs/json \
-H "X-Api-Key: haiyz_pk_live_xxxxxxxxxxxx" \
-H "X-Api-Secret: haiyz_sk_live_xxxxxxxxxxxxxxxxxxxxxxxx" \
-H "X-Api-User: [email protected]" \
-H "Content-Type: application/json" \
-d '{
"source_crs": "EPSG:4326",
"target_crs": "EPSG:3857",
"points": [{ "x": 46.72, "y": 24.68 }]
}'/enterprise/v1/gis/transform-crs/csvReproject a CSV of coordinates
The same reprojection for a file of coordinates: upload the CSV, name the two coordinate systems, and a converted CSV is written out.
filesource_crstarget_crsReturns the storage keys of the output and the input, the output filename, and how many points were converted.
curl -X POST https://haiyz.net/api/enterprise/v1/gis/transform-crs/csv \
-H "X-Api-Key: haiyz_pk_live_xxxxxxxxxxxx" \
-H "X-Api-Secret: haiyz_sk_live_xxxxxxxxxxxxxxxxxxxxxxxx" \
-F "[email protected]" \
-F "source_crs=EPSG:4326" \
-F "target_crs=EPSG:32638"/enterprise/v1/gis/bufferBuffer geometries by a distance
Grows every geometry in the file by a distance in metres — protection zones, setbacks, catchment rings. Set dissolve when overlapping rings should become one area instead of many.
filedistance_mtarget_formatdissolveReturns the storage key of the buffered file, the key of the input, and the output filename.
curl -X POST https://haiyz.net/api/enterprise/v1/gis/buffer \
-H "X-Api-Key: haiyz_pk_live_xxxxxxxxxxxx" \
-H "X-Api-Secret: haiyz_sk_live_xxxxxxxxxxxxxxxxxxxxxxxx" \
-F "[email protected]" \
-F "distance_m=100" \
-F "target_format=geojson" \
-F "dissolve=false"/enterprise/v1/gis/mergeMerge multiple vector files
Combines several vector files into one. This is the call for datasets that arrive split by district, by sheet or by contractor while everything downstream expects a single layer.
filestarget_formatReturns the storage key of the merged file and its filename.
curl -X POST https://haiyz.net/api/enterprise/v1/gis/merge \
-H "X-Api-Key: haiyz_pk_live_xxxxxxxxxxxx" \
-H "X-Api-Secret: haiyz_sk_live_xxxxxxxxxxxxxxxxxxxxxxxx" \
-F "[email protected]" \
-F "[email protected]" \
-F "target_format=geojson"/enterprise/v1/gis/simplifySimplify geometries to a tolerance
Reduces vertex count against a tolerance — the call that makes a heavy boundary layer usable on the web. Leave preserve_topology on unless self-intersections are acceptable in the output.
filetolerancetarget_formatpreserve_topologyReturns the storage key of the simplified file, the key of the input, and the output filename.
curl -X POST https://haiyz.net/api/enterprise/v1/gis/simplify \
-H "X-Api-Key: haiyz_pk_live_xxxxxxxxxxxx" \
-H "X-Api-Secret: haiyz_sk_live_xxxxxxxxxxxxxxxxxxxxxxxx" \
-F "[email protected]" \
-F "tolerance=0.001" \
-F "target_format=geojson" \
-F "preserve_topology=true"/enterprise/v1/gis/extract-exifExtract GPS EXIF from photos into GeoJSON
Reads EXIF from uploaded JPEGs and turns whatever GPS it finds into points. Photographs without location data are reported rather than dropped, so a field team can see which shots need attention.
filesReturns a row per photograph — filename, whether it carried GPS, latitude, longitude, altitude and timestamp — plus the geotagged and total counts and the key of the produced GeoJSON.
curl -X POST https://haiyz.net/api/enterprise/v1/gis/extract-exif \
-H "X-Api-Key: haiyz_pk_live_xxxxxxxxxxxx" \
-H "X-Api-Secret: haiyz_sk_live_xxxxxxxxxxxxxxxxxxxxxxxx" \
-F "[email protected]" \
-F "[email protected]"The failures this API returns, the rolling file window, the size ceilings and the retry behaviour.