Assessment Fields

Assessment Fields Reference

Every location uploaded through POST /ingestions/assets has its assessment response columns partitioned into one of ten disjoint assessment groups. Each group is stored separately and surfaced in API responses under relationships.assessments.attributes.{group}.

This page is the canonical reference for every key each group can carry.

GroupEnabled byStored asSurfaced in
coreinclude_coreassessment of type coreassessments.core
hazardinclude_hazardassessment of type hazardassessments.hazard
infrastructureinclude_infrastructureassessment of type infrastructureassessments.infrastructure
deforestation_screeninclude_deforestation (ingestion); include_deforestation_screen (reprocess PUT only)assessment of type deforestation_screenassessments.deforestation_screen
biodiversityinclude_biodiversityassessment of type biodiversityassessments.biodiversity
waterinclude_waterassessment of type waterassessments.water
luc_emissionsinclude_luc_emissionsassessment of type luc_emissionsassessments.luc_emissions
art9include_art9 / include_deforestation / include_legality (ingestion); include_art9 / include_eudr (DDS create path)assessment of type art9assessments.art9
art10include_art10 / include_legality (ingestion); include_art10 / include_eudr (DDS create path)assessment of type art10assessments.art10
eudr_profileinclude_eudr_profile (ingestion); force-run on the DDS create pathassessment of type eudr_profileassessments.eudr_profile

core, hazard, infrastructure, deforestation_screen, biodiversity, water, and luc_emissions are ingestion-scope โ€” surfaced under ingestions:read / locations:read. art9 (legality), art10 (country-risk), and eudr_profile are EUDR-scope โ€” surfaced on the same responses but gated behind assessments:read; without that scope the slots come back null. See eudr-compliance.md for the EUDR readiness contract and Including assessments on ingestion responses for the gated surfacing + nested response shape.

The key sets are disjoint by construction (a regression test in fm-api guards this). If a new column is added upstream it must land in exactly one group; otherwise it is treated as user source data and not promoted into assessments.

The field tables below cover core, art9, art10, hazard, biodiversity, water, luc_emissions, and infrastructure. The two groups split out after this page was written โ€” eudr_profile and deforestation_screen โ€” are documented in Including assessments on ingestion responses.

The source of truth for the partitioning is call-validate-locations.ts (CORE_KEYS, ART9_KEYS, ART10_KEYS, EUDR_PROFILE_KEYS, HAZARD_KEYS, INFRASTRUCTURE_KEYS, DEFORESTATION_SCREEN_KEYS, BIODIVERSITY_KEYS, WATER_KEYS, LUC_KEYS).


Request parameters (the assessments block)

The assessments block can be supplied on POST /ingestions/assets and on PUT /ingestions/assets. All fields are optional.

Every flag is strict opt-in (default false) โ€” none of them, including include_core, runs unless you set it true.

On the ingestion endpoints (POST / PUT /ingestions/assets) the honoured toggles are:

FieldTypeDefaultDescription
include_corebooleanfalsePersist the core row โ€” confidence score + level + plot- and facility-validation flags.
include_deforestationbooleanfalseRun the validation-time deforestation check (commodity-mask overlap). Writes the deforestation_screen row (the per-location deforestation summary object โ€” risk, deforestation_present, deforestation_area_ha โ€” plus deforestation_check_failed), reports deforestation_screen on the task summary's by_assessment, and writes deforestation_value (art9 group) plus the confidence_level (core group) that the metric_confidence_levels gate weighs. Not free โ€” see the cost note below the table.
include_deforestation_screenbooleanfalseReprocess (PUT) only, and requires the eudr:write scope. The upload POST rejects it: use include_deforestation there, which reaches the same sco2api primitive and produces the same row and the same by_assessment entry. On reprocess this flag runs the screen as a standalone full assessment, which is what makes it separable โ€” and it additionally re-runs the screen over every derived staged_location (see the cost note).
include_legalitybooleanfalseRun the Article 9 legality check (Gemini adverse-media web search). Writes the legality_* keys (art9 group) headlined by legality_risk_level, and โ€” via the same worker's deterministic backbone โ€” the article10_* keys (art10 group) headlined by article10_risk_level. Maps to the include_legality_check on the wire.
include_eudr_profilebooleanfalseRun the EUDR-profile enrichment add-on (Gemini facility description/profile + deterministic Article-29 country-risk tier) โ†’ eudr_profile row. Its own sco2api primitive โ€” no other ingestion flag turns it on. Maps to include_eudr_profile on the wire. The eudr_profile block surfaces on the assets / locations responses for callers holding assessments:read.
include_hazardbooleanfalseRun natural-hazard risk scoring โ†’ hazard row.
include_biodiversitybooleanfalseRun the biodiversity (landscape-integrity) screen โ†’ biodiversity row (landscape_integrity_score/_level, natural cover, fragmentation, Rao's Q, WDPA/IFL proximity). Maps to include_landscape_integrity on the wire (EPO-1810).
include_waterbooleanfalseRun the climatic water-budget screen โ†’ water row (water_budget_score/_level, seasonal climatic water deficit). Maps to include_water_budget on the wire (EPO-1810).
include_luc_emissionsbooleanfalseRun the land-use-change emissions screen โ†’ luc_emissions row (the land-cover change detected and its tCO2e/yr equivalent). Uses Earth Engine, and on a facility it also runs the isochrone, as include_deforestation does. Same name on the wire.
include_infrastructurebooleanfalsePersist the infrastructure row with the *_distance_km keys driven by the access checks below.
include_art9booleanfalseRun the Article 9 assessment on its own โ†’ art9 row (isochrone deforestation + adverse-media legality columns), without reporting or persisting art10. Same worker (and cost) as include_legality.
include_art10booleanfalseRun the Article 10 procedural / country risk assessment on its own โ†’ art10 row (governance, corruption, conflict, indigenous-overlap โ†’ article10_*, incl. the grounded article10_criteria), without reporting or persisting art9. The Article 10(2) criteria narrative (article10_summary) is surfaced on the legality (art9) read surface only โ€” request include_art9 / include_legality if you need it. The EUDR country-risk tier is a separate opt-in (include_eudr_profile), not this flag.

include_art9 / include_art10 are independently honoured on upload (EPO-1808; they were previously stripped). include_legality remains the both-groups shorthand. Note the two groups share one sco2api legality worker, so requesting either alone costs the same as include_legality โ€” the independence is in what gets reported (by_assessment) and persisted, not in what runs server-side.

On upload, include_deforestation is the flag for the deforestation_screen group. include_deforestation_screen is rejected there by the strict schema. The two reach the same sco2api primitive, and on the upload path the base flag already produces everything the group needs: the row write is data-driven, and the progress fold reports the group for either flag. So the separable spelling adds nothing on POST and stays on the reprocess PUT, where it runs the type as a standalone full assessment and the eudr:write gate means something.

The screen's summary is per-location and shaped the same for both location types, but it is produced by a different upstream check on each: a facility's comes from the isochrone-catchment deforestation reduce, a plot's or shed's from the polygon's own plot_validation. That is why the group's progress in by_assessment folds from a different sco2api sub-task per type.

What the deforestation check costs

Against a run that requests no deforestation at all:

  • Facility runs additionally solve the supply-shed isochrone and run an Earth Engine reduce over it. The isochrone is skipped entirely when nothing consumes it, which is why a core-validation or geocode-only upload is much cheaper, and the solve is bounded by a 750 s timeout before it degrades to a 50 km buffer.
  • Plot runs screen deforestation per polygon, and a plot with deforestation present takes a 0.15 penalty on its confidence score. So confidence_score and confidence_level are not invariant to these flags: the same upload scores differently with the check on. If you gate metric computation with metric_confidence_levels, that gate reads the affected level โ€” so on a run that also requests metrics, this can change which locations are computed, not just what is displayed.
  • The reprocess-only include_deforestation_screen additionally costs a derived-location pass, which include_deforestation never does. That flag puts deforestation_screen into the run's requested assessment types, so the screen also runs over each staged_location derived during the run โ€” the sheds and plots linked from your upload. Those are new locations with no cached validation row, so each is a real upstream call and emits its own usage event, and the pass is uncapped. This is the reason the upload path does not offer the flag: on POST it would buy that fan-out and no extra data.
  • An art9 row is opened per location either way, because the same check emits the isochrone/shed columns that belong to the art9 partition. The legality family is filtered out when Article 9 was not itself requested, so /assessments/{location_type}/legality can return rows whose legality fields are all null. Read legality_risk_level rather than row presence to decide whether Article 9 actually ran.

DDS-create-path shorthand (stripped on ingestion)

include_eudr drives both EUDR-scope groups on the DDS create path. It is silently stripped if sent to POST / PUT /ingestions/assets (see assessments-overview.md) โ€” use the per-group include_art9 / include_art10 flags (or include_legality for both) instead.

FieldTypeDefaultGroup enabledDescription
include_eudrbooleanfalseart9 + art10Shorthand that fans out to include_art9 + include_art10 only โ€” not hazard / infrastructure.

When both include_eudr and a per-group flag are present, the union wins โ€” include_eudr: true cannot be narrowed by setting an individual group to false.

Access checks (check_*)

The check_* flags are cross-cutting toggles that drive the water / port / road access checks. They sit at the top level of the assessments block โ€” not nested under any group โ€” because the same assessment call produces matching keys on both core and infrastructure:

  • core โ€” boolean access flags: water_access, port_proximity, road_access.
  • infrastructure โ€” numeric distances in km: nearest_water_km, nearest_port_km, nearest_road_km.
FieldTypeDefaultDrives (in core)Drives (in infrastructure)
check_water_accessbooleanfalsewater_accessnearest_water_km
check_port_proximitybooleanfalseport_proximitynearest_port_km
check_road_accessbooleanfalseroad_accessnearest_road_km

Both rows record the check_* snapshot on their sub_options column. A subsequent request that asks for an access check not covered by the cached sub_options is treated as a cache miss and refreshes the affected rows.


core group

Enabled by include_core. See assessments-overview.md ยง core for what this assessment does. Plot validation methodology lives in location-validation.md.

Common (always present on core)

FieldTypeDescription
confidence_scorenumber0โ€“1 score combining all plausibility indicators below.
confidence_levelstringlow | medium | high. Bucketing of confidence_score.
confidence_commentstringFree-text explanation of which indicators contributed.
commentstringGeneric per-feature comment.
common_commentstringPer-collection comment shared across features.
total_plotsnumberTotal plot count in the parent collection.
primary_warningstring | nullHeadline warning string for UI surfacing (most severe issue).
feature_idxnumberPosition of this feature in the source upload (0-based).
location_typestringDetected location type โ€” facility | plot | shed.
commodity_invalidbooleanPresent and true when the row's commodity cell names no supported commodity. The row was checked against the file's commodity (the declared commodity_type, or the column's most common value) instead. Absent when no commodity column was used.

Facility plausibility (location_type='facility')

FieldTypeDescription
producer_confirmation_scorenumber0โ€“1 โ€” confidence that the named producer matches points of interest / business records at the location.
producer_confirmedbooleanTrue iff producer_confirmation_score exceeds the per-commodity threshold.
producer_confirmation_commentstringFree-text explanation of which evidence supported / contradicted the producer name.
aggregation_commentstringComment about how multiple sources were combined into the score.
poi_dataobjectRaw point-of-interest matches that informed scoring.
commodity_presenceboolean / numberWhether commodity probability maps show presence at the location.
poi_presencebooleanWhether matching points of interest (mill, silo, warehouse, etc.) were found nearby.
high_densitybooleanWhether the surrounding area has high industrial / built-up density.
building_presencebooleanWhether building footprints exist within the detection radius.
road_accessbooleanWhether a road network segment is reachable within plausible distance.
water_accessbooleanWhether navigable waterways are within plausible distance.
port_proximitybooleanWhether a port facility is within plausible distance.

Plot validation counts (location_type='plot')

Each *_count is the number of plots in the upload that triggered the matching geometric check.

FieldTypeDescription
max_distance_gt_min_distance_countnumberPlots whose max-vertex distance vastly exceeds their min-vertex distance (elongated shapes).
max_angle_lt_min_angle_countnumberPlots with extreme interior-angle disparity (spiked geometries).
intersects_another_polygon_countnumberPlots that overlap another plot in the same collection.
distance_nearest_neighbor_countnumberPlots that are extremely close to a neighbour without overlapping (likely boundary error).
area_too_small_countnumberPlots below the per-commodity minimum area.
triangular_geometry_countnumberPlots whose vertex layout is suspiciously triangular (placeholder geometry).
bad_precision_countnumberPlots whose coordinates have insufficient decimal precision (~10 m floor).
short_boundary_segments_countnumberPlots with sub-resolution boundary segments.
self_intersection_countnumberPlots whose polygon ring crosses itself.
duplicate_vertices_countnumberPlots with consecutive identical vertices.
nested_geometry_collection_countnumberPlots delivered as nested GeometryCollection.
simplifiable_collections_countnumberPlots whose nested collection can be flattened without loss.
commodity_absence_countnumberPlots where commodity probability maps show no presence.
protected_area_overlap_countnumberPlots that intersect a WDPA protected area.
protected_area_assessedbooleanfalse when the protected-area read did not complete, so the overlap count was not verified.
plot_validityobjectAggregate shape-validity summary { score, level, investigate[] }.
deforestationobjectPer-plot deforestation summary { value, area_ha, level } (separate from art9).
overallobjectTop-level pillar-weighted summary { score, level, investigate[] }.
protected_area_metadataobjectWDPA polygon ids and names overlapping the plot, when applicable.

art9 group โ€” Article 9 isochrone deforestation

EUDR-scope: driven on the DDS create path, not on ingestion. See assessments-overview.md ยง art9.

FieldTypeDescription
deforestation_valuenumber0โ€“1 deforestation index for the isochrone shed. Higher = more cleared post-EUDR cutoff.
deforestation_area_hanumberHectares of detected deforestation within the shed (not the plot).
shed_geoobjectDeprecated. GeoJSON Polygon of the buffered isochrone catchment. Absent on live reads; still present on audit-trail plots and in artifact exports (metrics data). Read live screened areas from GET /ingestions/assets/{id}/screened-areas.

art10 group โ€” Article 10 legality + country risk

EUDR-scope: driven on the DDS create path, not on ingestion. See assessments-overview.md ยง art10.

FieldTypeDescription
legality_risk_scorenumber0โ€“1 risk score for legality (land tenure disputes, sanctions, environmental violations, illegal-activity media).
legality_risk_levelstringlow | medium | high bucketing.
legality_summarystringHuman-readable summary of the legality findings.
legality_sourcesarrayCited sources backing the score: { url, title, snippet, sentiment, lat, lon }.
eudr_country_risk_tierstringEUDR-published country tier โ€” low | standard | high. Drives the due-diligence depth required for the country.
corruption_perception_indexnumberTransparency International CPI for the country of operation. Lower = more perceived corruption.

hazard group โ€” Natural hazard risk

Enabled by include_hazard. See assessments-overview.md ยง hazard.

FieldTypeDescription
natural_hazard_risk_scorenumber0โ€“1 composite hazard score.
natural_hazard_risk_levelstringlow | medium | high bucketing.
natural_hazard_summarystringHuman-readable summary of which hazards drove the score.
natural_hazard_sourcesarrayCited sources backing the score: { url, title, snippet, hazard_type, lat, lon }.
flood_zone_pctnumberPercentage of the supply shed within a mapped flood zone.
flood_event_countnumberCount of recorded historical flood events.
extreme_heat_wbgtnumberWet-bulb globe temperature (ยฐC) proxy for extreme-heat exposure.
water_stress_scorenumber0โ€“1 baseline water-stress score.
nearest_grid_kmnumberStraight-line distance to the nearest power-grid infrastructure (hazard-gated).
nearest_grid_pointGeoJSON PointLocation of the nearest power-grid feature.

biodiversity group โ€” Landscape-integrity screen

Enabled by include_biodiversity (EPO-1810). A lightweight non-EE screen computed from the commodity / natural-forest masks over each location.

FieldTypeDescription
landscape_integrity_scorenumber0โ€“1 composite biodiversity score: strongest of forest-landscape intactness, WDPA-proximity and IFL-proximity; higher = more at stake.
landscape_integrity_levelstringlow | moderate | high | severe concern band.
landscape_natural_cover_fractionnumberNatural-habitat cover fraction of the shed (0โ€“1).
landscape_patch_countnumberNatural-habitat patch count (fragmentation).
landscape_rao_qnumberMean Rao's Q structural diversity of the canopy.
landscape_wdpa_kmnumberDistance (km) to the nearest WDPA protected area within the impact buffer; null if none.
landscape_ifl_kmnumberDistance (km) to the nearest Intact Forest Landscape within the impact buffer; null if none.

water group โ€” Climatic water-budget screen

Enabled by include_water (EPO-1810). The fast climatic arm of the water budget โ€” 1 โˆ’ P/PET aridity plus the seasonal climatic water deficit. Distinct from the hazard group's water_stress_score (a different worker's baseline signal).

FieldTypeDescription
water_budget_scorenumber0โ€“1 climatic water-stress index; higher = more stressed.
water_budget_levelstringlow | moderate | high | severe stress band (aridity-class aligned).
water_budget_cwd_mmnumberSeasonal climatic water deficit, mm/yr.

luc_emissions group โ€” Land-use-change emissions screen

Enabled by include_luc_emissions. Pairs the land-cover change detected over the assessment window with the emissions it implies. sco2api stores one nested luc_emissions object plus luc_emissions_check_failed; every API surface flattens it to the fields below, both on GET /assessments/{location_type}/luc-emissions and in assessments.luc_emissions.flags.

Every field except luc_check_failed is null when the screen failed and left no summary.

FieldTypeDescription
luc_risk_levelstring | nulllow | medium | high. Null when the screen ran unscoped or over a zero area, so a filter[luc_risk_level] never matches those rows.
luc_tco2eyearnumber | nullLUC emissions, tCO2e/yr: conversion plus peat oxidation plus fertiliser N2O.
intensity_tco2e_ha_yearnumber | nullluc_tco2eyear per hectare of screened_area_ha.
converted_area_hanumber | nullArea converted in the window, ha.
forest_converted_area_hanumber | nullConverted area that was forest, ha.
nonforest_converted_area_hanumber | nullConverted area that was not forest, ha.
main_lc_transitionstring | nullThe transition with the largest area, e.g. forest_to_cropland.
lc_transitionsobject | nullConverted area by transition, ha.
annual_lcobject | nullEmissions by year, tCO2e. Years with none are omitted.
screened_area_hanumber | nullThe area the screen ran over, ha.
screened_area_basisstring | nullWhich area that is, e.g. commodity or catchment.
commodity_basisstring | nullWhich conversions were counted. target: conversion to this commodity. cropland_fallback or commodity_union: conversion to farmland in general, not attributable to this commodity. plot_boundary: every conversion inside the submitted plot. unscoped counts every conversion and leaves the band null.
factor_basisstring | nullEmission-factor source. global_default means the country had no entry and forest transitions are underestimated.
assessment_periodnumber | nullWindow length, years. 20, or a tree crop's longer cycle.
monitoring_end_yearnumber | nullLast year of the window.
luc_check_failedbooleanTrue if the upstream screen errored.

infrastructure group โ€” Nearest-feature enrichments

Enabled by include_infrastructure. See assessments-overview.md ยง infrastructure. Distance keys present depend on which check_* flags were set at request time (see Access checks); the port metadata + GeoJSON points are emitted whenever the port check runs.

FieldTypeDriven byDescription
nearest_water_kmnumbercheck_water_accessDistance to the nearest navigable waterway.
nearest_port_kmnumbercheck_port_proximityStraight-line distance to the nearest port facility.
nearest_road_kmnumbercheck_road_accessDistance to the nearest road network segment.
port_road_kmnumbercheck_port_proximityRoad-routed driving distance to the nearest port (Google Directions).
nearest_port_namestringcheck_port_proximityName of the nearest port facility.
nearest_port_addressstringcheck_port_proximityAddress of the nearest port facility.
nearest_port_pointGeoJSON Pointcheck_port_proximityLocation of the nearest port facility.
nearest_water_pointGeoJSON Pointcheck_water_accessLocation of the nearest navigable waterway.
port_route_countnumbercheck_port_proximityHow many alternative driving routes to the port exist (max 3). 1 is a single point of failure; 0 with port_routes_unavailable: false means no road route exists.
port_routes_unavailablebooleancheck_port_proximitytrue only when the routing call itself failed. Distinguishes "we could not look" from "there is no route" โ€” do not read a port_route_count of 0 without it.

Port freight routes (port_routes) โ€” opt-in

The route geometry behind port_route_count is not returned by default. Each route is a decoded driving polyline of several hundred [lon, lat] vertices, so a location can carry tens of KB โ€” enough to matter on a bulk upload, where a single page of results would otherwise drag the whole set through Postgres.

Request it explicitly on the infrastructure read endpoint:

GET /assessments/{location_type}/infrastructure?include=port_routes
FieldTypeDescription
port_routesarray | nullTop-level attribute (not inside distances). An array of routes; each route is a list of [lon, lat] vertices, ordered from the location to the port. Route 0 is the primary. null when the location has no routed port.

The key is omitted entirely without the include, so a caller can tell "I did not ask for this" from "this location has no routes". It is an include, not a sparse field โ€” fields[assessment]=port_routes is a 400. The two compose: ?include=port_routes&fields[assessment]=distances returns both.

port_routes is never present on the aggregate assessment relationship (GET /locations?include=assessment, DDS record reads) or in CSV artifact exports, and it is not replicated onto catchment members when one representative location is assessed for a group โ€” the routes belong to the location they were measured from.


Response-shape note

The assets / locations responses surface the ingestion-scope slots โ€” core, hazard, infrastructure, deforestation_screen, biodiversity, water, luc_emissions โ€” under ingestions:read / locations:read. The EUDR-scope rows (art9, art10, eudr_profile) are surfaced on the same responses, but gated behind assessments:read; without that scope the slots come back null. The full EUDR-scope payloads are also readable from the dedicated GET /assessments/{location_type}/{legality,country-risk,eudr-profile} slugs and from the audit-trail record once the DDS create path has produced them (GET /regulations/eudr/audit-trail/:recordId/plots). For the nested response shape and per-partition field references, see Including assessments on ingestion responses.