Endpoints

About

Here we list all the available endpoints from Fields API. For easily calling them, we recommend using Leaf's Postman collection.

All HTTP methods should be prepended by this service's endpoint:

https://api.withleaf.io/services/fields/api

There is a REST resources section if you want to check it out.

This service has the following endpoints available:

DescriptionEndpoints
Get all fieldsGET /fields
Get a fieldGET /users/{id}/fields/{id}
Create a fieldPOST /users/{id}/fields
Get all operations of a fieldGET /users/{id}/fields/{id}/operations
Get an operation of a fieldGET /users/{id}/fields/{id}/operations/{id}
Get fields by geometry (deprecated)POST /fields/query/intersects
Get fields by geometryPOST /users/{leafUserId}/fields/intersects
Get intersection of fieldsPOST /users/{id}/fields/intersect
Delete a fieldDELETE /users/{id}/fields/{id}
Get all boundaries from fieldGET users/{leafUserId}/fields/{fieldId}/boundaries
Get a boundary from fieldGET users/{leafUserId}/fields/{fieldId}/boundaries/{boundaryId}
Get active boundary from fieldGET users/{leafUserId}/fields/{fieldId}/boundary
Update active boundary from fieldPUT users/{leafUserId}/fields/{fieldId}/boundary
Get all farmsGET /farms
Get a farmGET /users/{id}/farms/{id}
Get all growersGET /growers
Get a growerGET /growers/{id}

Endpoints

Get all fields

 GET /fields

Gets a paged list of Fields. It is possible to filter the results by passing some query parameters.

  • type, only matches fields with this type (string).
  • provider, only matches fields from this provider (string).
  • leafUserId, only matches fields from this user (string).
  • page, an integer specifying the page being fetched.
  • size, an integer specifying the size of the page (defaults to 20).

These last two parameters are used exclusively for paging through results.

Response

A JSON array containing Fields.

curl -X GET \
-H 'Authorization: Bearer YOUR_TOKEN' \
'https://api.withleaf.io/services/fields/api/fields'

Get a field

 GET /users/{id}/fields/{id}

Gets a single Field by its id.

Response

A single Field as a JSON object.

curl -X GET \
-H 'Authorization: Bearer YOUR_TOKEN' \
'https://api.withleaf.io/services/fields/api/users/{leafUserId}/fields/{id}'

Create a field

 POST /users/{id}/fields

Creates a Field for the user leafUserId. A resquest body must be provided containing the an entry "geometry", which represents the boundaries of the Field being created as a GeoJSON geometry (it must be a "MultiPolygon"). The entry "id" is optional. If no id is provided, an UUID will be generated. The Field id CAN NOT be updated.

Request body example:

{
"geometry": {
"type": "MultiPolygon",
"coordinates": [
[
[
[-93.48821327980518, 41.77137549568163],
[-93.48817333680519, 41.77143534378164],
[-93.48821327390516, 41.76068857977987],
[-93.48821327980518, 41.77137549568163]
]
]
]
}
}

Response

A Field as a JSON object.

curl -X POST \
-H 'Authorization: Bearer YOUR_TOKEN' \
-d '{ "geometry": { "type: "MultiPolygon", "geometry": [...] } }'
'https://api.withleaf.io/services/fields/api/fields/users/{leafUserId}/{id}'

Get all operations of a field

 GET /users/{id}/fields/{id}/operations

Gets a paged list of all operation files of the Field and Leaf User specified in the URL.

It is possible to filter the results by passing some query parameters. They are listed below.

Parameter (to filter by)TypeDescription
operationTypeString "harvested", "planted", "applied" or "other"retrieve operations of given type
providerString "CNHI", "JohnDeere", "Trimble" or "ClimateFieldView"retrieve operations of given provider
originString "provider", "automerged", "merged" or "uploaded"retrieve operations of given origin
cropString name of the crop, like "corn" or "soybeans". Entire crop list available hereretrieve operations with this crop.
startTimeISO 8601 datetime formatretrieve operations that started after this date
endTimeISO 8601 datetime formatretrieve operations that ended before this date

You can also pass some parameters used exclusively for paging through results. They are:

  • page, an integer specifying the page being fetched (default is 0)
  • size, an integer specifying the size of the page (default is 20, max is 100)

Response

A JSON array of Files.

curl -X GET \
-H 'Authorization: Bearer YOUR_TOKEN' \
'https://api.withleaf.io/services/fields/api/users/{leafUserId}/fields/{fieldId}/operations'

Get an operation of a field

 GET /users/{id}/fields/{id}/operations/{id}

Gets a single Operation File of a field by its id.

Response

A single Operation File.

curl -X GET \
-H 'Authorization: Bearer YOUR_TOKEN' \
'https://api.withleaf.io/services/fields/api/users/{leafUserId}/fields/{fieldId}/operations/{id}'

Get Fields by geometry (deprecated)

 POST /fields/query/intersects

Use this endpoint instead.

Gets a list of fields that intersect with the GeoJSON MultiPolygon sent in the request body.

Response

A JSON list of Fields.

