An assessment's actual farm data is not stored on the assessment record itself. It lives across 16 nested resources, one per Cool Farm Tool data category, each addressed under the parent assessment:
assessments/{ASSESSMENT_ID}/{section}/
Every section supports the standard CRUD verbs unless a subsection below says otherwise:
| Method | Purpose |
|---|---|
GET assessments/{ASSESSMENT_ID}/{section}/ | List all entries for this section on this assessment. |
POST assessments/{ASSESSMENT_ID}/{section}/ | Create a new entry. |
GET assessments/{ASSESSMENT_ID}/{section}/{id}/ | Retrieve one entry. |
PUT/PATCH assessments/{ASSESSMENT_ID}/{section}/{id}/ | Update one entry. |
DELETE assessments/{ASSESSMENT_ID}/{section}/{id}/ | Delete one entry. |
Base URL, authentication, and the response envelope are the same as everywhere else in this API — see the overview page. For what an assessment's status values mean and how these sections roll up into an assessment, see the assessments page.
Six of the sections below are "one per assessment" rather than "many":
seeds,crop_details,residues,soil_carbon_changes,non_crop_biomass_estimated, andre_deforestation. Sending a secondPOSTto any of these for the same assessment is untested and is expected to raise an unhandled database-integrity error surfaced as a generic HTTP 500, rather than a clean validation message. UsePUT/PATCHagainst the existing record instead of a secondPOSTfor these six sections. This warning applies once, generally — it is not repeated in each subsection below.
Permissions
All 16 sections are gated by the same dynamic permission as the parent assessment, not a per-section slug: read actions (
GETlist/retrieve) requireassessment.view, and write actions (POST/PUT/PATCH/DELETE) requireassessment.edit. There is no separatefertilizer.view,pesticide.edit, etc. for these nested endpoints — a caller who can edit an assessment's fields can create, update, and delete entries in any of its 16 sections.
Status codes
The same status codes apply across all 16 sections:
| Status | Trigger |
|---|---|
| 200 | List / retrieve / update succeeded. |
| 201 | Create succeeded. |
| 204 | Delete succeeded. |
| 400 | Validation failure — a bad enum value, a malformed value+unit object, or (for non_crop_biomass_estimated specifically) an update attempted after the parent assessment is no longer draft. |
| 403 | Caller's token doesn't carry assessment.view/assessment.edit for this company (see Permissions above). |
| 404 | Assessment or section entry not found (or not owned by the caller's company). |
Seeds and crop details
seeds/
seeds/One per assessment.
| Field | Notes |
|---|---|
purchase_type | Enum. Values come from the system's seed-purchase catalog (e.g. seed, plug). |
mass_of_seed | Value+unit. Required when purchase_type is seed. |
seed_source_type | Enum. Required when purchase_type is seed. |
number_of_plugs | Required when purchase_type is plug. |
plugs_in_peat_soil | Required when purchase_type is plug. |
purchase_typedecides which field set is live. If it's"seed",mass_of_seed/seed_source_typeare required andnumber_of_plugs/plugs_in_peat_soilare cleared server-side. If it's"plug", it's the reverse. Send the fields for yourpurchase_type— the other set is nulled either way, whether or not you sent it.
Fertilizers and pesticides
fertilizers/
fertilizers/Many per assessment.
| Field | Notes |
|---|---|
fertilizer_type | Enum, from the fertilizer-type catalog. Optional. |
production_region | Enum. |
weight_or_units | Enum — the application-rate basis. |
fertilizer_application_rate | Value+unit pair. |
fertilizer_emission_factor | Value+unit pair. |
percentage_N/percentage_P/percentage_K/etc. | Five composition percentage fields. Only apply when fertilizer_type is left blank. |
If
fertilizer_typeis set, the five composition percentage fields plus the legacyname/amount/unitfields are force-cleared server-side, even if you send values for them. Those composition fields only apply when you leavefertilizer_typeblank and compose a custom fertilizer by hand.
Free-text sections
The category/type fields in the sections below are free text — despite field names that read like a fixed key set, there is currently no enum validation enforced server-side for them. Any string is accepted.
machinery_operations/
machinery_operations/Many per assessment.
| Field | Notes |
|---|---|
soil_type | Free text, no enum validation. |
machine_type | Free text, no enum validation. |
fuel_type | Free text, no enum validation. |
This section's data is also separately embedded directly on the root Assessment payload as a nested object:
{"machinery_operations": true|false, "soil_type": ..., "list_of_machines": [...]}. The standalonemachinery_operations/endpoint and that embedded object represent the same underlying data two different ways — updating one does not automatically keep the other's shape in sync in your own client-side cache, so pick one representation to treat as the source of truth in your integration.
Residues and land-use sections
non_crop_biomass_estimated/
non_crop_biomass_estimated/One per assessment.
| Field | Notes |
|---|---|
intercrops | List. Each item's intercrop_type is an enum from its own catalog. |
shade_trees | List. Each item's shade_tree_type is an enum from its own catalog. |
hedges | List. Each item's hedge_type is an enum from its own catalog. |
This is the only section with a submission lock. If the parent assessment's
statusis no longerdraft, any update here is rejected with a 400-style validation error: "Cannot update biomass in a finalized assessment." Once an assessment has moved pastdraft(for example after submit), this section becomes read-only.
soil_carbon_changes/
soil_carbon_changes/One per assessment.
| Field | Notes |
|---|---|
land_use_changes | List of entries. Fields within each entry are free text, no enum validation. |
Example: create a fertilizer entry (many per assessment)
curl -X POST https://backend.spacenus.de/api/v1.2/regen-scope-3/assessments/ASSESSMENT_ID/fertilizers/ \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"fertilizer_type": "urea",
"production_region": "europe",
"weight_or_units": "per_hectare",
"fertilizer_application_rate": {"value": 150, "unit": "kg_per_hectare"},
"fertilizer_emission_factor": {"value": 1.8, "unit": "kg-CO2e/kg"}
}'A successful response:
{
"status": "success",
"message": "Created",
"data": {
"id": 42,
"assessment": "ASSESSMENT_ID",
"fertilizer_type": "urea",
"production_region": "europe",
"weight_or_units": "per_hectare",
"fertilizer_application_rate": {"value": 150, "unit": "kg_per_hectare"},
"fertilizer_emission_factor": {"value": 1.8, "unit": "kg-CO2e/kg"},
"percentage_N_as_ammonium_N": null,
"percentage_N_as_nitrate_N": null,
"percentage_N_as_urea_N": null,
"percentage_P2O5_or_percentage_P": null,
"percentage_K2O_or_percentage_K": null,
"name": null,
"amount": null,
"unit": null
}
}Note the composition/legacy fields all came back null — fertilizer_type was set, so the server force-cleared them even though this request never mentioned them.
Example: create crop details (one per assessment)
curl -X POST https://backend.spacenus.de/api/v1.2/regen-scope-3/assessments/ASSESSMENT_ID/crop_details/ \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"crop_type_key": "wheat",
"total_harvested": {"value": 12.5, "unit": "tonnes"},
"farmgate_amount": {"value": 11.9, "unit": "tonnes"}
}'A successful response:
{
"status": "success",
"message": "Created",
"data": {
"id": 7,
"assessment": "ASSESSMENT_ID",
"crop_type_key": "wheat",
"total_harvested": {"value": 12.5, "unit": "tonnes"},
"farmgate_amount": {"value": 11.9, "unit": "tonnes"}
}
}A second POST to crop_details/ for this same assessment is not the way to change these values — use PATCH on crop_details/7/ instead (see the warning at the top of this page).
