Skip to content

Exporting layers to files

Any cached layer can be downloaded as a file. Exports run as background jobs, so a large base converts without tying up the API, and one request can produce several formats at once.

The endpoint is shaped like Esri’s — POST .../FeatureServer/export, returning an esriJob… status document — so ArcGIS clients that already speak createReplica need no special handling.

Open a base and pick the Export tab. Choose one or more formats, tick the layers you want, optionally set a projection or a filter, and hit Export. A progress card appears and turns into a row of download buttons when the job lands.

Downloads expire (24 hours by default, see Expiry), so treat the links as short-lived rather than permanent URLs.

Terminal window
curl -X POST 'https://{SERVER}/api/v0/rest/services/{baseId}/FeatureServer/export' \
-H 'Authorization: Bearer {key}' \
-H 'Content-Type: application/json' \
-d '{ "formats": "gpkg,shapefile" }'
{
"jobId": "6f1c…",
"jobStatus": "esriJobSubmitted",
"statusUrl": "https://{SERVER}/api/v0/rest/services/{baseId}/FeatureServer/export/jobs/6f1c…"
}

Authenticate exactly as you would a FeatureServer read: a session cookie, an org- or base-scoped API key, or an app token. Parameters may be sent as JSON body fields or as query-string parameters — ArcGIS clients use both, so either works.

Path Exports
/rest/services/{baseId}/FeatureServer/export every table in the base
/rest/services/{baseId}/FeatureServer/export?layers=0,2 just those layer ids
/rest/services/{baseId}/{tableName}/FeatureServer/export that one table

POST …/createReplica is an alias of …/export, for clients that only know the Esri name.

Terminal window
curl 'https://{SERVER}/api/v0/rest/services/{baseId}/FeatureServer/export/jobs/{jobId}' \
-H 'Authorization: Bearer {key}'
{
"jobId": "6f1c…",
"jobStatus": "esriJobSucceeded",
"progress": 100,
"expires": "2026-09-10T14:02:11.000Z",
"results": {
"paths": [
{ "format": "gpkg", "sizeBytes": 1841152, "url": "…/jobs/6f1c…/results/gpkg" },
{ "format": "shapefile", "sizeBytes": 903221, "url": "…/jobs/6f1c…/results/shapefile" }
]
}
}

jobStatus is one of esriJobSubmitted, esriJobExecuting, esriJobSucceeded or esriJobFailed. Each paths entry is a direct download — same auth as everything else.

A job that produced some of the formats it was asked for still succeeds, and reports the rest under messages:

"messages": [{ "type": "esriJobMessageTypeError", "description": "dxf: ogr2ogr exited 1 …" }]

So always read messages even on esriJobSucceeded — never assume every requested format is in results.

Request them as a comma-separated formats list (or repeat format=).

format File Notes
geojson .geojson Copied straight from the cache when unfiltered, so it is essentially free
csv .csv Geometry written as WKT
xlsx .xlsx One sheet per layer
shapefile .zip Field names truncated to 10 characters by the format itself
gpkg .gpkg One table per layer
kml / kmz .kml / .kmz One folder per layer
format File Notes
filegdb .zip A .gdb folder, one feature class per layer; opens in ArcGIS Pro
featurecollection .json Esri FeatureSet JSON with a layerDefinition
spatialite .sqlite SpatiaLite database — Esri’s “SQLite geodatabase”; QGIS reads it directly
format File Notes
flatgeobuf .fgb Cloud-optimized; seekable and streamable
geoparquet .parquet Columnar, for DuckDB / Spark / pandas analytics
gml .gml OGC XML, common in European open data
dxf .dxf CAD exchange (AutoCAD); attributes are largely dropped by the format

mbtiles builds a vector tileset rather than converting features, and takes its own options (zoom range, per-layer field keep-lists, projection) plus an optional snapshot block that publishes it at a hosted tiles endpoint. It does not accept the filters below. See the Vector tiles tab in the UI, and Vector tiles and snapshots for the full option set.

gpkg, filegdb, xlsx, kml, kmz, gml and spatialite hold many layers natively, so a multi-layer export is a single file with a layer/table/sheet per table.

The rest hold one layer each, so a multi-layer export of geojson, csv, shapefile, featurecollection, flatgeobuf, geoparquet or dxf arrives as a .zip of per-layer files. A single-layer export is always the plain file.

All four are optional, all apply to every layer in the export, and all are evaluated by GDAL:

Parameter Example Effect
outSR 3857 Reproject from 4326 to this EPSG code
where population > 100000 SQL attribute filter
bbox -10,40,5,55 Spatial filter, minX,minY,maxX,maxY in 4326
outFields name,population,iso3 Keep only these attributes (* or omitted keeps all)
Terminal window
curl -X POST '…/{baseId}/FeatureServer/export' \
-H 'Authorization: Bearer {key}' -H 'Content-Type: application/json' \
-d '{
"formats": "geojson,gpkg",
"layers": "0,1",
"outSR": 3857,
"where": "population > 100000",
"outFields": "name,population"
}'

Because the filter is shared, a where clause or a field name that only exists on some of the selected layers will fail those layers — they show up in messages while the rest of the export still succeeds.

bbox is always interpreted in 4326, even when outSR asks for something else: it filters the source data, then the survivors are reprojected.

Artifacts live on disk under the export id and are swept by an hourly maintenance job. The window is EXPORT_TTL_HOURS (default 24); the exact deadline for a given job is in its status document as expires. After that both the download and the status endpoint return 404, and a new job has to be submitted.

An export converts whatever Sync Server last synced, not the upstream source. A layer with no cache yet fails with No cache for layer "…" — sync the base first., so trigger a sync (POST /api/v0/bases/{baseId}/sync) and wait for it before exporting a newly added table.