curl -X POST \
-H 'Authorization: Bearer YOUR_TOKEN' \
-d '{ "geometry": { "type: "MultiPolygon", "geometry": [...] } }'
'https://api.withleaf.io/services/fields/api/fields/query/intersects'

Get Fields by geometry

 POST /users/{leafUserId}/fields/intersects

Gets a list of fields that intersect with the GeoJSON MultiPolygon sent in the request body. The minimum intersection percentage is given by intersectionThreshold, its default value is 0.01%.

Response

A JSON list of Fields.

curl -X POST \
-H 'Authorization: Bearer YOUR_TOKEN' \
-d '{ "geometry": { "type: "MultiPolygon", "coordinates": [...] }, "intersectionThreshold": 25.7 }'
'https://api.withleaf.io/services/fields/api/users/{leafUserId}/fields/intersects'

Get intersection of fields

 POST /users/{id}/fields/intersect

Gets a GeoJSON MultiPolygon corresponding to the intersection of the Fields specified by the given id's. Such Field id's goes in a list, in the request body.

Response

A JSON in the format of a GeoJSON geometry.

curl --location --request \
POST 'https://api.withleaf.io/services/fields/api/users/{id}/fields/intersect' \
--header 'Authorization: Bearer YOUR_LEAF_TOKEN' \
--header 'Content-Type: application/json' \
--data-raw '["id1", "id2"]'

Delete a field

 DELETE /users/{id}/fields/{id}

Deletes the field with the given id.

Get all boundaries from field

 GET /users/{leafUserId}/fields/{fieldId}/boundaries

Gets a list of boundaries from a field.

Response

A list of Boundary as a JSON object.

curl -X GET \
-H 'Authorization: Bearer YOUR_TOKEN' \
'https://api.withleaf.io/services/fields/api/users/{leafUserId}/fields/{id}/boundaries'

Get a boundary from field

 GET /users/{leafUserId}/fields/{fieldId}/boundaries/{boundaryId}

Gets a single Boundary from a field by its id.

Response

A single Boundary as a JSON object.

curl -X GET \
-H 'Authorization: Bearer YOUR_TOKEN' \
'https://api.withleaf.io/services/fields/api/users/{leafUserId}/fields/{fieldId}/boundaries/{boundaryId}'

Get active boundary from field

 GET /users/{leafUserId}/fields/{fieldId}/boundary

Gets the active Boundary from a field.

Response

A single Boundary as a JSON object.

curl -X GET \
-H 'Authorization: Bearer YOUR_TOKEN' \
'https://api.withleaf.io/services/fields/api/users/{leafUserId}/fields/{fieldId}/boundary'

Update active boundary from field

 PUT /users/{leafUserId}/fields/{fieldId}/boundary

Updates the active boundary of field fieldId. The previous active boundary is not deleted, but set as inactive.

Request body example:

{
"geometry": {
"type": "MultiPolygon",
"coordinates": [
[
[
[-93.48821327980518, 41.77137549568163],
[-93.48817333680519, 41.77143534378164],
[-93.48821327390516, 41.76068857977987],
[-93.48821327980518, 41.77137549568163]
]
]
]
}
}

Response

A Field as a JSON object.

curl -X PUT \
-H 'Authorization: Bearer YOUR_TOKEN' \
-d '{ "geometry": { "type: "MultiPolygon", "geometry": [...] } }'
'https://api.withleaf.io/services/fields/api/users/{leafUserId}/fields/{fieldId}/boundary'

Get all farms

 GET /farms

Gets a paged list of all Farms. It is possible to pass some query parameters.

  • provider, only matches Farms from this provider (string)
  • leafUserId, only matches Farms from this Leaf User (UUID)
  • page, an integer specifying the page being fetched
  • size, an integer specifying the size of the page (defaults to 20)

The parameters are used exclusively for paging through results.

Response

A JSON array containing Farms.

curl -X GET \
-H 'Authorization: Bearer YOUR_TOKEN' \
'https://api.withleaf.io/services/fields/api/farms'

Get a farm

 GET /users/{id}/farms/{id}

Gets a single Farm by its id.

Response

A single Farm as a JSON object.

curl -X GET \
-H 'Authorization: Bearer YOUR_TOKEN' \
'https://api.withleaf.io/services/fields/api/users/{leafUserId}/farms/{id}'

Get all growers

 GET /growers

Gets a paged list of all Growers. Use the following parameters for paging through results.

  • provider, only matches Growers from this provider (string)
  • leafUserId, only matches Growers from this Leaf User (UUID)
  • page, an integer specifying the page being fetched
  • size, an integer specifying the size of the page (defaults to 20)

Response

A JSON array containing Growers.

curl -X GET \
-H 'Authorization: Bearer YOUR_TOKEN' \
'https://api.withleaf.io/services/fields/api/growers'

Get a grower

 GET /growers/{id}

Gets a single Grower by its id.

Response

A single Grower as a JSON object.

curl -X GET \
-H 'Authorization: Bearer YOUR_TOKEN' \
'https://api.withleaf.io/services/fields/api/growers/{id}'

REST Resources

See below the REST resources and their endpoints.

Field Resource

