Reading and editing features
Every synced table is served as an ArcGIS Feature Service. Existing GIS clients — the
ArcGIS Maps SDK, ArcGIS Pro, QGIS’s Esri connector, anything that speaks f=json — point at the
URL and work, with no translation layer. The same table is also available as
plain GeoJSON and through the
records API.
# one table = one single-layer servicehttps://{SERVER}/api/v0/rest/services/{baseId}/{tableName}/FeatureServer
# the whole base = one service, every table a layerhttps://{SERVER}/api/v0/rest/services/{baseId}/FeatureServerAppend /0 for the first layer, then any Esri method. Both forms accept the same requests; the
base-level form is what you want when tables reference each other, because
relationships are only complete across a whole base.
Authenticate as you would any read: a session cookie, an app token, or an API key. Esri clients
that only know ?token= work as-is — the token parameter takes an app token or an ims_… key.
Querying
Section titled “Querying”curl 'https://{SERVER}/api/v0/rest/services/appXXX/Locations/FeatureServer/0/query' \ --get \ --data-urlencode "where=Status = 'Open' AND Capacity > 100" \ --data-urlencode 'outFields=*' \ --data-urlencode 'f=geojson' \ --data-urlencode 'token=ims_…'The usual Esri query parameters are supported:
| Parameter | Notes |
|---|---|
where |
SQL-92 subset — comparisons, AND/OR/NOT, IN, LIKE, BETWEEN, IS NULL |
objectIds |
Comma-separated OBJECTIDs |
geometry, geometryType, spatialRel, inSR |
Spatial filtering (envelope, point, polygon) |
outFields |
* or a comma-separated list |
returnGeometry, outSR |
Geometry on/off, reprojection |
orderByFields |
Field ASC, Other DESC |
resultOffset, resultRecordCount |
Paging |
returnCountOnly, returnIdsOnly, returnExtentOnly, returnDistinctValues |
Cheap metadata queries |
groupByFieldsForStatistics, outStatistics |
Server-side aggregation |
f |
json (Esri), geojson, pbf where the client asks for it, html |
Also available on a layer: /generateRenderer, /queryRelatedRecords, /getEstimates,
/info, /layers, and /queryAttachments (see Attachments).
OBJECTIDs
Section titled “OBJECTIDs”Source systems rarely have a stable integer id, so Sync Server derives the OBJECTID by hashing
the provider’s record key. The hash is stable across syncs — a record keeps its OBJECTID as long
as its key doesn’t change — but it is not a value to persist in another system as a
long-term identifier. Use the provider record key (OID / Airtable recXXX / the NocoDB Id)
for that; it’s exposed as a field and is what the records API and the
activity log key on.
Editing
Section titled “Editing”curl -X POST '…/FeatureServer/0/applyEdits' \ -H 'Content-Type: application/x-www-form-urlencoded' \ --data-urlencode 'token=ims_…' \ --data-urlencode 'updates=[{"attributes":{"OBJECTID":1024,"Status":"Closed"}}]'applyEdits takes adds, updates and deletes, and returns Esri’s
addResults / updateResults / deleteResults. Writes go straight through to the upstream
provider — an applyEdits against an Airtable-backed layer is an Airtable API call — and then
update the cache in place, so the next read reflects the edit without waiting for a sync.
What you need to know before wiring up a client:
- The provider must be writable. Airtable, NocoDB, Postgres, PostGIS and MSSQL are;
fetchandtsipreject edits with a “not supported” error rather than pretending. - Write access is enforced per base — an org
memberrole or better, an API key withwritepermission, or the base owner. Areadkey gets a 403. - Edits are serialized per table, so two clients editing the same table can’t interleave.
- Every edit is logged, with a before-snapshot, and is the basis for rollback.
- Every edit is broadcast over the realtime feed, so other clients on the same table update without polling.
- Read-only fields stay read-only — formulas, rollups, lookups, autonumbers and created/modified stamps are rejected rather than silently dropped.
Optimistic concurrency
Section titled “Optimistic concurrency”Each table carries a monotonic revision, reported on the realtime feed
every time the table changes. Rollback accepts it as
expectedRevision and returns 409 if someone else changed the table since you read it,
rather than overwriting their work. Ordinary edits are not revision-gated — they are serialized
by the write lock, and the realtime feed tells you when to re-read.
Field metadata
Section titled “Field metadata”Feature services only have four usable scalar types, so everything else the provider knows about a column travels through Esri’s side channels — which means a well-behaved client gets the real types back:
| Provider concept | How it arrives |
|---|---|
| Single-select | Coded-value domain |
| Multi-select | JSON array value + description.multiValue |
| Number ranges | Range domain |
| Currency, percent, rating, duration, URL, email, phone | description.fieldValueType |
| Formula / rollup / lookup / autonumber | editable: false |
| Created / modified time and by | Layer-level editFieldsInfo |
Clients that don’t recognise a key ignore it, so this is additive for existing consumers. Stored values are unchanged — a multi-select cell is the same JSON array literal it always was.
Relationships
Section titled “Relationships”Link fields between tables in the same base are published as ArcGIS relationships, so
queryRelatedRecords works and clients that understand related tables (the Maps SDK, Pro) show
them. Relationships are built bidirectionally across the whole base, which is why they’re only
complete on the base-level service URL:
GET /api/v0/rest/services/{baseId}/FeatureServer/relationshipsOne-to-one, one-to-many and many-to-many (through an intermediary table) are all supported.
Plain GeoJSON
Section titled “Plain GeoJSON”If you just want the features:
GET /api/v0/{baseId}/{tableName}.geojson → the cached FeatureCollectionGET /api/v0/{baseId}/schema → the base's tables and their fieldsSame auth rules, no Esri envelope. This is the cheapest way to feed MapLibre, deck.gl or a data-processing job.
Vector tiles
Section titled “Vector tiles”The same table is also available as Mapbox Vector Tiles — see Vector tiles and snapshots.