A Cultivation ties one Crop to one Field within one Season — it's the record of "this crop was grown in this field during this season." Fertilization events are recorded against a Cultivation, not a Field directly. This page covers Cultivation CRUD. Base URL, authentication, the response envelope, the FK _id write pattern, and other shared conventions are covered in the Farm Management overview — this page only covers what's specific to Cultivations.
Endpoints
| Method | Path | Purpose |
|---|---|---|
GET | /cultivation/ | List cultivations. |
POST | /cultivation/ | Create a cultivation — single object or bulk array (see below). |
GET | /cultivation/{id}/ | Retrieve one cultivation. |
PUT | /cultivation/{id}/ | Full update. |
PATCH | /cultivation/{id}/ | Partial update. |
DELETE | /cultivation/{id}/ | Delete a cultivation (see the delete note below). |
Authentication and permissions
Send your access token as a bearer token, as described in the overview page.
| Action | Required permission |
|---|---|
| List / Retrieve | cultivation.view |
| Create | cultivation.create |
| Update / Partial update | cultivation.edit |
| Delete | cultivation.delete |
Only 3 fields are actually usable through this endpoint
Confirm scope with the backend team before treating this as a general cultivation-data API. The underlying Cultivation model has many more agronomic fields —
quality,variety,date_sowing, four soil-measurement fields, two fertilizer-allowance fields,strobilurin,date_harvest,yield_value,protein_content,water_status,n_min— but the serializer behind/cultivation/excludes every one of them. They cannot be read or written through this endpoint at all, only through internal mechanisms. If you need any of that data, this endpoint won't expose it — check with Spacenus before assuming otherwise.
Create-body fields
These are the only 3 fields that exist on this serializer:
| Field | Type | Required | Notes |
|---|---|---|---|
season_id | integer (FK) | Yes | |
crop_id | integer (FK) | Yes | The underlying model actually allows this to be null, but the API layer enforces it as required — always send a value. |
field_id | integer (FK) | Yes |
Bulk create
POST /cultivation/ accepts either a single object or a JSON array of objects.
Unlike Field and Season, Cultivation returns a unified 400 for validation failures on both a single object and a bulk array — there's no 402 case to special-case here. See the overview page's bulk-create section for how this compares across resources.
Deleting a cultivation
DELETE /cultivation/{id}/refuses to delete the last non-deleted cultivation for its field. If the cultivation you're trying to delete is the only one remaining for that field, the request is rejected with:{ "message": "At least one cultivation must be kept. You cannot delete the last cultivation." }with status 400, not 204 — and the record is not deleted. Otherwise, the delete proceeds as a normal soft delete and returns
204 No Content.
Filters
GET /cultivation/ supports exact-match filtering on:
| Filter | Matches |
|---|---|
crop | Crop ID |
field | Field ID |
season | Season ID |
Sharing (?share=true)
?share=true)Cultivation has a direct Field link, so ?share=true is resolved through the field's own sharing scope, the same way Field and Farm work — see the overview page.
Status codes
| Status | Trigger |
|---|---|
| 200 | List, retrieve, update, or create (single or bulk) succeeded. |
| 400 | Validation failure (single or bulk), or the "last cultivation" delete-block case above. |
| 403 | Missing permission. |
| 404 | Cultivation not found. |
Example: create a cultivation
curl -X POST https://backend.spacenus.de/api/v1.2/cultivation/ \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"season_id": 501,
"crop_id": 12,
"field_id": 340
}'A successful response:
{
"status": "success",
"message": "Created successfully.",
"data": {
"id": 902,
"season": {
"id": 501,
"name": "2024 Winter Wheat"
},
"crop": {
"id": 12,
"name": "Wheat"
},
"field": {
"id": 340,
"name": "North Field"
}
}
}