Most EUDR articles are written by lawyers for compliance officers. This one is for the engineers who get handed a ticket that says "make us EUDR compliant" and a deadline.
I work as a full-stack engineer at Dimitra, where we build agritech and EUDR compliance software. What follows is the mental model I wish I had on day one.
The regulation in one paragraph
The EU Deforestation Regulation, Regulation (EU) 2023/1115, says that seven commodities, and products made from them, can only be placed on the EU market or exported from it if they are:
- Deforestation-free. Produced on land that was not deforested after 31 December 2020.
- Legal. Produced in line with the laws of the country of production.
- Covered by a due diligence statement (DDS) submitted to the EU before the goods move.
The seven commodities are cattle, cocoa, coffee, oil palm, rubber, soya and wood. The scope is much wider than it sounds, because derived products are in scope too: leather, chocolate, furniture, tyres, paper, and so on.
Why this lands on engineering
The legal requirement sounds simple. The data requirement is not. To prove a bag of coffee is deforestation-free, you need to answer:
- Which plots of land did this coffee come from?
- Where exactly are those plots, as coordinates or polygons?
- Were those plots forest on 31 December 2020, and are they deforested now?
- Who handled it between the farm and the EU border?
Every one of those is a join across systems that usually don't talk to each other: farm registries, cooperative spreadsheets, exporter ERPs, satellite data, and the EU's own submission system.
The core data model
Here is the shape that keeps showing up, stripped of anything specific to one product:
type Producer = { id: string; name: string; country: string; // ISO 3166-1 alpha-2 }; type Plot = { id: string; producerId: string; geometry: GeoJSON.Point | GeoJSON.Polygon | GeoJSON.MultiPolygon; areaHectares: number; commodity: "cattle" | "cocoa" | "coffee" | "oil_palm" | "rubber" | "soya" | "wood"; riskAssessment?: { method: string; deforestationDetected: boolean; checkedAt: string; }; }; type Lot = { id: string; plotIds: string[]; // the hard part quantityKg: number; harvestedFrom: string; harvestedTo: string; }; type DueDiligenceStatement = { id: string; lotIds: string[]; hsCode: string; referenceNumber?: string; // returned by the EU system submittedAt?: string; };
The line that causes the most pain is plotIds: string[]. Real supply chains mix. A cooperative aggregates coffee from hundreds of smallholders, an exporter blends lots, and suddenly one container maps to thousands of plots. Your data model has to keep that link alive through every split and merge.
Geolocation is the first wall
The regulation asks for the geolocation of every plot of land where the commodity was produced. In short:
- Small plots can be a single point (latitude, longitude).
- Larger plots need a polygon describing the boundary.
- Coordinates must be precise, and the format the EU system accepts is GeoJSON.
I wrote a separate deep dive on this: EUDR Geolocation Requirements: Points vs Polygons. It covers the area threshold, coordinate precision, and the validation errors you will hit.
Risk assessment: where satellites come in
Once you have plots, you check them against forest data. The usual pattern:
- Load a forest baseline for the cut-off date. The EU's Joint Research Centre published a global forest cover map for 2020 as one reference.
- Overlay forest loss or disturbance data from after the cut-off.
- Flag plots where loss intersects the plot boundary.
- Send flagged plots to a human for review, because satellites are not courts.
This is where remote sensing meets compliance. More on the mechanics in Detecting Deforestation with Satellite Imagery.
The due diligence statement
The DDS is the output. It is a structured submission to the EU's information system (built on TRACES) that bundles the operator, the product and its customs code, the quantity, the country of production, and the geolocation of the plots. A submitted statement gets a reference number that travels with the goods.
I broke down the fields in EUDR Due Diligence Statement: What Data Goes In.
What I would build first
If you are starting from zero, this is the order I would build in:
- A plot registry with real geometry validation. Bad geometry poisons everything downstream.
- Lot-to-plot traceability that survives aggregation. Model splits and merges explicitly.
- A risk check pipeline that runs on plot creation and on a schedule.
- DDS generation last, because it is mostly a serialisation of the three things above.