> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bijection.com/llms.txt
> Use this file to discover all available pages before exploring further.

# ArcGIS Feature Service

> Resources, examples, configuration and evidence for ArcGIS Feature Service.

Use the `@bijection/connectors/arcgis` entrypoint to declare ArcGIS Feature Service resources.

## Availability

This page describes the pinned source package. Published availability is unestablished for this artifact. [Source build and package availability](https://docs.bijection.com/client/sdk-distribution.md).

## Resources and modes

| Resource | Mode | Description |
| - | - | - |
| Feature layer | `keyset` | Object id keyset walk |

Declare a resource in application code, then bind deployment-specific settings and credentials. See [typed resources](https://docs.bijection.com/integrations/resources.md), [connections](https://docs.bijection.com/integrations/connections.md) and [source inspection](https://docs.bijection.com/integrations/cli.md).

## Feature layer

### keyset: Object id keyset walk

The following example matches configuration `parcels`.

```ts theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
import { arcgis } from "@bijection/connectors/arcgis";
import { v } from "bijection/values";

export const parcels = arcgis.layer.keyset({
  properties: {
    PARCEL_ID: v.string(),
    ZONING: v.union(v.string(), v.null()),
    ACRES: v.union(v.number(), v.null()),
  },
  geometry: { types: ["Polygon", "MultiPolygon"] },
  pageSize: 2,
});
```

> **Inferred record types**
>
> ```ts theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
> {
>   "objectId": bigint;
>   "geometry": any;
>   "PARCEL_ID": string;
>   "ZONING": string | null;
>   "ACRES": number | null;
> }
> ```

#### Configuration: parcels

Case: `arcgis/layer/keyset/parcels`.

Connection and resource configuration are declared by this exact case.

Credential kind: `arcgis`. Keep credential material in the private credential inventory.

| Setting | Type | Required | Owner |
| - | - | - | - |
| `endpoint` | string | Yes | Shared connection |
| `service` | string | Yes | Resource binding |
| `layer` | string | Yes | Resource binding |

> **Complete configuration contract**
>
> ```json theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
> {
>   "setup": [],
>   "resource": {
>     "access": {},
>     "defaults": {},
>     "connector": "arcgis",
>     "output": {
>       "kind": "single",
>       "collection": "records"
>     },
>     "credential_kind": "arcgis",
>     "connection_fields": [
>       "endpoint"
>     ],
>     "address": {
>       "kind": "setup",
>       "field": "endpoint"
>     }
>   },
>   "connection_setup": {
>     "type": "object",
>     "value": {
>       "endpoint": {
>         "fieldType": {
>           "type": "string"
>         },
>         "optional": false
>       },
>       "service": {
>         "fieldType": {
>           "type": "string"
>         },
>         "optional": false
>       },
>       "layer": {
>         "fieldType": {
>           "type": "string"
>         },
>         "optional": false
>       }
>     }
>   },
>   "execution": null
> }
> ```

Native admission analysis is available for this exact declaration.

**Collection: records**

| Contract | Meaning |
| - | - |
| Initial | Enumeration of observed records |
| Changes | Repeated observations of current records |
| Deletions | Deletion detection unsupported |
| Resume | Opaque cursor |
| Gap | Explicit repair required after a gap |
| Retention | Unspecified |

> **Complete native profile**
>
> ```json theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
> {
>   "movement": {
>     "exchanges": {
>       "records": {
>         "200": {
>           "placement": "retained_bytes",
>           "interpretation": "json",
>           "projectsBeforeRetention": false,
>           "retainedBodyLimitBytes": "524288",
>           "fileLimitBytes": null
>         }
>       },
>       "records_after": {
>         "200": {
>           "placement": "retained_bytes",
>           "interpretation": "json",
>           "projectsBeforeRetention": false,
>           "retainedBodyLimitBytes": "524288",
>           "fileLimitBytes": null
>         }
>       }
>     },
>     "nativeInputLimitBytes": null,
>     "steps": [
>       {
>         "id": "acquire.1",
>         "inputs": [],
>         "action": {
>           "operation": "acquire",
>           "subject": "exchange records",
>           "limitBytes": null
>         }
>       },
>       {
>         "id": "acquire.2",
>         "inputs": [],
>         "action": {
>           "operation": "acquire",
>           "subject": "exchange records_after",
>           "limitBytes": null
>         }
>       },
>       {
>         "id": "retain.1",
>         "inputs": [
>           "acquire.1",
>           "acquire.2"
>         ],
>         "action": {
>           "operation": "retain",
>           "subject": "acquisition evidence",
>           "reason": "recovery",
>           "release": "acquisition_custody"
>         }
>       },
>       {
>         "id": "interpret.1",
>         "inputs": [
>           "retain.1"
>         ],
>         "action": {
>           "operation": "interpret",
>           "subject": "acquired input",
>           "produces": "records"
>         }
>       },
>       {
>         "id": "materialize.1",
>         "inputs": [
>           "interpret.1"
>         ],
>         "action": {
>           "operation": "materialize",
>           "subject": "source rows",
>           "reason": "serving",
>           "release": "replacement"
>         }
>       },
>       {
>         "id": "publish.1",
>         "inputs": [
>           "materialize.1"
>         ],
>         "action": {
>           "operation": "publish",
>           "subject": "source rows",
>           "visibility": "with_acquisition"
>         }
>       }
>     ]
>   },
>   "initial": "enumeration",
>   "changes": "observations",
>   "deletions": "unsupported",
>   "resume": "opaque_cursor",
>   "retentionMs": null,
>   "gap": "explicit_repair",
>   "limits": {
>     "http_response_bytes": "524288"
>   },
>   "restrictions": [],
>   "commands": {}
> }
> ```

> **Commands, occurrences and artifacts**
>
> ```json theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
> {
>   "records": {
>     "records": {
>       "protocol": "record_observation",
>       "coverage": "records",
>       "consistency": "observations",
>       "atomicity": "record",
>       "history": "observations",
>       "recordRefresh": false,
>       "reconciliation": false,
>       "notifications": false,
>       "snapshotMaxRows": null,
>       "profile": {
>         "movement": {
>           "exchanges": {
>             "records": {
>               "200": {
>                 "placement": "retained_bytes",
>                 "interpretation": "json",
>                 "projectsBeforeRetention": false,
>                 "retainedBodyLimitBytes": "524288",
>                 "fileLimitBytes": null
>               }
>             },
>             "records_after": {
>               "200": {
>                 "placement": "retained_bytes",
>                 "interpretation": "json",
>                 "projectsBeforeRetention": false,
>                 "retainedBodyLimitBytes": "524288",
>                 "fileLimitBytes": null
>               }
>             }
>           },
>           "nativeInputLimitBytes": null,
>           "steps": [
>             {
>               "id": "acquire.1",
>               "inputs": [],
>               "action": {
>                 "operation": "acquire",
>                 "subject": "exchange records",
>                 "limitBytes": null
>               }
>             },
>             {
>               "id": "acquire.2",
>               "inputs": [],
>               "action": {
>                 "operation": "acquire",
>                 "subject": "exchange records_after",
>                 "limitBytes": null
>               }
>             },
>             {
>               "id": "retain.1",
>               "inputs": [
>                 "acquire.1",
>                 "acquire.2"
>               ],
>               "action": {
>                 "operation": "retain",
>                 "subject": "acquisition evidence",
>                 "reason": "recovery",
>                 "release": "acquisition_custody"
>               }
>             },
>             {
>               "id": "interpret.1",
>               "inputs": [
>                 "retain.1"
>               ],
>               "action": {
>                 "operation": "interpret",
>                 "subject": "acquired input",
>                 "produces": "records"
>               }
>             },
>             {
>               "id": "materialize.1",
>               "inputs": [
>                 "interpret.1"
>               ],
>               "action": {
>                 "operation": "materialize",
>                 "subject": "source rows",
>                 "reason": "serving",
>                 "release": "replacement"
>               }
>             },
>             {
>               "id": "publish.1",
>               "inputs": [
>                 "materialize.1"
>               ],
>               "action": {
>                 "operation": "publish",
>                 "subject": "source rows",
>                 "visibility": "with_acquisition"
>               }
>             }
>           ]
>         },
>         "initial": "enumeration",
>         "changes": "observations",
>         "deletions": "unsupported",
>         "resume": "opaque_cursor",
>         "retentionMs": null,
>         "gap": "explicit_repair",
>         "limits": {
>           "http_response_bytes": "524288"
>         },
>         "restrictions": [],
>         "commands": {}
>       }
>     }
>   },
>   "occurrences": null,
>   "artifacts": {
>     "raw_archive": false,
>     "native_file_transfer_limit_bytes": null,
>     "external_versions": false,
>     "files": {}
>   },
>   "commands": {}
> }
> ```

**Recorded checks**

| Requirement | Scope | Evidence | Result |
| - | - | - | - |
| last-key-empty-page-ends | \{"kind":"collection","name":"records"} | Fixture: ./src/connectors/arcgis/fixtures/first-page.json | passed (2026-10-24T21:36:11.983Z) |
| last-key-empty-page-ends | \{"kind":"collection","name":"records"} | Fixture: ./src/connectors/arcgis/fixtures/continuation-page.json | passed (2026-10-24T21:36:11.984Z) |
| last-key-empty-page-ends | \{"kind":"collection","name":"records"} | Fixture: ./src/connectors/arcgis/fixtures/empty-final-page.json | passed (2026-10-24T21:36:11.984Z) |
| last-key-empty-page-ends | \{"kind":"collection","name":"records"} | Fixture: ./src/connectors/arcgis/fixtures/unsorted-page.json | passed (2026-10-24T21:36:11.985Z) |
| page-publication-recovery | \{"kind":"collection","name":"records"} | Native test: integrations/acquisition/acquisition\_windows\_preserve\_sequences\_and\_restart\_fences\_old\_work (shared\_engine) | Execution result unavailable |
| identity-account | \{"kind":"connection"} | Fixture: ./src/connectors/arcgis/fixtures/identity.json | passed (2026-10-24T21:36:11.985Z) |

Hosted qualification: **unestablished for this catalog configuration**. Installed connections report their own identity, authority and current status.

#### Configuration: hydrants

Case: `arcgis/layer/keyset/hydrants`.

Connection and resource configuration are declared by this exact case.

Credential kind: `arcgis`. Keep credential material in the private credential inventory.

| Setting | Type | Required | Owner |
| - | - | - | - |
| `endpoint` | string | Yes | Shared connection |
| `service` | string | Yes | Resource binding |
| `layer` | string | Yes | Resource binding |

> **Complete configuration contract**
>
> ```json theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
> {
>   "setup": [],
>   "resource": {
>     "access": {},
>     "defaults": {},
>     "connector": "arcgis",
>     "output": {
>       "kind": "single",
>       "collection": "records"
>     },
>     "credential_kind": "arcgis",
>     "connection_fields": [
>       "endpoint"
>     ],
>     "address": {
>       "kind": "setup",
>       "field": "endpoint"
>     }
>   },
>   "connection_setup": {
>     "type": "object",
>     "value": {
>       "endpoint": {
>         "fieldType": {
>           "type": "string"
>         },
>         "optional": false
>       },
>       "service": {
>         "fieldType": {
>           "type": "string"
>         },
>         "optional": false
>       },
>       "layer": {
>         "fieldType": {
>           "type": "string"
>         },
>         "optional": false
>       }
>     }
>   },
>   "execution": null
> }
> ```

Native admission analysis is available for this exact declaration.

**Collection: records**

| Contract | Meaning |
| - | - |
| Initial | Enumeration of observed records |
| Changes | Repeated observations of current records |
| Deletions | Deletion detection unsupported |
| Resume | Opaque cursor |
| Gap | Explicit repair required after a gap |
| Retention | Unspecified |

> **Complete native profile**
>
> ```json theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
> {
>   "movement": {
>     "exchanges": {
>       "records": {
>         "200": {
>           "placement": "retained_bytes",
>           "interpretation": "json",
>           "projectsBeforeRetention": false,
>           "retainedBodyLimitBytes": "524288",
>           "fileLimitBytes": null
>         }
>       },
>       "records_after": {
>         "200": {
>           "placement": "retained_bytes",
>           "interpretation": "json",
>           "projectsBeforeRetention": false,
>           "retainedBodyLimitBytes": "524288",
>           "fileLimitBytes": null
>         }
>       }
>     },
>     "nativeInputLimitBytes": null,
>     "steps": [
>       {
>         "id": "acquire.1",
>         "inputs": [],
>         "action": {
>           "operation": "acquire",
>           "subject": "exchange records",
>           "limitBytes": null
>         }
>       },
>       {
>         "id": "acquire.2",
>         "inputs": [],
>         "action": {
>           "operation": "acquire",
>           "subject": "exchange records_after",
>           "limitBytes": null
>         }
>       },
>       {
>         "id": "retain.1",
>         "inputs": [
>           "acquire.1",
>           "acquire.2"
>         ],
>         "action": {
>           "operation": "retain",
>           "subject": "acquisition evidence",
>           "reason": "recovery",
>           "release": "acquisition_custody"
>         }
>       },
>       {
>         "id": "interpret.1",
>         "inputs": [
>           "retain.1"
>         ],
>         "action": {
>           "operation": "interpret",
>           "subject": "acquired input",
>           "produces": "records"
>         }
>       },
>       {
>         "id": "materialize.1",
>         "inputs": [
>           "interpret.1"
>         ],
>         "action": {
>           "operation": "materialize",
>           "subject": "source rows",
>           "reason": "serving",
>           "release": "replacement"
>         }
>       },
>       {
>         "id": "publish.1",
>         "inputs": [
>           "materialize.1"
>         ],
>         "action": {
>           "operation": "publish",
>           "subject": "source rows",
>           "visibility": "with_acquisition"
>         }
>       }
>     ]
>   },
>   "initial": "enumeration",
>   "changes": "observations",
>   "deletions": "unsupported",
>   "resume": "opaque_cursor",
>   "retentionMs": null,
>   "gap": "explicit_repair",
>   "limits": {
>     "http_response_bytes": "524288"
>   },
>   "restrictions": [],
>   "commands": {}
> }
> ```

> **Commands, occurrences and artifacts**
>
> ```json theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
> {
>   "records": {
>     "records": {
>       "protocol": "record_observation",
>       "coverage": "records",
>       "consistency": "observations",
>       "atomicity": "record",
>       "history": "observations",
>       "recordRefresh": false,
>       "reconciliation": false,
>       "notifications": false,
>       "snapshotMaxRows": null,
>       "profile": {
>         "movement": {
>           "exchanges": {
>             "records": {
>               "200": {
>                 "placement": "retained_bytes",
>                 "interpretation": "json",
>                 "projectsBeforeRetention": false,
>                 "retainedBodyLimitBytes": "524288",
>                 "fileLimitBytes": null
>               }
>             },
>             "records_after": {
>               "200": {
>                 "placement": "retained_bytes",
>                 "interpretation": "json",
>                 "projectsBeforeRetention": false,
>                 "retainedBodyLimitBytes": "524288",
>                 "fileLimitBytes": null
>               }
>             }
>           },
>           "nativeInputLimitBytes": null,
>           "steps": [
>             {
>               "id": "acquire.1",
>               "inputs": [],
>               "action": {
>                 "operation": "acquire",
>                 "subject": "exchange records",
>                 "limitBytes": null
>               }
>             },
>             {
>               "id": "acquire.2",
>               "inputs": [],
>               "action": {
>                 "operation": "acquire",
>                 "subject": "exchange records_after",
>                 "limitBytes": null
>               }
>             },
>             {
>               "id": "retain.1",
>               "inputs": [
>                 "acquire.1",
>                 "acquire.2"
>               ],
>               "action": {
>                 "operation": "retain",
>                 "subject": "acquisition evidence",
>                 "reason": "recovery",
>                 "release": "acquisition_custody"
>               }
>             },
>             {
>               "id": "interpret.1",
>               "inputs": [
>                 "retain.1"
>               ],
>               "action": {
>                 "operation": "interpret",
>                 "subject": "acquired input",
>                 "produces": "records"
>               }
>             },
>             {
>               "id": "materialize.1",
>               "inputs": [
>                 "interpret.1"
>               ],
>               "action": {
>                 "operation": "materialize",
>                 "subject": "source rows",
>                 "reason": "serving",
>                 "release": "replacement"
>               }
>             },
>             {
>               "id": "publish.1",
>               "inputs": [
>                 "materialize.1"
>               ],
>               "action": {
>                 "operation": "publish",
>                 "subject": "source rows",
>                 "visibility": "with_acquisition"
>               }
>             }
>           ]
>         },
>         "initial": "enumeration",
>         "changes": "observations",
>         "deletions": "unsupported",
>         "resume": "opaque_cursor",
>         "retentionMs": null,
>         "gap": "explicit_repair",
>         "limits": {
>           "http_response_bytes": "524288"
>         },
>         "restrictions": [],
>         "commands": {}
>       }
>     }
>   },
>   "occurrences": null,
>   "artifacts": {
>     "raw_archive": false,
>     "native_file_transfer_limit_bytes": null,
>     "external_versions": false,
>     "files": {}
>   },
>   "commands": {}
> }
> ```

**Recorded checks**

| Requirement | Scope | Evidence | Result |
| - | - | - | - |
| last-key-empty-page-ends | \{"kind":"collection","name":"records"} | No retained check covers this scoped arcgis requirement. | Execution result unavailable |
| page-publication-recovery | \{"kind":"collection","name":"records"} | Native test: integrations/acquisition/acquisition\_windows\_preserve\_sequences\_and\_restart\_fences\_old\_work (shared\_engine) | Execution result unavailable |
| identity-account | \{"kind":"connection"} | Fixture: ./src/connectors/arcgis/fixtures/identity.json | passed (2026-10-24T21:36:11.985Z) |

Hosted qualification: **unestablished for this catalog configuration**. Installed connections report their own identity, authority and current status.

## Provider guidance

Compiled declaration examples and configuration details are published in the [connector reference](https://docs.bijection.com/integrations/connectors/index).

Setup: `endpoint` is the ArcGIS REST services root (for example
`https://services.arcgis.com/<org>/arcgis/rest/services`) and is
connection-owned; `service` and `layer` select
`<service>/FeatureServer/<layer>`. A service in a folder needs the folder in
`endpoint`. Install an `arcgis` credential (`arcgis.credential(name)`); its
deployment presentation sends the API key or token as a bearer
`Authorization` header or as the `token` query parameter. Username/password
token generation is not supported.

One record per feature, keyed by `objectId`, the layer's object id read as an
exact integer (a value outside JSON's exact range is refused, never rounded).
`geometry` is the provider's GeoJSON geometry, or `null`, published in the
WGS84 XY coordinate space (`WGS84_XY_SPACE`, sphere distances). Declared attribute fields are published by
their ArcGIS names; dates arrive as the provider's epoch milliseconds.

## What the declaration establishes

* Pages are `query` requests with `f=geojson` and `outSR=4326`, so the
  server, not this recipe, produces longitude/latitude. A layer stored in
  another spatial reference is projected by the server with its default datum
  transformation; that step is the provider's and is not verified here.
  `returnZ=false` keeps positions 2D. No Esri JSON is decoded and nothing is
  repaired: geometry the profile refuses (for example an uncut antimeridian
  edge) fails admission.
* The walk is a keyset over the object id: `where=<oid> > <K>` and
  `orderByFields=<oid> ASC`, where `K` is the host's last-record-key
  continuation, derived from keys the host verified in the previous page. The
  first page of a pass sends `where=1=1`. `resultOffset` is not used: an offset
  is a guest-chosen position over a live ordering that the host cannot check,
  and one insert or delete ahead of it skips or repeats a feature silently.
  `objectIds` paging would carry an id list from one response into later
  requests through guest code, which the host cannot verify either.
* The reader refuses a page whose keys are not strictly ascending after the
  continuation (a server that ignored the sort or the filter), a 200 response
  carrying an ArcGIS `error` member, and a page larger than requested.
* A server answering fewer rows than requested (`maxRecordCount`,
  `exceededTransferLimit`) is harmless: the next page continues after the last
  key returned. An empty page derives no continuation and ends the pass.

## What it does not establish

Coverage is `none`. A completed walk proves each returned feature's values at
the moment its page was read; it is not a snapshot, and a feature missing from
the walk proves nothing, so no deletion is ever published. Layer definition
queries, view filters and feature-level security narrow what the server returns
without saying so. Object ids reassigned by truncate-and-append or a republish
look like new features; the old keys stay published. Hosted qualification
against a real service has not been run.

## Change tracking (not declared)

`extractChanges` (services advertising `supportsChangeTracking`) is not
declared, because the current HTTP contract cannot carry it with host-verified
evidence:

* It answers `edits[].features.{adds, updates, deleteIds}` with the next
  `layerServerGens[].serverGen`. `deleteIds` are bare integers, and record or
  feed evidence reads keys and presence from objects; there is no arm that
  reads a deletion from a scalar array, and one response cannot project two
  readings (upserts and deletes) of the same collection.
* Its features are Esri JSON only (`dataFormat` is `json` or `sqlite`), in the
  layer's spatial reference. Publishing them under the geometry profile needs a
  host-owned Esri JSON to GeoJSON decoder, and a non-WGS84 layer needs
  reprojection, which the profile forbids.
* Bootstrapping needs a snapshot/serverGen handoff: a generation captured
  before the keyset walk, then changes after it, with `minServerGen` beyond the
  retained generation reported as a reset. No existing protocol spells that
  handoff for a separate snapshot endpoint.
* Large extractions answer asynchronously with a `statusUrl` and later a
  `resultUrl`.

## Provider references

Provider references and prerequisites are maintained in the connector guidance above. No separate provider-documentation review date is recorded.

## Source and evidence

[Canonical connector source](https://github.com/bijectionhq/component-support/blob/b632604330ce9cbcfe17a5a680ef4fbe80f6f672/packages/connectors/src/connectors/arcgis/README.md), [native analysis](https://github.com/bijectionhq/component-support/blob/b632604330ce9cbcfe17a5a680ef4fbe80f6f672/packages/connectors/contract-analysis.json) and [check receipts](https://github.com/bijectionhq/component-support/blob/b632604330ce9cbcfe17a5a680ef4fbe80f6f672/packages/connectors/evidence.json).

Connector artifact: `905888ea276a2a28e36981a79e8142b2547ea451c3e63162cb6915ad4a7d1305`.

The resource declaration examples above are compiled and compared with exact catalog declarations. Recorded checks apply only to their source, declaration and runtime identities. Configure a connection and inspect its status to establish deployment-specific readiness.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.