EUDR Audit Trail From Deforestation Metrics (Plots Only)
End-to-end recipe that goes from a raw plot-only upload to an
exported EUDR DDS report — and shows how a caller-supplied CSV
column (here clientId) is projected into that report via
report_data_fields.
Plot-only upload. This workflow uploads
location_type: plotassets exclusively. Facilities (and other location types) are out of scope here — the audit record is built from the upload's plots.
It chains three subsystems that each have their own per-endpoint docs:
- Ingestion — upload plot geometry, wait for it to stage.
- Deforestation metrics — run
processBatchStatsover the upload and wait for it to finish. - EUDR audit trail — create an audit record from the upload's
plots (carrying a
report_data_fieldsprojection), poll the create task for the new record id, inspect / replace the projection list, and finally export the report so the projected column visibly lands under each plot'sdata_fields.
Everything is keyed off a single ddsdf_task_id (the upload), so the
create filter simply reuses filter[assets.task_id].
▶Endpoint map
| Step | Method | Path | Threads to next |
|---|---|---|---|
| 01 | POST | /ingestions/assets (location_type: plot; CSV carries a custom clientId column) | ddsdf_task_id |
| 02 | GET | /ingestions/{task_id} (poll until staged) | — |
| 03 | PUT | /ingestions/assets?filter[assets.task_id]=eq:{task_id} (metrics:["deforestation"]) | ddsdf_metrics_task_id |
| 04 | GET | /ingestions/{metrics_task_id} (poll until terminal) | — |
| 05 | POST | /regulations/eudr/audit-trail (task filter + report_data_fields) | ddsdf_create_task_id |
| 06 | GET | /regulations/eudr/audit-trail/tasks/{create_task_id} (poll until complete) | ddsdf_record_id |
| 07 | GET | /regulations/eudr/audit-trail/{record_id}/data-fields | (confirm projection) |
| 08 | PUT | /regulations/eudr/audit-trail/{record_id}/data-fields (full-replace) | (replace semantics) |
| 09 | GET | /regulations/eudr/audit-trail/{record_id}/report | (projected report) |
| 10 | — | Render a standalone HTML report (Bruno-side preview) | — |
| 11 | GET | /regulations/eudr/audit-trail/{record_id}/audit-trail/html | signed download URL |
| 12 | POST | /regulations/eudr/audit-trail/{record_id}/authorisations | clears authorization_missing |
| 13 | POST | /regulations/eudr/dds/{record_id}/submit | ddsdf_submit_task_id |
| 14 | GET | /regulations/eudr/audit-trail/tasks/{submit_task} (poll until complete) | TRACES identifiers |
Steps 12–14 file the record with EU TRACES — the end of the customer's flow. Submit files only the compliant supply base and requires a live authorisation for the current version (step 12), which must be the last write before submit.
▶Variables exchanged
ddsdf_task_id— set by step 01 (the upload); read by steps 02, 03, 05.ddsdf_metrics_task_id— set by step 03 (equalsddsdf_task_idwhen the filter fast-path reuses the existing task); read by step 04.ddsdf_create_task_id— set by step 05; polled in step 06.ddsdf_record_id— set by step 06 from the create task'sresult.records[0].record_id; read by steps 07–09.ddsdf_*_poll_retries— used by the polling helper to bound retries.
▶How report_data_fields threads through
report_data_fields threads throughThe clientId column is not a tag and not a filter input — it
is an uploaded data column that the report projects. Two independent
threads run side by side:
- Selection —
filter[assets.task_id]picks which plots become the audit record (step 05). This is how the upload is bound to the record. - Projection —
report_data_fieldsdeclaresclient_id← first-non-null of["clientId", "client_id"]. It is stored on the version (read back via the data-fields endpoint, step 07) and resolved per plot at report-build time: eachplot_registerentry'sdata_fieldsblock carries{ value, label, matched_path }for every projection key (step 09). See the Report Data Fields concept page for the resolution rules and the inherit / clear / replace tri-state on version cut.
▶Why this is a workflow, not a per-endpoint test
Each endpoint is covered in Endpoints/ and the ingestion/metrics
flows in their own Workflows folders. This collection exercises the
composition: an upload's plots flow into an audit record, a custom
CSV column survives the whole chain, and the projection is observable
on the final report. Treat it as runnable documentation.