Download OpenAPI specification:
Farmable API enables seamless integration between Farmable’s farm management platform and external systems such as ERP software, farm machinery, and other agricultural tools.
Farmable is a mobile-first farm management solution built by farmers for farmers. It simplifies daily operations with AI-powered features:
For support, contact [email protected].
The Farmable API is a RESTful service built on OpenAPI principles. It provides read-only access for partners (e.g., companies connected via the Farmable app) and now extends to write capabilities for job submissions.
Rate-Limit-Remaining, Rate-Limit-Retry-After-Seconds2026-07-11T17:15:00Z)api-key header200 OK, 400 Bad Request, 401 Unauthorized, 429 Too Many Requests)errorId to quote when reporting a problemRetrieve crop varieties to which partner has access. Each entry belongs to a field (fieldId) and references its crop (cropId).
[- {
- "cropId": "6e1f1bac-ca2e-4a67-bb6a-93e1ba58b870",
- "fieldId": 0,
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
- "percentage": 0,
- "sowDate": "2019-08-24T14:15:22Z"
}
][- {
- "categoryGroup": "string",
- "categoryType": "string",
- "eppoCode": "string",
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "label": "string",
- "name": "string"
}
]Retrieve equipments to which partner has access.
[- {
- "equipmentType": "string",
- "farmId": 0,
- "id": 0,
- "inspectionDate": "2019-08-24",
- "name": "string",
- "ownEquipment": true,
- "rate": "string",
- "registrationNumber": "string",
- "tankSize": "string"
}
][- {
- "address": "string",
- "businessName": "string",
- "city": "string",
- "coordinate": {
- "x": 0.1,
- "y": 0.1
}, - "country": "string",
- "createdAt": "2019-08-24T14:15:22Z",
- "farmOwner": {
- "email": "string",
- "firstName": "string",
- "id": 0,
- "lastName": "string",
- "mobilePhone": "string"
}, - "id": 0,
- "name": "string",
- "productionMethods": [
- "CONVENTIONAL"
], - "seasonCutoffDate": "string",
- "timeZone": "string",
- "vatNumber": "string",
- "zip": "string"
}
]Create a new fertilizer job for fields.
| completedDate | string <date> ^\d{4}-\d{2}-\d{2}$ Job completion date |
| documentOnSewageSludge | boolean Document on sewage sludge (required for Spanish locations) |
| farmId required | integer <int32> Farm ID |
| fields required | Array of integers <int32> [ items <int32 > ] List of field IDs |
| memberId required | integer <int32> Member ID |
| startDate required | string <date> ^\d{4}-\d{2}-\d{2}$ Job start date |
required | Array of objects (TreatmentInputV1) List of treatments to apply |
{- "completedDate": "2024-01-16",
- "documentOnSewageSludge": true,
- "farmId": 0,
- "fields": [
- 0
], - "memberId": 0,
- "startDate": "2024-01-15",
- "treatments": [
- {
- "amount": 0.1,
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "unit": "GRAM_PER_SQUARE_METER"
}
]
}{- "id": 0
}[- {
- "areaSize": 0.1,
- "averageDistanceBetweenRows": 0.1,
- "averageDistanceBetweenTreesInRows": 0.1,
- "centroid": {
- "x": 0.1,
- "y": 0.1
}, - "comment": "string",
- "farmId": 0,
- "fieldType": "GREEN_HOUSE",
- "harvestAllowedDate": "string",
- "id": 0,
- "name": "string",
- "numberOfPlants": 0,
- "plantHeight": 0.1,
- "productionMethod": "string",
- "productiveArea": 0.1,
- "reentryAllowedDate": "string",
- "registrationNumber": "string",
- "rootstock": "string",
- "treeSupplier": "string",
- "varieties": [
- {
- "category": {
- "categoryGroup": "string",
- "categoryType": "string",
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "label": "string",
- "name": "string"
}, - "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
- "percentage": 0,
- "sowDate": "2019-08-24T14:15:22Z"
}
], - "wktGeometry": "string"
}
]Retrieve harvest logged on the farms you have access to: date, the fields it came from and what was growing on them, the quantity in the unit the farm counts in, and the quality grade the farm assigned. This is the only place harvest appears — /v1/jobs deliberately excludes it, so there is nothing to reconcile between the two. A farm may log harvest on its own or from a job; in the second case jobId is set, for reference, though that job is not returned by /v1/jobs. Filter by harvest date with dateFrom and dateTo, same rules as /v1/jobs: send both or neither, at most 366 days apart, any past season. Paging works the same way too.
| dateFrom | string <date> ^\d{4}-\d{2}-\d{2}$ Example: dateFrom=2026-01-01 Earliest harvest date (inclusive), ISO format. Send together with dateTo. |
| dateTo | string <date> ^\d{4}-\d{2}-\d{2}$ Example: dateTo=2026-12-31 Latest harvest date (inclusive), ISO format. At most 366 days after dateFrom. |
| page | integer >= 0 Default: 0 Zero-based page number. Only meaningful together with pageSize. |
| pageSize | integer [ 1 .. 1000 ] Example: pageSize=500 Records per page, 1 to 1000. Omit to receive the whole window in one response. |
[- {
- "boxes": {
- "count": 0.1,
- "name": "string",
- "size": 0.1,
- "unit": "string"
}, - "comment": "string",
- "countingUnit": "string",
- "createdAt": "string",
- "cropId": "6e1f1bac-ca2e-4a67-bb6a-93e1ba58b870",
- "date": "string",
- "farmId": 0,
- "fields": [
- {
- "areaSize": 0.1,
- "crops": [
- {
- "cropId": "6e1f1bac-ca2e-4a67-bb6a-93e1ba58b870",
- "percentage": 0,
- "sowDate": "string",
- "variety": "string",
- "varietyId": "6e92bc19-63eb-482a-9560-91cc340f6c2a"
}
], - "fieldId": 0,
- "name": "string"
}
], - "id": 0,
- "jobId": 0,
- "pickers": {
- "teamIds": [
- 0
], - "teamLeadAccountIds": [
- 0
], - "teamMemberIds": [
- 0
]
}, - "pieces": 0,
- "quality": 0,
- "variety": "string",
- "weight": {
- "unit": "string",
- "weight": 0.1
}
}
]Retrieve completed and planned activity logged on the farms you have access to: activity type, farm and field IDs, dates, applied products with dosage and unit, the assigned team member, notes and status. Filter by completion date (inclusive, ISO dates). Omitting both bounds returns the last year. The 366-day limit applies to how wide the window is, not how far back it reaches: any past season can be retrieved, one request per season — dateFrom=2024-01-01&dateTo=2024-12-31 is fine. Always send both bounds. Sending only dateFrom leaves the upper bound at today, which for an older start date exceeds the limit and returns 400 rather than quietly narrowing the window. Paging is opt-in: pass pageSize to receive pages ordered by descending job id (a stable key, so records never move between pages) and keep requesting until a page comes back shorter than pageSize. Omit pageSize and the whole window arrives in one response. Harvest is not included here: it has quantities, pickers and its own records, and is served by /v1/harvests. Nothing about a harvest is lost by its absence from this endpoint.
| dateFrom | string <date> ^\d{4}-\d{2}-\d{2}$ Example: dateFrom=2024-01-01 Earliest completion date (inclusive), ISO format. Send together with dateTo. |
| dateTo | string <date> ^\d{4}-\d{2}-\d{2}$ Example: dateTo=2024-12-31 Latest completion date (inclusive), ISO format. At most 366 days after dateFrom. |
| page | integer >= 0 Default: 0 Zero-based page number. Only meaningful together with pageSize. |
| pageSize | integer [ 1 .. 1000 ] Example: pageSize=500 Records per page, 1 to 1000. Omit to receive the whole window in one response. |
[- {
- "activityType": "string",
- "assignedMember": {
- "accountId": 0,
- "firstName": "string",
- "lastName": "string"
}, - "causes": [
- {
- "causeId": "37a69642-48de-402f-9a54-26d0692ba081",
- "eppoCode": "string",
- "name": "string",
- "type": "string"
}
], - "completedDate": "string",
- "createdAt": "string",
- "customJobType": "string",
- "dueDate": "string",
- "farmId": 0,
- "fields": [
- {
- "areaSize": 0.1,
- "crops": [
- {
- "areaSize": 0.1,
- "cropId": "6e1f1bac-ca2e-4a67-bb6a-93e1ba58b870",
- "percentage": 0,
- "sowDate": "string",
- "variety": "string",
- "varietyId": "6e92bc19-63eb-482a-9560-91cc340f6c2a"
}
], - "fieldId": 0,
- "name": "string"
}
], - "id": 0,
- "jobType": "string",
- "notes": [
- {
- "accountId": 0,
- "createdAt": "string",
- "note": "string"
}
], - "startDate": "string",
- "status": "string",
- "treatments": [
- {
- "amount": 0.1,
- "productId": "dcd53ddb-8104-4e48-8cc0-5df1088c6113",
- "productName": "string",
- "productType": "string",
- "registeredCropId": "bf01498d-02dc-44af-8580-fb0c8cefa709",
- "unit": "string"
}
]
}
]Retrieve weather conditions (temperature, wind, precipitation) logged against a specific job. Farmer-logged weather takes precedence over automatically recorded weather (see the source field).
| jobId required | integer >= 1 Example: 42 Job ID. |
{- "jobId": 0,
- "loggedAt": "string",
- "precipitation": 0.1,
- "source": "string",
- "temperature": 0.1,
- "windDirection": "string",
- "windSpeed": 0.1
}[- {
- "boxSize": 0.1,
- "boxVolume": 0.1,
- "category": {
- "categoryGroup": "string",
- "categoryType": "string",
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "label": "string",
- "name": "string"
}, - "countingUnit": "BOXES",
- "date": "2019-08-24",
- "fieldIds": [
- 0
], - "harvestDates": [
- "2019-08-24"
], - "id": 0,
- "variety": "string",
- "volume": 0.1
}
]Create a new spray job for fields.
| causeIds required | Array of strings <uuid> [ items <uuid > ] List of cause IDs |
| completedDate | string Job completion date |
| equipmentId required | integer <int32> Equipment ID |
| farmId required | integer <int32> Farm ID |
| fields required | Array of integers <int32> [ items <int32 > ] List of field IDs |
| justificationIds required | Array of strings <uuid> [ items <uuid > ] List of justification IDs |
| memberId required | integer <int32> Member ID |
| startDate required | string Job start date |
required | Array of objects (TreatmentInputV1) List of treatments to apply |
{- "causeIds": [
- "497f6eca-6276-4993-bfeb-53cbbbba6f08"
], - "completedDate": "2024-01-16",
- "equipmentId": 0,
- "farmId": 0,
- "fields": [
- 0
], - "justificationIds": [
- "497f6eca-6276-4993-bfeb-53cbbbba6f08"
], - "memberId": 0,
- "startDate": "2024-01-15",
- "treatments": [
- {
- "amount": 0.1,
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "unit": "GRAM_PER_SQUARE_METER"
}
]
}{- "id": 0
}Retrieve all timesheet records including date, start time, end time and duration in hours. Records without an end time belong to team members that are still clocked in. Records without a team member ID were recorded by the team lead for the whole team. Optionally filter by start date (inclusive, ISO date).
| dateFrom | string <date> ^\d{4}-\d{2}-\d{2}$ Example: dateFrom=2026-01-01 Earliest start date (inclusive), ISO format. |
| dateTo | string <date> ^\d{4}-\d{2}-\d{2}$ Example: dateTo=2026-01-31 Latest start date (inclusive), ISO format. |
[- {
- "comment": "string",
- "date": "2019-08-24",
- "durationHours": 0.1,
- "endTime": "2019-08-24T14:15:22Z",
- "farmId": 0,
- "fieldIds": [
- 0
], - "id": 0,
- "startTime": "2019-08-24T14:15:22Z",
- "teamId": 0,
- "teamLeadId": 0,
- "teamMemberId": 0,
- "teamMemberName": "string",
- "teamName": "string"
}
]Retrieve clock-in (start) times per team member. Entries without a team member ID were recorded by the team lead for the whole team. Optionally filter by date (inclusive, ISO date).
| dateFrom | string <date> ^\d{4}-\d{2}-\d{2}$ Example: dateFrom=2026-01-01 Earliest clock-in date (inclusive), ISO format. |
| dateTo | string <date> ^\d{4}-\d{2}-\d{2}$ Example: dateTo=2026-01-31 Latest clock-in date (inclusive), ISO format. |
[- {
- "clockInTime": "2019-08-24T14:15:22Z",
- "farmId": 0,
- "teamId": 0,
- "teamMemberId": 0,
- "teamMemberName": "string",
- "timesheetId": 0
}
]Retrieve clock-out (end) times per team member. Only records that have been clocked out are returned. Entries without a team member ID were recorded by the team lead for the whole team. Optionally filter by clock-in date (inclusive, ISO date).
| dateFrom | string <date> ^\d{4}-\d{2}-\d{2}$ Example: dateFrom=2026-01-01 Earliest clock-in date (inclusive), ISO format. |
| dateTo | string <date> ^\d{4}-\d{2}-\d{2}$ Example: dateTo=2026-01-31 Latest clock-in date (inclusive), ISO format. |
[- {
- "clockOutTime": "2019-08-24T14:15:22Z",
- "farmId": 0,
- "teamId": 0,
- "teamMemberId": 0,
- "teamMemberName": "string",
- "timesheetId": 0
}
]Retrieve tasks completed during a timesheet entry (e.g. Spray, Other). Optionally filter by timesheet start date (inclusive, ISO date).
| dateFrom | string <date> ^\d{4}-\d{2}-\d{2}$ Example: dateFrom=2026-01-01 Earliest timesheet start date (inclusive), ISO format. |
| dateTo | string <date> ^\d{4}-\d{2}-\d{2}$ Example: dateTo=2026-01-31 Latest timesheet start date (inclusive), ISO format. |
[- {
- "durationHours": 0.1,
- "farmId": 0,
- "id": 0,
- "jobId": 0,
- "timesheetId": 0,
- "workType": "string"
}
]Retrieve treatments to which partner has access. Optionally filter by field IDs.
| fieldIds | string^$|^[1-9][0-9]*(,[1-9][0-9]*)*$ Example: fieldIds=12,45,78 CSV of field IDs. If omitted or empty, returns all treatments. |
[- {
- "amount": 0.1,
- "categoryId": "string",
- "categoryName": "string",
- "farmId": 0,
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "name": "string",
- "registrationNumber": "string",
- "type": "string",
- "unit": "GRAM_PER_SQUARE_METER"
}
]