Use the fields service to manage field records, field boundaries, boundary history, preview-field activation, spatial intersection queries, and farm records. This page is the reference for CRUD operations and field-level sync behavior after you already understand the Leaf field model.
For conceptual background, see Fields Overview and Managing Fields.
Base URL
https://api.withleaf.io/services/fields/api
Endpoints
| Endpoint | Method | Path |
|---|
| Get all fields | GET | /fields |
| Get a field | GET | /users/{leafUserId}/fields/{id} |
| Create a field | POST | /users/{leafUserId}/fields |
| Update a field | PATCH | /users/{leafUserId}/fields/{id} |
| Delete a field | DELETE | /users/{leafUserId}/fields/{id} |
| Get all operation files of a field | GET | /users/{leafUserId}/fields/{fieldId}/operations/files |
| Get an operation file of a field | GET | /users/{leafUserId}/fields/{fieldId}/operations/files/{fileId} |
| Get fields by geometry | POST | /users/{leafUserId}/fields/intersects |
| Get intersection of fields | POST | /users/{leafUserId}/fields/intersect |
| Sync fields manually | POST | /users/{leafUserId}/fields/sync |
| Enable a preview field | POST | /users/{leafUserId}/fields/{id}/enableSync |
| Upload a field to provider | POST | /users/{leafUserId}/fields/{fieldId}/integration/{providerName} |
| Get all boundaries | GET | /users/{leafUserId}/fields/{fieldId}/boundaries |
| Get a boundary | GET | /users/{leafUserId}/fields/{fieldId}/boundaries/{boundaryId} |
| Get active boundary | GET | /users/{leafUserId}/fields/{fieldId}/boundary |
| Update active boundary | PUT | /users/{leafUserId}/fields/{fieldId}/boundary |
| Get all farms | GET | /farms |
| Get a farm | GET | /users/{leafUserId}/farms/{id} |
| Create a farm | POST | /users/{leafUserId}/farms |
| Update a farm | PUT | /users/{leafUserId}/farms/{id} |
Fields
Get all fields
GET /fields
Returns a paginated list of fields across all Leaf users. You can narrow results with query parameters.
Parameters
| Parameter | Type | Description |
|---|
leafUserId | string (UUID) | Filter by Leaf user. |
id | string (UUID) | Filter by field ID. |
name | string | Filter by field name. |
type | string | Field type (ORIGINAL, MERGED). |
farmId | integer | Filter by farm ID. |
provider | string | Filter by provider name (JohnDeere, ClimateFieldView, CNHI, Trimble, Leaf). |
organizationId | string | Filter by provider organization ID. |
mergedFieldId | string (UUID) | Filter by merged field ID. |
providerFieldId | string | Filter by the field ID on the provider side. |
providerFieldName | string | Filter by the field name on the provider side. |
legacy | boolean | Filter by legacy field status. |
status | string | Filter by field status (PROCESSED, PREVIEW, WAITING). |
providerStatus | string | Filter by provider-side status. |
beforeCreatedTime | string (ISO 8601) | Fields created before this time. |
afterCreatedTime | string (ISO 8601) | Fields created after this time. |
beforeUpdatedTime | string (ISO 8601) | Fields updated before this time. |
afterUpdatedTime | string (ISO 8601) | Fields updated after this time. |
operationType | string | Filter by operation type (harvested, planted, applied, tillage). |
operationProvider | string | Filter by provider on associated operations. |
operationStartTime | string (ISO 8601) | Filter fields with operations starting after this time. |
operationEndTime | string (ISO 8601) | Filter fields with operations ending before this time. |
operationCrop | string | Filter by crop name on associated operations. |
operationVariety | string | Filter by variety name on associated operations. |
page | integer | Page number (default 0). |
size | integer | Page size (default 20, max 100). |
sort | string | Sorting order. Comma-separated fields with optional ,asc or ,desc suffix. |
The default page size is 20 when page and size are not set.
Request
curl -X GET \
-H 'Authorization: Bearer YOUR_TOKEN' \
'https://api.withleaf.io/services/fields/api/fields?leafUserId=UUID&status=PROCESSED&page=0&size=10'
Response
[
{
"id": "1a952614-3673-4d1e-b677-1f7224339ec6",
"leafUserId": "58800d61-91ac-4922-8e2a-f0216b9f052a",
"boundaries": ["279b52d5-ec6d-4459-a06a-4f47ffab0659"],
"providerName": "JohnDeere",
"providerId": 2,
"providerFieldId": "b96ed268-728f-489e-b928-9d3e70082be4",
"providerBoundaryId": "125fc49f-7e75-43fe-89f2-af976addb392",
"providerFieldName": "North Quarter",
"organizationId": "428214",
"type": "ORIGINAL",
"farmId": 3746117,
"mergedFieldId": "f97c5bbc-2dbf-4400-8d59-39eba37f8847",
"sources": [],
"status": "PROCESSED",
"createdTime": "2021-10-20T21:21:24.732030Z",
"updatedTime": "2021-11-03T01:34:15.154051Z"
}
]
Get a field
GET /users/{leafUserId}/fields/{id}
Returns a single field for the specified Leaf user.
Parameters
| Parameter | Type | Description |
|---|
leafUserId | path (UUID) | The Leaf user ID. |
id | path (UUID) | The field ID. |
Request
curl -X GET \
-H 'Authorization: Bearer YOUR_TOKEN' \
'https://api.withleaf.io/services/fields/api/users/{leafUserId}/fields/{id}'
Response
Returns a single field object (same shape as the objects in the Get all fields response).
Create a field
POST /users/{leafUserId}/fields
Creates a field for the specified Leaf user. The request body must include a geometry property with type set to MultiPolygon.
You can optionally set id and name. If you omit id, Leaf generates a UUID. The id cannot be changed after creation.
Parameters
| Parameter | Type | Description |
|---|
leafUserId | path (UUID) | The Leaf user ID. |
Request body
{
"name": "North Quarter",
"geometry": {
"type": "MultiPolygon",
"coordinates": [[[
[-93.48821, 41.77137],
[-93.48817, 41.77143],
[-93.48821, 41.76068],
[-93.48821, 41.77137]
]]]
}
}
Request
curl -X POST \
-H 'Authorization: Bearer YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"name":"North Quarter","geometry":{"type":"MultiPolygon","coordinates":[[[[-93.48821,41.77137],[-93.48817,41.77143],[-93.48821,41.76068],[-93.48821,41.77137]]]]}}' \
'https://api.withleaf.io/services/fields/api/users/{leafUserId}/fields'
Response
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"leafUserId": "95eb7d79-b93d-4fc2-877a-3f2b366f8beb",
"area": {
"value": 12.45,
"unit": "ha"
},
"boundaries": ["d0245010-157d-4988-96a2-5f3637098475"],
"geometry": {
"type": "MultiPolygon",
"coordinates": [[[[-93.48821, 41.77137], [-93.48817, 41.77143], [-93.48821, 41.76068], [-93.48821, 41.77137]]]]
},
"type": "ORIGINAL",
"name": "North Quarter",
"status": "PROCESSED",
"createdTime": "2024-01-15T19:48:51.017280Z",
"updatedTime": "2024-01-15T19:48:51.017280Z"
}
Update a field
PATCH /users/{leafUserId}/fields/{id}
Updates a field. You can update name, farmId, and geometry. If you update the geometry, Leaf creates a new active boundary and sets the previous one to inactive.
Parameters
| Parameter | Type | Description |
|---|
leafUserId | path (UUID) | The Leaf user ID. |
id | path (UUID) | The field ID. |
Request body
{
"name": "Updated Field Name",
"farmId": 1538766
}
Request
curl -X PATCH \
-H 'Authorization: Bearer YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"name":"Updated Field Name","farmId":1538766}' \
'https://api.withleaf.io/services/fields/api/users/{leafUserId}/fields/{id}'
Response
Returns the updated field object.
Delete a field
DELETE /users/{leafUserId}/fields/{id}
Deletes a manually created field.
Fields created by a provider cannot be deleted through the API.
Parameters
| Parameter | Type | Description |
|---|
leafUserId | path (UUID) | The Leaf user ID. |
id | path (UUID) | The field ID. |
Request
curl -X DELETE \
-H 'Authorization: Bearer YOUR_TOKEN' \
'https://api.withleaf.io/services/fields/api/users/{leafUserId}/fields/{id}'
Get all operation files of a field
GET /users/{leafUserId}/fields/{fieldId}/operations/files
Returns a paginated list of machine files associated with the specified field.
Parameters
| Parameter | Type | Description |
|---|
leafUserId | path (UUID) | The Leaf user ID. |
fieldId | path (UUID) | The field ID. |
id | string | Filter by file ID. |
operationType | string | harvested, planted, applied, or tillage. |
provider | string | CNHI, JohnDeere, Trimble, ClimateFieldView, AgLeader, Stara, or Leaf. |
origin | string | provider, automerged, merged, or uploaded. |
crop | string | Crop name filter. |
variety | string | Variety name filter. |
startTime | string (ISO 8601) | Files with operations starting after this time. |
endTime | string (ISO 8601) | Files with operations ending before this time. |
page | integer | Page number (default 0). |
size | integer | Page size (default 20, max 100). |
sort | string | Sorting order with optional ,asc or ,desc suffix. |
Request
curl -X GET \
-H 'Authorization: Bearer YOUR_TOKEN' \
'https://api.withleaf.io/services/fields/api/users/{leafUserId}/fields/{fieldId}/operations/files?operationType=harvested'
Response
[
{
"id": "abbac24d-7f13-414a-989a-ee5dc9de624b",
"operationType": "harvested",
"origin": "automerged",
"startTime": "2017-10-27T08:59:58Z",
"endTime": "2017-10-27T09:40:33Z",
"crops": ["corn"],
"varieties": ["Corn"],
"providerFileId": "cacde0d5-55b9-4bff-bf2c-05ec1def1c95",
"provider": "Leaf",
"leafUserId": "dcb6fd16-b6f4-40bc-805e-659c7f7350d6"
}
]
Get an operation file of a field
GET /users/{leafUserId}/fields/{fieldId}/operations/files/{fileId}
Returns a single machine file associated with the specified field.
Parameters
| Parameter | Type | Description |
|---|
leafUserId | path (UUID) | The Leaf user ID. |
fieldId | path (UUID) | The field ID. |
fileId | path (UUID) | The file ID. |
Request
curl -X GET \
-H 'Authorization: Bearer YOUR_TOKEN' \
'https://api.withleaf.io/services/fields/api/users/{leafUserId}/fields/{fieldId}/operations/files/{fileId}'
Response
{
"id": "75127023-190a-4579-b76c-ccbcfcf00d3c",
"operationType": "harvested",
"origin": "automerged",
"startTime": "2017-10-27T08:59:58Z",
"endTime": "2017-10-27T09:40:33Z",
"crops": ["corn"],
"varieties": ["Corn"],
"providerFileId": "a3602817-57e4-4056-bdef-4fb687ba4c2e",
"provider": "Leaf",
"leafUserId": "01a17a22-e6fa-4d83-b343-ea23eddbd936"
}
Get fields by geometry
POST /users/{leafUserId}/fields/intersects
Returns all fields that intersect with the provided GeoJSON MultiPolygon geometry.
The intersectionThreshold parameter (default 0.01, range 0.01–100) sets the minimum overlap percentage required. The API checks both “intersection by field” and “intersection by geometry” ratios and returns the field if either exceeds the threshold.
Parameters
| Parameter | Type | Description |
|---|
leafUserId | path (UUID) | The Leaf user ID. |
Request body
{
"geometry": {
"type": "MultiPolygon",
"coordinates": [[[
[-93.48821, 41.77137],
[-93.48817, 41.77143],
[-93.48821, 41.76068],
[-93.48821, 41.77137]
]]]
},
"intersectionThreshold": 3
}
Request
curl -X POST \
-H 'Authorization: Bearer YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"geometry":{"type":"MultiPolygon","coordinates":[[[[-93.48821,41.77137],[-93.48817,41.77143],[-93.48821,41.76068],[-93.48821,41.77137]]]]},"intersectionThreshold":3}' \
'https://api.withleaf.io/services/fields/api/users/{leafUserId}/fields/intersects'
Response
Returns a list of field objects that match the intersection criteria.
Get intersection of fields
POST /users/{leafUserId}/fields/intersect
Returns the MultiPolygon geometry representing the intersection of the specified fields.
Parameters
| Parameter | Type | Description |
|---|
leafUserId | path (UUID) | The Leaf user ID. |
Request body
["field-id-1", "field-id-2"]
Request
curl -X POST \
-H 'Authorization: Bearer YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '["field-id-1", "field-id-2"]' \
'https://api.withleaf.io/services/fields/api/users/{leafUserId}/fields/intersect'
Response
{
"type": "MultiPolygon",
"coordinates": [[[
[-89.84388, 39.71943],
[-89.84392, 39.72439],
[-89.83936, 39.72539],
[-89.83928, 39.71951],
[-89.84388, 39.71943]
]]]
}
Sync fields manually
POST /users/{leafUserId}/fields/sync
Schedules a sync to fetch field boundaries from connected providers. Use this when fieldsAutoSync is disabled.
Parameters
| Parameter | Type | Description |
|---|
leafUserId | path (UUID) | The Leaf user ID. |
Request
curl -X POST \
-H 'Authorization: Bearer YOUR_TOKEN' \
'https://api.withleaf.io/services/fields/api/users/{leafUserId}/fields/sync'
Enable a preview field
POST /users/{leafUserId}/fields/{id}/enableSync
Removes a field from PREVIEW mode and queues it for the next sync. The field status changes to WAITING, and after syncing it becomes PROCESSED.
Use this when the
customDataSync configuration is enabled. You can also activate all fields under a grower at once with the
growers enableSync endpoint.
Parameters
| Parameter | Type | Description |
|---|
leafUserId | path (UUID) | The Leaf user ID. |
id | path (UUID) | The field ID. |
Request
curl -X POST \
-H 'Authorization: Bearer YOUR_TOKEN' \
'https://api.withleaf.io/services/fields/api/users/{leafUserId}/fields/{id}/enableSync'
Upload a field to provider
POST /users/{leafUserId}/fields/{fieldId}/integration/{providerName}
Pushes a Leaf field boundary to a connected provider. Supported providers: JohnDeere, ClimateFieldView.
The API prevents sending a field back to the provider it was fetched from to avoid recursive syncs.
Parameters
| Parameter | Type | Description |
|---|
leafUserId | path (UUID) | The Leaf user ID. |
fieldId | path (UUID) | The field ID. |
providerName | path (string) | JohnDeere or ClimateFieldView. |
organizationId | query (string) | Required for John Deere uploads. |
Request
curl -X POST \
-H 'Authorization: Bearer YOUR_TOKEN' \
'https://api.withleaf.io/services/fields/api/users/{leafUserId}/fields/{fieldId}/integration/JohnDeere?organizationId=428214'
Response
Returns one object keyed by the Leaf field ID. Inside that object, the provider name maps to the provider-specific upload response.
{
"ba518264-7f2a-11ee-b962-0242ac120002": {
"JohnDeere": {
"field_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"farm_id": "f1e2d3c4-b5a6-7890-abcd-ef1234567890",
"grower_id": "g1h2i3j4-k5l6-7890-abcd-ef1234567890",
"boundary_id": "b1c2d3e4-f5a6-7890-abcd-ef1234567890"
}
}
}
Boundaries
Get all boundaries
GET /users/{leafUserId}/fields/{fieldId}/boundaries
Returns all boundaries (active and inactive) for a field. Leaf keeps a history of all boundary changes.
Parameters
| Parameter | Type | Description |
|---|
leafUserId | path (UUID) | The Leaf user ID. |
fieldId | path (UUID) | The field ID. |
Request
curl -X GET \
-H 'Authorization: Bearer YOUR_TOKEN' \
'https://api.withleaf.io/services/fields/api/users/{leafUserId}/fields/{fieldId}/boundaries'
Response
[
{
"id": "90060545-d448-493a-965f-625a17916067",
"status": "ACTIVE",
"geometry": {
"type": "MultiPolygon",
"coordinates": [[[
[-89.84392, 39.72439],
[-89.84388, 39.71943],
[-89.83928, 39.71951],
[-89.83936, 39.72539],
[-89.84392, 39.72439]
]]]
},
"area": {
"value": 23.659,
"unit": "ha"
},
"validity": "VALID",
"createdTime": "2024-01-10T03:33:51.528534Z",
"updatedTime": "2024-01-10T03:33:51.528534Z"
}
]
Get a boundary
GET /users/{leafUserId}/fields/{fieldId}/boundaries/{boundaryId}
Returns a single boundary by ID.
Parameters
| Parameter | Type | Description |
|---|
leafUserId | path (UUID) | The Leaf user ID. |
fieldId | path (UUID) | The field ID. |
boundaryId | path (UUID) | The boundary ID. |
Request
curl -X GET \
-H 'Authorization: Bearer YOUR_TOKEN' \
'https://api.withleaf.io/services/fields/api/users/{leafUserId}/fields/{fieldId}/boundaries/{boundaryId}'
Response
Returns a single boundary object (same shape as objects in the Get all boundaries response).
Get active boundary
GET /users/{leafUserId}/fields/{fieldId}/boundary
Returns the currently active boundary for a field.
Parameters
| Parameter | Type | Description |
|---|
leafUserId | path (UUID) | The Leaf user ID. |
fieldId | path (UUID) | The field ID. |
Request
curl -X GET \
-H 'Authorization: Bearer YOUR_TOKEN' \
'https://api.withleaf.io/services/fields/api/users/{leafUserId}/fields/{fieldId}/boundary'
Response
Returns a single boundary object.
Update active boundary
PUT /users/{leafUserId}/fields/{fieldId}/boundary
Replaces the active boundary with a new geometry. The previous active boundary is preserved as an inactive historical record.
Parameters
| Parameter | Type | Description |
|---|
leafUserId | path (UUID) | The Leaf user ID. |
fieldId | path (UUID) | The field ID. |
Request body
{
"geometry": {
"type": "MultiPolygon",
"coordinates": [[[
[-93.48821, 41.77137],
[-93.48817, 41.77143],
[-93.48821, 41.76068],
[-93.48821, 41.77137]
]]]
}
}
Request
curl -X PUT \
-H 'Authorization: Bearer YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"geometry":{"type":"MultiPolygon","coordinates":[[[[-93.48821,41.77137],[-93.48817,41.77143],[-93.48821,41.76068],[-93.48821,41.77137]]]]}}' \
'https://api.withleaf.io/services/fields/api/users/{leafUserId}/fields/{fieldId}/boundary'
Response
{
"id": "g7941ef8-iddf-42c1-b43c-d36b0df369e8",
"status": "ACTIVE",
"geometry": {
"type": "MultiPolygon",
"coordinates": [[[
[-93.48821, 41.77137],
[-93.48817, 41.77143],
[-93.48821, 41.76068],
[-93.48821, 41.77137]
]]]
},
"area": {
"value": 0.197,
"unit": "ha"
},
"validity": "VALID",
"createdTime": "2024-01-15T19:48:51.017280Z",
"updatedTime": "2024-01-15T19:48:51.017280Z"
}
Farms
Get all farms
GET /farms
Returns a paginated list of all farms.
Parameters
| Parameter | Type | Description |
|---|
leafUserId | string (UUID) | Filter by Leaf user. |
growerId | integer | Filter by grower ID. |
provider | string | Filter by provider name. |
name | string | Filter by farm name. |
providerFarmId | string | Filter by the farm ID on the provider side. |
page | integer | Page number (default 0). |
size | integer | Page size (default 20, max 100). |
sort | string | Sorting order with optional ,asc or ,desc suffix. |
Request
curl -X GET \
-H 'Authorization: Bearer YOUR_TOKEN' \
'https://api.withleaf.io/services/fields/api/farms?leafUserId=UUID'
Response
[
{
"id": 1538766,
"name": "Main Farm",
"providerId": 2,
"providerName": "JohnDeere",
"providerFarmId": "2f4a03ed-ac81-4c6d-810d-1db6b47baec2",
"providerFarmName": "Main Farm",
"leafUserId": "ace92e9c-2e83-4d85-ab34-1f76a480abc8",
"fieldIds": ["6595418e-11d2-4260-9e6b-e8c452fb8375"],
"growerId": 12345,
"createdTime": "2024-01-06T09:34:11.759672Z",
"updatedTime": "2024-01-07T09:15:42.855759Z"
}
]
Get a farm
GET /users/{leafUserId}/farms/{id}
Returns a single farm by ID.
Parameters
| Parameter | Type | Description |
|---|
leafUserId | path (UUID) | The Leaf user ID. |
id | path (integer) | The farm ID. |
Request
curl -X GET \
-H 'Authorization: Bearer YOUR_TOKEN' \
'https://api.withleaf.io/services/fields/api/users/{leafUserId}/farms/{id}'
Response
Returns a single farm object (same shape as objects in the Get all farms response).
Create a farm
POST /users/{leafUserId}/farms
Creates a farm for the specified Leaf user.
Parameters
| Parameter | Type | Description |
|---|
leafUserId | path (UUID) | The Leaf user ID. |
Request body
{
"name": "South Farm",
"growerId": 873300016
}
Request
curl -X POST \
-H 'Authorization: Bearer YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"name":"South Farm","growerId":873300016}' \
'https://api.withleaf.io/services/fields/api/users/{leafUserId}/farms'
Response
Returns the created farm object.
Update a farm
PUT /users/{leafUserId}/farms/{id}
Updates a farm’s name and/or growerId.
Parameters
| Parameter | Type | Description |
|---|
leafUserId | path (UUID) | The Leaf user ID. |
id | path (integer) | The farm ID. |
Request body
{
"name": "Updated Farm Name",
"growerId": 873300016
}
Request
curl -X PUT \
-H 'Authorization: Bearer YOUR_TOKEN' \
-H 'Content-Type: application/json' \
-d '{"name":"Updated Farm Name","growerId":873300016}' \
'https://api.withleaf.io/services/fields/api/users/{leafUserId}/farms/{id}'
Response
Returns the updated farm object.