A field might have one or neither of the following keys:

  • a "mergedFieldId" key or
  • a "sources" key

A Field will only have one of the previous keys if it is either a field that has been merged with other one(s) or if it is a result of a merge. Leaf merges fields that have any sort of overlap. This makes it easier for you to query operations from a field by querying by the merged field. Because a field might exist in multiple providers, Leaf detects that and creates a single field that you can query for - and you can still query by the individual fields too.

geometry and area are deprecated keys that contains the geometry of the active boundary and its area, respectively.

{
"id": "UUID",
"providerName": "str",
"providerFieldName": "str",
"providerFieldId": "str",
"providerFieldName": "str",
"providerBoundaryId": "UUID",
"type": "ORIGINAL",
"leafUserId": "UUID",
"organizationId": "str",
"mergedFieldId": ["UUID"],
"files": ["UUID"],
"boundaries": ["UUID"],
"geometry": {
"type": "MultiPolygon",
"coordinates": [
[
[
[-93.48821327980518, 41.77137549568163],
[-93.48817333680519, 41.77143534378164],
[-93.48821327390516, 41.76068857977987],
[-93.48821327980518, 41.77137549568163]
]
]
]
},
"area": {
"value": double,
"unit": "ha"
}
}
DescriptionEndpoints
Get all fieldsGET /fields
Get a fieldGET /users/{id}/fields/{id}
Create a fieldPOST /users/{id}/fields
Get fields by geometryPOST /fields/query/intersects
Get intersection of fieldsPOST /users/{id}/fields/intersect
Delete a fieldDELETE /users/{id}/fields/{id}

Boundary Resource

Every Field at Leaf can have 0 or many boundaries. Fields created via Leaf's endpoints must have at least one boundary. Only one boundary may be active, the others are inactive boundaries. Boundaries cannot be deleted or have its geometry updated. Every update generates a new Boundary, and Leaf keeps a history of all seen Boundaries.

Each boundary has a status and providerStatus.

  • status - Represents the current status of the boundary:

    • ACTIVE - If the boundary was created at Leaf, it is the active boundary. If it is from a provider, this boundary exists at the provider and is the active boundary there.
    • INACTIVE - If the boundary was created at Leaf, it is an inactive boundary. If it is from a provider, this boundary exists at the provider and is inactive there.
    • OUTDATED_ON_PROVIDER - The boundary is from a provider. The boundary once existed on the provider exactly as it is in that boundary, but it was edited (e.g. has a new geometry but the same provider boundary id).
    • DELETED_ON_PROVIDER - The boundary is from a provider. The boundary once existed on the provider, but it was deleted. The user won't find that boundary in the provider.
  • providerStatus - Is the status of the boundary on the provider.

    • ACTIVE - The boundary is the active boundary in the provider.
    • INACTIVE - The boundary is inactive in the provider.

providerStatus, just like the geometry, is a static attribute. In case this attribute is changed at the provider, the boundary's status is updated and a new boundary is created with the updated providerStatus in order to maintain history.

{
"id": "UUID",
"status": "ACTIVE",
"geometry": {
"type": "MultiPolygon",
"coordinates": [
[
[
[
-89.84392762184143,
39.72439389620628
],
[
-89.84388470649719,
39.71943436012731
],
[
-89.83928203582764,
39.71951688444436
],
[
-89.83936786651611,
39.725392361998416
],
[
-89.84392762184143,
39.72439389620628
]
]
]
]
},
"area": {
"value": double,
"unit": "ha"
}
}
DescriptionEndpoints
Get all boundaries from fieldGET users/{leafUserId}/fields/{fieldId}/boundaries
Get a boundary from fieldGET users/{leafUserId}/fields/{fieldId}/boundaries/{boundaryId}
Get active boundary from fieldGET users/{leafUserId}/fields/{fieldId}/boundary
Update active boundary from fieldPUT users/{leafUserId}/fields/{fieldId}/boundary

Operation Resource

{
"id": "UUID",
"operationType": "harvested|planted|applied",
"startTime": "ISO date-time",
"endTime": "ISO date-time",
"crops": ["str"],
"varieties": ["str"],
"providerFileId": "str",
"provider": "Trimble",
"origin": "provider|merged|automerged|uploaded",
"leafUserId": "UUID"
}
DescriptionEndpoints
Get all operations of a fieldGET /users/{id}/fields/{id}/operations
Get an operation of a fieldGET /users/{id}/fields/{id}/operations/{id}

Farm Resource

{
"id": "long",
"name": "str",
"providerName": "str",
"providerFarmName": "str",
"providerFarmId": "UUID",
"leafUserId": "UUID",
"growerId": "long",
"fieldIds": ["UUID"]
}
DescriptionEndpoints
Get all farmsGET /farms
Get a farmGET /users/{id}/farms/{id}

Grower Resource

{
"id": 2345,
"leafUserId": "UUID",
"providerName": "str",
"providerOrganizationId": "str",
"providerCompanyId": "str",
"providerUserId": "str",
"providerGrowerId": "str",
"farmIds": [4534]
}
DescriptionEndpoints
Get all growersGET /growers
Get a growerGET /growers/{id}