Assessment Data Sections

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:

MethodPurpose
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, and re_deforestation. Sending a second POST to 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. Use PUT/PATCH against the existing record instead of a second POST for 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 (GET list/retrieve) require assessment.view, and write actions (POST/PUT/PATCH/DELETE) require assessment.edit. There is no separate fertilizer.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:

StatusTrigger
200List / retrieve / update succeeded.
201Create succeeded.
204Delete succeeded.
400Validation 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.
403Caller's token doesn't carry assessment.view/assessment.edit for this company (see Permissions above).
404Assessment or section entry not found (or not owned by the caller's company).

Seeds and crop details

seeds/

One per assessment.

FieldNotes
purchase_typeEnum. Values come from the system's seed-purchase catalog (e.g. seed, plug).
mass_of_seedValue+unit. Required when purchase_type is seed.
seed_source_typeEnum. Required when purchase_type is seed.
number_of_plugsRequired when purchase_type is plug.
plugs_in_peat_soilRequired when purchase_type is plug.

purchase_type decides which field set is live. If it's "seed", mass_of_seed/seed_source_type are required and number_of_plugs/plugs_in_peat_soil are cleared server-side. If it's "plug", it's the reverse. Send the fields for your purchase_type — the other set is nulled either way, whether or not you sent it.

crop_details/

One per assessment.

FieldNotes
crop_type_keyEnum, from the crop-type catalog.
total_harvestedValue+unit pair. Default unit tonnes.
farmgate_amountValue+unit pair. Default unit tonnes.

Fertilizers and pesticides

fertilizers/

Many per assessment.

FieldNotes
fertilizer_typeEnum, from the fertilizer-type catalog. Optional.
production_regionEnum.
weight_or_unitsEnum — the application-rate basis.
fertilizer_application_rateValue+unit pair.
fertilizer_emission_factorValue+unit pair.
percentage_N/percentage_P/percentage_K/etc.Five composition percentage fields. Only apply when fertilizer_type is left blank.

If fertilizer_type is set, the five composition percentage fields plus the legacy name/amount/unit fields are force-cleared server-side, even if you send values for them. Those composition fields only apply when you leave fertilizer_type blank and compose a custom fertilizer by hand.

pesticides/

Many per assessment.

FieldNotes
pesticide_typeEnum, from the pesticide-type catalog.
pesticide_categoryEnum, from the pesticide-category catalog.
field_percentageFixed to unit %.
active_ingredient_percentageFixed to unit %.
pesticide_application_rateValue+unit pair.

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.

wastewater/

Many per assessment.

FieldNotes
oxygen_demand_typeFree text, no enum validation.
wastewater_treatmentFree text, no enum validation.

co_products/

Many per assessment.

FieldNotes
co_product_typeFree text, no enum validation.
co_allocation_methodFree text, no enum validation.

refrigerants/

Many per assessment.

FieldNotes
equipment_type_keyFree text, no enum validation.
refrigerant_type_keyFree text, no enum validation.
recovery_pathway_keyFree text, no enum validation.
refrigerant_allocation_methodFree text, no enum validation.

transport/

Many per assessment.

FieldNotes
transport_weightValue+unit pair.
transport_distanceValue+unit pair.
transport_typeFree text, no enum validation.
transport_boundaryFree text, no enum validation.

machinery_operations/

Many per assessment.

FieldNotes
soil_typeFree text, no enum validation.
machine_typeFree text, no enum validation.
fuel_typeFree 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 standalone machinery_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.

irrigation_energy/

Many per assessment.

Value+unit measurement fields for irrigation energy use. Category fields on this section are free text, no enum validation.

non_crop_biomass_measured/

Many per assessment.

Value+unit measurement fields for directly-measured non-crop biomass. Category fields on this section are free text, no enum validation.

Residues and land-use sections

residues/

One per assessment.

FieldNotes
residue_management_practiceEnum.
above_ground_dry_matterValue+unit pair. Default unit kg_per_hectare.

re_deforestation/

One per assessment.

FieldNotes
reforestationNested detail object.
deforestationNested detail object.
forest_typeEnum, from the forest-type catalog.

non_crop_biomass_estimated/

One per assessment.

FieldNotes
intercropsList. Each item's intercrop_type is an enum from its own catalog.
shade_treesList. Each item's shade_tree_type is an enum from its own catalog.
hedgesList. 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 status is no longer draft, any update here is rejected with a 400-style validation error: "Cannot update biomass in a finalized assessment." Once an assessment has moved past draft (for example after submit), this section becomes read-only.

soil_carbon_changes/

One per assessment.

FieldNotes
land_use_changesList 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).