In this recipe you'll create a full traceability journey for a T-shirt by adding one processing stage at a time. The API automatically rolls up each stage's CO₂ and distance into the journey totals.
See the Traceability concept page for the model.
1. Make sure the product exists
The traceability references a company product. Create one if you don't have it yet:
curl -X POST {{BASE_URL}}/api/v1/company/products \-H "Content-Type: application/json" \-d '{"name": "T-Shirt Organic Cotton SS26","code": "CP-TSH-SS26","unitOfMeasure": "PCS","active": true}'
Capture the returned id as PRODUCT_ID.
2. Create the traceability header
curl -X POST {{BASE_URL}}/api/v1/product/traceability \-H "Content-Type: application/json" \-d '{"productId": "'"$PRODUCT_ID"'","traceabilityName": "T-Shirt SS26 — Full Supply Chain","description": "Cotton-to-garment journey with CO2 estimate"}'
Capture the returned id as TRAC_ID. Note totalCo2PerKg and totalDistanceKm are 0 at this point — they'll be updated as stages are added.
3. Add stage 1 — cotton cultivation (supplier)
curl -X POST "{{BASE_URL}}/api/v1/product/traceability/$TRAC_ID/stages" \-H "Content-Type: application/json" \-d '{"sequenceOrder": 1,"stageName": "Cotton cultivation","companyType": "SUPPLIER","supplierId": "cotton-farm-uuid…","transportMode": "TRUCK","startsFromCompany": false,"distanceKm": 120,"co2Emissions": 15.4,"certificationsSnapshot": "GOTS"}'
4. Add stage 2 — spinning (supplier)
curl -X POST "{{BASE_URL}}/api/v1/product/traceability/$TRAC_ID/stages" \-H "Content-Type: application/json" \-d '{"sequenceOrder": 2,"stageName": "Spinning","companyType": "SUPPLIER","supplierId": "spinning-mill-uuid…","transportMode": "TRUCK","startsFromCompany": false,"distanceKm": 80,"co2Emissions": 10.2,"certificationsSnapshot": "GOTS, OEKO-TEX"}'
5. Add stage 3 — sea freight to Italy
curl -X POST "{{BASE_URL}}/api/v1/product/traceability/$TRAC_ID/stages" \-H "Content-Type: application/json" \-d '{"sequenceOrder": 3,"stageName": "Sea freight","companyType": "SUPPLIER","supplierId": "spinning-mill-uuid…","transportMode": "SHIP","startsFromCompany": false,"distanceKm": 10850,"co2Emissions": 108.5}'
6. Add stage 4 — dyeing & sewing (in your own facility)
curl -X POST "{{BASE_URL}}/api/v1/product/traceability/$TRAC_ID/stages" \-H "Content-Type: application/json" \-d '{"sequenceOrder": 4,"stageName": "Dyeing and sewing","companyType": "COMPANY","companyId": "your-company-uuid…","internalProcess": "Dyed with low-impact reactive dyes, sewn in Prato","transportMode": "TRUCK","startsFromCompany": true,"distanceKm": 180,"co2Emissions": 23.0,"certificationsSnapshot": "OEKO-TEX"}'
7. Read the full journey
curl "{{BASE_URL}}/api/v1/product/traceability/$TRAC_ID"
The response contains the header and every stage (sorted by sequenceOrder) together with the aggregated totalCo2PerKg and totalDistanceKm.
8. Correct a mistake
Update a stage
curl -X PATCH "{{BASE_URL}}/api/v1/product/traceability/stages/$STAGE_ID" \-H "Content-Type: application/json" \-d '{ "co2Emissions": 12.7, "distanceKm": 95 }'
Remove a stage
curl -X DELETE "{{BASE_URL}}/api/v1/product/traceability/stages/$STAGE_ID"
The parent journey's aggregates are recomputed automatically.
9. Render a timeline on your side
With the full journey JSON you have everything needed to render a timeline UI:
- stages sorted by
sequenceOrder - party per stage (
companyType,supplierId/companyId) - transport leg (
transportMode,distanceKm,co2Emissions) - certifications active at each stage (
certificationsSnapshot)
For a lighter, batch-level alternative — e.g. documenting the provenance of a single shipment without modeling the full chain — use the Traceability Records API.