Fields are the core spatial entity in Leaf. You can create them manually with a boundary polygon, sync them from connected providers, or both. This page covers listing, reading, and mutating fields and their boundaries.
Listing fields
GET /services/fields/api/fields
Returns a paginated list of fields across all Leaf users. Filter by leafUserId, status, type, provider, farmId, and more. The default page size is 20.
curl -X GET \
-H 'Authorization: Bearer YOUR_TOKEN' \
'https://api.withleaf.io/services/fields/api/fields?leafUserId=UUID&status=PROCESSED&page=0&size=10'
See API Reference: Fields for the full parameter table including time-range filters, operation-linked filters, and sort options.
Getting a field
GET /services/fields/api/users/{leafUserId}/fields/{id}
Returns a single field by its ID for the specified Leaf user. See API Reference: Fields for details.
Creating a field
To create a field manually, POST a GeoJSON MultiPolygon geometry to the fields endpoint. Leaf creates both the field and its first active boundary from the geometry you provide.
POST /services/fields/api/users/{leafUserId}/fields
curl -X POST \
-H 'Authorization: Bearer YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{
"name": "North Quarter",
"geometry": {
"type": "MultiPolygon",
"coordinates": [[[[
[-93.4880, 41.7710],
[-93.4800, 41.7710],
[-93.4800, 41.7600],
[-93.4880, 41.7600],
[-93.4880, 41.7710]
]]]]
}
}' \
'https://api.withleaf.io/services/fields/api/users/{leafUserId}/fields'
You can optionally set id and name on the request body. If you omit id, Leaf generates a UUID. The id cannot be changed after creation.
Updating a field
PATCH /services/fields/api/users/{leafUserId}/fields/{id}
You can update name, farmId, and geometry on manually created fields. Provider-created fields must be updated through the provider platform.
If you update the geometry, Leaf creates a new active boundary and sets the old one to inactive.
Getting boundaries
Every field can have multiple boundaries, but only one is active at a time. Leaf keeps a full history of boundary changes, so the list endpoint returns both active and inactive records.
GET /services/fields/api/users/{leafUserId}/fields/{fieldId}/boundaries
Returns all boundaries for a field, including inactive and historical records. Each boundary has a status (ACTIVE, INACTIVE, OUTDATED_ON_PROVIDER, or DELETED_ON_PROVIDER) that indicates its lifecycle state.
GET /services/fields/api/users/{leafUserId}/fields/{fieldId}/boundary
Returns only the currently active boundary for a field.
GET /services/fields/api/users/{leafUserId}/fields/{fieldId}/boundaries/{boundaryId}
Returns a specific boundary by its ID. See API Reference: Fields for response details.
Getting operation files for a field
GET /services/fields/api/users/{leafUserId}/fields/{fieldId}/operations/files
Returns operation files (harvested, planted, applied, tillage) associated with this specific field. These are the same operations available through the Operations endpoints, scoped to the field’s boundary. You can filter by operationType, provider, crop, variety, and time range.
GET /services/fields/api/users/{leafUserId}/fields/{fieldId}/operations/files/{fileId}
Returns a single operation file for the field. See API Reference: Fields for the full parameter list.
Updating the active boundary
PUT /services/fields/api/users/{leafUserId}/fields/{fieldId}/boundary
This replaces the active boundary with a new geometry. The previous active boundary is preserved as an inactive historical record.
Syncing fields from providers
When fieldsAutoSync is enabled, Leaf pulls field boundaries from all connected providers automatically. To trigger a manual sync:
POST /services/fields/api/users/{leafUserId}/fields/sync
This schedules a sync for the Leaf user. New fields from the provider appear after the sync completes. Changed boundaries on the provider side produce new boundary records in Leaf.
Preview mode
When customDataSync is enabled, newly synced fields arrive in PREVIEW status. Preview fields have metadata (name, provider info) but no boundary geometry. To fully activate a field:
POST /services/fields/api/users/{leafUserId}/fields/{id}/enableSync
The field status changes to WAITING, and its boundary is fetched in the next sync window. After processing, the status becomes PROCESSED.
You can activate all fields under a grower at once using POST /growers/enableSync with a list of grower IDs.
Finding fields by geometry
POST /services/fields/api/users/{leafUserId}/fields/intersects
Send a MultiPolygon geometry in the request body and Leaf returns all fields that overlap it. The intersectionThreshold parameter (default 0.01, range 0.01–100) controls the minimum overlap percentage required. Leaf checks both “intersection by field” and “intersection by geometry” ratios, and returns the field if either exceeds the threshold.
Deleting a field
DELETE /services/fields/api/users/{leafUserId}/fields/{fieldId}
Only manually created fields can be deleted. Provider-created fields cannot be deleted from the Leaf side.
Uploading fields to a provider
POST /services/fields/api/users/{leafUserId}/fields/{fieldId}/integration/{providerName}
You can push a Leaf field boundary to John Deere or Climate FieldView. The field must already exist in Leaf. Leaf prevents sending a field back to the provider it came from to avoid recursive syncs.
For John Deere, add the organizationId query parameter.
What to do next
- Fields Overview — The Grower/Farm/Field hierarchy and boundary model.
- Uploading Boundaries — Create fields in bulk from shapefiles, GeoJSON, or KML.
- Growers — Manage the grower layer of the hierarchy.
- API Reference: Fields — Full endpoint reference with all parameters, query filters, pagination options, and response schemas.