{"openapi":"3.1.0","info":{"title":"Zeropact LCA API","description":"Submit one product per request and receive a ProductOutput document containing product details, lifecycle inventory, impact results, and traceability. Authenticate requests with X-API-Key. Input validation supports flexible and strict profiles. Batch submissions follow via the batch process call","version":"1.2.6"},"paths":{"/health":{"get":{"tags":["Service"],"summary":"Health","operationId":"health_health_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/v1/samples":{"get":{"tags":["Examples"],"summary":"List Samples","operationId":"list_samples_v1_samples_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/v1/samples/{sample_id}":{"get":{"tags":["Examples"],"summary":"Get Sample","operationId":"get_sample_v1_samples__sample_id__get","parameters":[{"name":"sample_id","in":"path","required":true,"schema":{"type":"string","title":"Sample Id"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/examples/output-with-traces":{"get":{"tags":["Examples"],"summary":"Trace Example","operationId":"trace_example_v1_examples_output_with_traces_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/schemas/{name}":{"get":{"tags":["Contracts"],"summary":"Schema","operationId":"schema_schemas__name__get","parameters":[{"name":"name","in":"path","required":true,"schema":{"type":"string","title":"Name"}}],"responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}},"/v1/products/calculate":{"post":{"tags":["Products"],"summary":"Calculate one product LCA","operationId":"calculate_v1_products_calculate_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"profile","in":"query","required":false,"schema":{"enum":["flexible","strict"],"type":"string","default":"flexible","title":"Profile"}},{"name":"output_variant","in":"query","required":false,"schema":{"enum":["standard","with-traces"],"type":"string","description":"with-traces selects the bundled bottle trace output for either bottle example; other inputs must use standard.","default":"standard","title":"Output Variant"},"description":"with-traces selects the bundled bottle trace output for either bottle example; other inputs must use standard."}],"responses":{"200":{"description":"ProductOutput containing inventory, impacts, and traceability.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProductOutput"},"example":{"product":{"product_id":"13435934-a6ea-52d4-8e0c-59b44b5d65ef","product_version":"2026-09-01T10:00:00Z","tenant_id":"977c02ae-a5c0-5759-9bcd-ea8bf922855a","run_id":"e67fe78e-5392-5198-be9b-2be79fc773e5","sku":"WB-1000","name":"HydroFlow Reusable Bottle","description":"750ml stainless steel reusable water bottle","brand":"HydroFlow","customer_category":"Drinkware","url":"https://example.com/products/wb-1000","category":{"id":"6d55190e-e0de-519c-a299-6e2bd7d3d320","name":"Reusable Bottles","description":"Reusable drinkware"},"manufacturing_location":{"id":"07e0760c-029f-5a77-b0d4-c56cc7295352","name":"United States","short_name":"US"},"is_active":true,"physical_properties":{"weight":0.32,"weight_unit":{"id":"8a1fc1f2-56b6-5c1f-87fe-9bb79dc55ead","name":"kg"},"volume":0.75,"volume_unit":{"id":"fd33c712-ce1c-5896-8b57-b4cbb0daf923","name":"l"},"density":null,"density_unit":null},"system_boundary":"cradle-to-gate","functional_unit":"One unit of product"},"materials":[{"id":"df3cfe84-71ed-5117-a568-9c60313d83d2","name":"Stainless steel","technical_name":null,"amount":0.3,"unit":{"id":"8a1fc1f2-56b6-5c1f-87fe-9bb79dc55ead","name":"kg"},"geography":{"id":"055566e1-ca64-52d9-a582-e6e63a6b9a6a","name":"China","short_name":"CN"},"mapped_process":{"beautified_name":"Steel Production, Chromium Steel 18/8","id":"a5e48697-4324-58fc-b1b0-049d91f52252","geography":{"id":"39d60bbf-1d54-5cd1-a3f1-1058c79f4157","name":"Global","short_name":"GLO"},"unit":{"id":"8a1fc1f2-56b6-5c1f-87fe-9bb79dc55ead","name":"kg"},"source":{"id":"1288ab27-21e7-52ef-9d24-aec2d69ed853","name":"ecoinvent","version":"3.12","system_model":"cutoff"},"organic":null,"recycled":false,"certification":null}}],"packaging":[{"id":"18319992-f2f6-5c66-b88a-a2d0816ac15f","name":"Cardboard box","technical_name":null,"amount":0.05,"unit":{"id":"8a1fc1f2-56b6-5c1f-87fe-9bb79dc55ead","name":"kg"},"geography":{"id":"07e0760c-029f-5a77-b0d4-c56cc7295352","name":"United States","short_name":"US"},"mapped_process":{"beautified_name":"Recycled Corrugated Board Box Production","id":"d84d367b-4872-5f63-9e1a-d7885b7a2a2b","geography":{"id":"07e0760c-029f-5a77-b0d4-c56cc7295352","name":"United States","short_name":"US"},"unit":{"id":"8a1fc1f2-56b6-5c1f-87fe-9bb79dc55ead","name":"kg"},"source":{"id":"1288ab27-21e7-52ef-9d24-aec2d69ed853","name":"ecoinvent","version":"3.12","system_model":"cutoff"},"organic":null,"recycled":true,"certification":null}}],"transports":[{"id":"a286bc20-ff8d-5681-83c7-64d0346c9995","name":"Ocean freight CN to US","description":null,"amount":3.3,"unit":{"id":"ba53f9c7-fa8e-5acc-b46b-09d8faf1abdb","name":"metric ton*km"},"origin":{"id":"055566e1-ca64-52d9-a582-e6e63a6b9a6a","name":"China","short_name":"CN"},"destination":{"id":"07e0760c-029f-5a77-b0d4-c56cc7295352","name":"United States","short_name":"US"},"transport_mode":"container_ship","transport_medium":"sea","distance_km":11000,"weight_kg":0.3,"mapped_process":{"beautified_name":"Transport, Freight, Sea, Container Ship","id":"34b2849e-5e3d-58f5-82d5-73cda0ecaa88","geography":{"id":"39d60bbf-1d54-5cd1-a3f1-1058c79f4157","name":"Global","short_name":"GLO"},"unit":{"id":"ba53f9c7-fa8e-5acc-b46b-09d8faf1abdb","name":"metric ton*km"},"source":{"id":"1288ab27-21e7-52ef-9d24-aec2d69ed853","name":"ecoinvent","version":"3.12","system_model":"cutoff"}}}],"manufacturing":[{"id":"8a1b3e39-c719-5f83-ba0a-a4c350da5a97","name":"Injection moulding","description":null,"amount":0.3,"unit":{"id":"8a1fc1f2-56b6-5c1f-87fe-9bb79dc55ead","name":"kg"},"geography":{"id":"07e0760c-029f-5a77-b0d4-c56cc7295352","name":"United States","short_name":"US"},"mapped_process":{"beautified_name":"Injection Moulding","id":"10185b28-7fd6-578d-87aa-7b5b912c8156","geography":{"id":"07e0760c-029f-5a77-b0d4-c56cc7295352","name":"United States","short_name":"US"},"unit":{"id":"8a1fc1f2-56b6-5c1f-87fe-9bb79dc55ead","name":"kg"},"source":{"id":"1288ab27-21e7-52ef-9d24-aec2d69ed853","name":"ecoinvent","version":"3.12","system_model":"cutoff"}}}],"market_mix":[{"id":"134e3450-cb54-56fa-9604-2b55415a5809","country":"US","share":1.0,"geography":{"id":"07e0760c-029f-5a77-b0d4-c56cc7295352","name":"United States","short_name":"US"}}],"inventory":[{"inventory_item_id":"cd9ba6e3-0d6c-5b5c-ae4d-b6d6ad18bba7","inventory_id":"8ccddaaa-55a7-51b6-9d5b-f3050c8385eb","name":"Stainless steel","lifecycle_stage":"Raw Materials","amount":0.3,"unit":{"id":"8a1fc1f2-56b6-5c1f-87fe-9bb79dc55ead","name":"kg"},"geography":{"id":"055566e1-ca64-52d9-a582-e6e63a6b9a6a","name":"China","short_name":"CN"},"converted_amount":null,"converted_unit":null,"mapped_process":{"beautified_name":"Steel Production, Chromium Steel 18/8","id":"a5e48697-4324-58fc-b1b0-049d91f52252","geography":{"id":"39d60bbf-1d54-5cd1-a3f1-1058c79f4157","name":"Global","short_name":"GLO"},"unit":{"id":"8a1fc1f2-56b6-5c1f-87fe-9bb79dc55ead","name":"kg"},"source":{"id":"1288ab27-21e7-52ef-9d24-aec2d69ed853","name":"ecoinvent","version":"3.12","system_model":"cutoff"}}},{"inventory_item_id":"9a5eeb82-49fd-5ad2-be16-4ddd2849461e","inventory_id":"7abd9ed2-7145-57ab-a8a0-aedcb40b80a4","name":"Cardboard box","lifecycle_stage":"Packaging","amount":0.05,"unit":{"id":"8a1fc1f2-56b6-5c1f-87fe-9bb79dc55ead","name":"kg"},"geography":{"id":"07e0760c-029f-5a77-b0d4-c56cc7295352","name":"United States","short_name":"US"},"converted_amount":null,"converted_unit":null,"mapped_process":{"beautified_name":"Recycled Corrugated Board Box Production","id":"d84d367b-4872-5f63-9e1a-d7885b7a2a2b","geography":{"id":"07e0760c-029f-5a77-b0d4-c56cc7295352","name":"United States","short_name":"US"},"unit":{"id":"8a1fc1f2-56b6-5c1f-87fe-9bb79dc55ead","name":"kg"},"source":{"id":"1288ab27-21e7-52ef-9d24-aec2d69ed853","name":"ecoinvent","version":"3.12","system_model":"cutoff"}}},{"inventory_item_id":"cb511d2b-ba5c-558b-8224-2994dadedf2e","inventory_id":"44af5e9e-4706-5b77-af50-48bf4b6dd2e9","name":"Ocean freight CN to US","lifecycle_stage":"Transportation","amount":3.3,"unit":{"id":"ba53f9c7-fa8e-5acc-b46b-09d8faf1abdb","name":"metric ton*km"},"geography":{"id":"39d60bbf-1d54-5cd1-a3f1-1058c79f4157","name":"Global","short_name":"GLO"},"converted_amount":null,"converted_unit":null,"mapped_process":{"beautified_name":"Transport, Freight, Sea, Container Ship","id":"34b2849e-5e3d-58f5-82d5-73cda0ecaa88","geography":{"id":"39d60bbf-1d54-5cd1-a3f1-1058c79f4157","name":"Global","short_name":"GLO"},"unit":{"id":"ba53f9c7-fa8e-5acc-b46b-09d8faf1abdb","name":"metric ton*km"},"source":{"id":"1288ab27-21e7-52ef-9d24-aec2d69ed853","name":"ecoinvent","version":"3.12","system_model":"cutoff"}}},{"inventory_item_id":"18561175-16b1-544f-8588-db2956366422","inventory_id":"25539ab9-0027-5733-8d69-d34735d8fbeb","name":"Injection moulding","lifecycle_stage":"Manufacturing","amount":0.3,"unit":{"id":"8a1fc1f2-56b6-5c1f-87fe-9bb79dc55ead","name":"kg"},"geography":{"id":"07e0760c-029f-5a77-b0d4-c56cc7295352","name":"United States","short_name":"US"},"converted_amount":null,"converted_unit":null,"mapped_process":{"beautified_name":"Injection Moulding","id":"10185b28-7fd6-578d-87aa-7b5b912c8156","geography":{"id":"07e0760c-029f-5a77-b0d4-c56cc7295352","name":"United States","short_name":"US"},"unit":{"id":"8a1fc1f2-56b6-5c1f-87fe-9bb79dc55ead","name":"kg"},"source":{"id":"1288ab27-21e7-52ef-9d24-aec2d69ed853","name":"ecoinvent","version":"3.12","system_model":"cutoff"}}}],"impacts_by_inventory_item":[{"inventory_item":{"inventory_item_id":"cd9ba6e3-0d6c-5b5c-ae4d-b6d6ad18bba7","name":"Stainless steel","description":null,"unit":{"id":"8a1fc1f2-56b6-5c1f-87fe-9bb79dc55ead","name":"kg"}},"mapped_process":{"beautified_name":"Steel Production, Chromium Steel 18/8","id":"a5e48697-4324-58fc-b1b0-049d91f52252","geography":{"id":"39d60bbf-1d54-5cd1-a3f1-1058c79f4157","name":"Global","short_name":"GLO"},"unit":{"id":"8a1fc1f2-56b6-5c1f-87fe-9bb79dc55ead","name":"kg"},"source":{"id":"1288ab27-21e7-52ef-9d24-aec2d69ed853","name":"ecoinvent","version":"3.12","system_model":"cutoff"}},"impact_indicator":{"id":"27e45c71-11c8-5298-9add-66a93ce3d1fa","name":"Climate change, total","unit":"kg CO2 eq","category":{"id":"8d47eab7-7fe7-5415-a5fa-3d378470063c","name":"Climate change"},"method":{"id":"ae6bcbbf-bf75-5ca6-8a32-1204cddb9e9a","name":"EF 3.1"}},"amount":1.82},{"inventory_item":{"inventory_item_id":"cd9ba6e3-0d6c-5b5c-ae4d-b6d6ad18bba7","name":"Stainless steel","description":null,"unit":{"id":"8a1fc1f2-56b6-5c1f-87fe-9bb79dc55ead","name":"kg"}},"mapped_process":{"beautified_name":"Steel Production, Chromium Steel 18/8","id":"a5e48697-4324-58fc-b1b0-049d91f52252","geography":{"id":"39d60bbf-1d54-5cd1-a3f1-1058c79f4157","name":"Global","short_name":"GLO"},"unit":{"id":"8a1fc1f2-56b6-5c1f-87fe-9bb79dc55ead","name":"kg"},"source":{"id":"1288ab27-21e7-52ef-9d24-aec2d69ed853","name":"ecoinvent","version":"3.12","system_model":"cutoff"}},"impact_indicator":{"id":"7baf25d4-1ebe-5987-94de-2cc548106ec9","name":"Water use","unit":"m3 depriv.","category":{"id":"2eab2077-f6bd-5cf9-9145-29ac07502137","name":"Water use"},"method":{"id":"ae6bcbbf-bf75-5ca6-8a32-1204cddb9e9a","name":"EF 3.1"}},"amount":0.004},{"inventory_item":{"inventory_item_id":"9a5eeb82-49fd-5ad2-be16-4ddd2849461e","name":"Cardboard box","description":null,"unit":{"id":"8a1fc1f2-56b6-5c1f-87fe-9bb79dc55ead","name":"kg"}},"mapped_process":{"beautified_name":"Recycled Corrugated Board Box Production","id":"d84d367b-4872-5f63-9e1a-d7885b7a2a2b","geography":{"id":"07e0760c-029f-5a77-b0d4-c56cc7295352","name":"United States","short_name":"US"},"unit":{"id":"8a1fc1f2-56b6-5c1f-87fe-9bb79dc55ead","name":"kg"},"source":{"id":"1288ab27-21e7-52ef-9d24-aec2d69ed853","name":"ecoinvent","version":"3.12","system_model":"cutoff"}},"impact_indicator":{"id":"27e45c71-11c8-5298-9add-66a93ce3d1fa","name":"Climate change, total","unit":"kg CO2 eq","category":{"id":"8d47eab7-7fe7-5415-a5fa-3d378470063c","name":"Climate change"},"method":{"id":"ae6bcbbf-bf75-5ca6-8a32-1204cddb9e9a","name":"EF 3.1"}},"amount":0.03},{"inventory_item":{"inventory_item_id":"cb511d2b-ba5c-558b-8224-2994dadedf2e","name":"Ocean freight CN to US","description":null,"unit":{"id":"ba53f9c7-fa8e-5acc-b46b-09d8faf1abdb","name":"metric ton*km"}},"mapped_process":{"beautified_name":"Transport, Freight, Sea, Container Ship","id":"34b2849e-5e3d-58f5-82d5-73cda0ecaa88","geography":{"id":"39d60bbf-1d54-5cd1-a3f1-1058c79f4157","name":"Global","short_name":"GLO"},"unit":{"id":"ba53f9c7-fa8e-5acc-b46b-09d8faf1abdb","name":"metric ton*km"},"source":{"id":"1288ab27-21e7-52ef-9d24-aec2d69ed853","name":"ecoinvent","version":"3.12","system_model":"cutoff"}},"impact_indicator":{"id":"27e45c71-11c8-5298-9add-66a93ce3d1fa","name":"Climate change, total","unit":"kg CO2 eq","category":{"id":"8d47eab7-7fe7-5415-a5fa-3d378470063c","name":"Climate change"},"method":{"id":"ae6bcbbf-bf75-5ca6-8a32-1204cddb9e9a","name":"EF 3.1"}},"amount":0.09},{"inventory_item":{"inventory_item_id":"18561175-16b1-544f-8588-db2956366422","name":"Injection moulding","description":null,"unit":{"id":"8a1fc1f2-56b6-5c1f-87fe-9bb79dc55ead","name":"kg"}},"mapped_process":{"beautified_name":"Injection Moulding","id":"10185b28-7fd6-578d-87aa-7b5b912c8156","geography":{"id":"07e0760c-029f-5a77-b0d4-c56cc7295352","name":"United States","short_name":"US"},"unit":{"id":"8a1fc1f2-56b6-5c1f-87fe-9bb79dc55ead","name":"kg"},"source":{"id":"1288ab27-21e7-52ef-9d24-aec2d69ed853","name":"ecoinvent","version":"3.12","system_model":"cutoff"}},"impact_indicator":{"id":"27e45c71-11c8-5298-9add-66a93ce3d1fa","name":"Climate change, total","unit":"kg CO2 eq","category":{"id":"8d47eab7-7fe7-5415-a5fa-3d378470063c","name":"Climate change"},"method":{"id":"ae6bcbbf-bf75-5ca6-8a32-1204cddb9e9a","name":"EF 3.1"}},"amount":0.21}],"aggregated_results":[{"stage":"Raw Materials","aggregation_basis":"PRODUCT_LIFETIME","impact_indicator":{"id":"27e45c71-11c8-5298-9add-66a93ce3d1fa","name":"Climate change, total","unit":"kg CO2 eq","category":{"id":"8d47eab7-7fe7-5415-a5fa-3d378470063c","name":"Climate change"},"method":{"id":"ae6bcbbf-bf75-5ca6-8a32-1204cddb9e9a","name":"EF 3.1"}},"amount":1.82},{"stage":"Raw Materials","aggregation_basis":"PRODUCT_LIFETIME","impact_indicator":{"id":"7baf25d4-1ebe-5987-94de-2cc548106ec9","name":"Water use","unit":"m3 depriv.","category":{"id":"2eab2077-f6bd-5cf9-9145-29ac07502137","name":"Water use"},"method":{"id":"ae6bcbbf-bf75-5ca6-8a32-1204cddb9e9a","name":"EF 3.1"}},"amount":0.004},{"stage":"Packaging","aggregation_basis":"PRODUCT_LIFETIME","impact_indicator":{"id":"27e45c71-11c8-5298-9add-66a93ce3d1fa","name":"Climate change, total","unit":"kg CO2 eq","category":{"id":"8d47eab7-7fe7-5415-a5fa-3d378470063c","name":"Climate change"},"method":{"id":"ae6bcbbf-bf75-5ca6-8a32-1204cddb9e9a","name":"EF 3.1"}},"amount":0.03},{"stage":"Transportation","aggregation_basis":"PRODUCT_LIFETIME","impact_indicator":{"id":"27e45c71-11c8-5298-9add-66a93ce3d1fa","name":"Climate change, total","unit":"kg CO2 eq","category":{"id":"8d47eab7-7fe7-5415-a5fa-3d378470063c","name":"Climate change"},"method":{"id":"ae6bcbbf-bf75-5ca6-8a32-1204cddb9e9a","name":"EF 3.1"}},"amount":0.09},{"stage":"Manufacturing","aggregation_basis":"PRODUCT_LIFETIME","impact_indicator":{"id":"27e45c71-11c8-5298-9add-66a93ce3d1fa","name":"Climate change, total","unit":"kg CO2 eq","category":{"id":"8d47eab7-7fe7-5415-a5fa-3d378470063c","name":"Climate change"},"method":{"id":"ae6bcbbf-bf75-5ca6-8a32-1204cddb9e9a","name":"EF 3.1"}},"amount":0.21},{"stage":"Total","aggregation_basis":"PRODUCT_LIFETIME","impact_indicator":{"id":"27e45c71-11c8-5298-9add-66a93ce3d1fa","name":"Climate change, total","unit":"kg CO2 eq","category":{"id":"8d47eab7-7fe7-5415-a5fa-3d378470063c","name":"Climate change"},"method":{"id":"ae6bcbbf-bf75-5ca6-8a32-1204cddb9e9a","name":"EF 3.1"}},"amount":2.15},{"stage":"Total","aggregation_basis":"PRODUCT_LIFETIME","impact_indicator":{"id":"7baf25d4-1ebe-5987-94de-2cc548106ec9","name":"Water use","unit":"m3 depriv.","category":{"id":"2eab2077-f6bd-5cf9-9145-29ac07502137","name":"Water use"},"method":{"id":"ae6bcbbf-bf75-5ca6-8a32-1204cddb9e9a","name":"EF 3.1"}},"amount":0.004}],"issues":[],"traces":[]}}}},"400":{"description":"Invalid JSON or input contract"},"401":{"description":"Missing or invalid API key"},"413":{"description":"Input exceeds 128 KiB"},"415":{"description":"JSON required"},"429":{"description":"Rate or concurrency limit"},"502":{"description":"Invalid upstream calculation response"},"503":{"description":"Calculation service unavailable"},"504":{"description":"Calculation request timed out"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InputProduct/$defs/InputProductFlexible"},"examples":{"01-t-shirt":{"summary":"ASKET The T-Shirt — White","value":{"sku":"FASHION-FIXTURE-01-T-SHIRT","name":"ASKET The T-Shirt — White","description":"Production-only published-data benchmark for one garment. Product-page reference size/length and garment mass are undisclosed. Activity quantities are one published component/service bundle per garment, not measured kg, kWh or tonne-km. Main-fabric composition: 100% organic cotton.","brand":"ASKET","customer_category":"Fashion apparel","url":"https://www.asket.com/en-us/mens-t-shirt-white","manufacturing_location":"Portugal","physical_properties":null,"system_boundary":"cradle-to-gate","functional_unit":"One unit of product","materials":[{"name":"The T-Shirt (White) — Main Fabric bundle","description":"Published Main Fabric contribution for one reference garment, version 1.3. Exact physical activity undisclosed. Main-fabric composition: 100% organic cotton.","amount":1,"unit":"garment_component_bundle","geography":"Aggregated supply chain; exact geography unresolved"},{"name":"The T-Shirt (White) — Trims bundle","description":"Published Trims contribution for one reference garment, version 1.3. Exact physical activity undisclosed.","amount":1,"unit":"garment_component_bundle","geography":"Aggregated supply chain; exact geography unresolved"}],"packaging":[],"manufacturing":[{"name":"The T-Shirt (White) — Assembly bundle","description":"Published Assembly contribution for one reference garment, version 1.3. Exact physical activity undisclosed.","amount":1,"unit":"garment_assembly_bundle","geography":"Portugal"}],"transports":[{"name":"The T-Shirt (White) — Transport bundle","description":"Published Transport contribution for one reference garment, version 1.3. Exact physical activity undisclosed.","amount":1,"unit":"garment_transport_bundle","origin":null,"destination":null,"transport_mode":null,"transport_medium":null,"distance":null,"weight":null}]}},"02-long-sleeve":{"summary":"ASKET The Long Sleeve T-Shirt — Grey Melange","value":{"sku":"FASHION-FIXTURE-02-LONG-SLEEVE","name":"ASKET The Long Sleeve T-Shirt — Grey Melange","description":"Production-only published-data benchmark for one garment. Product-page reference size/length and garment mass are undisclosed. Activity quantities are one published component/service bundle per garment, not measured kg, kWh or tonne-km. Main-fabric composition: 100% organic cotton.","brand":"ASKET","customer_category":"Fashion apparel","url":"https://www.asket.com/en-us/mens-long-sleeve-t-shirt-grey-melange","manufacturing_location":"Portugal","physical_properties":null,"system_boundary":"cradle-to-gate","functional_unit":"One unit of product","materials":[{"name":"The Long Sleeve T-Shirt (Grey Melange) — Main Fabric bundle","description":"Published Main Fabric contribution for one reference garment, version 1.3. Exact physical activity undisclosed. Main-fabric composition: 100% organic cotton.","amount":1,"unit":"garment_component_bundle","geography":"Aggregated supply chain; exact geography unresolved"},{"name":"The Long Sleeve T-Shirt (Grey Melange) — Trims bundle","description":"Published Trims contribution for one reference garment, version 1.3. Exact physical activity undisclosed.","amount":1,"unit":"garment_component_bundle","geography":"Aggregated supply chain; exact geography unresolved"}],"packaging":[],"manufacturing":[{"name":"The Long Sleeve T-Shirt (Grey Melange) — Assembly bundle","description":"Published Assembly contribution for one reference garment, version 1.3. Exact physical activity undisclosed.","amount":1,"unit":"garment_assembly_bundle","geography":"Portugal"}],"transports":[{"name":"The Long Sleeve T-Shirt (Grey Melange) — Transport bundle","description":"Published Transport contribution for one reference garment, version 1.3. Exact physical activity undisclosed.","amount":1,"unit":"garment_transport_bundle","origin":null,"destination":null,"transport_mode":null,"transport_medium":null,"distance":null,"weight":null}]}},"03-oxford-shirt":{"summary":"ASKET The Oxford Shirt — White","value":{"sku":"FASHION-FIXTURE-03-OXFORD-SHIRT","name":"ASKET The Oxford Shirt — White","description":"Production-only published-data benchmark for one garment. Product-page reference size/length and garment mass are undisclosed. Activity quantities are one published component/service bundle per garment, not measured kg, kWh or tonne-km. Main-fabric composition: 100% organic cotton.","brand":"ASKET","customer_category":"Fashion apparel","url":"https://www.asket.com/en-us/mens-oxford-shirt-white","manufacturing_location":"Portugal","physical_properties":null,"system_boundary":"cradle-to-gate","functional_unit":"One unit of product","materials":[{"name":"The Oxford Shirt (White) — Main Fabric bundle","description":"Published Main Fabric contribution for one reference garment, version 1.5. Exact physical activity undisclosed. Main-fabric composition: 100% organic cotton.","amount":1,"unit":"garment_component_bundle","geography":"Aggregated supply chain; exact geography unresolved"},{"name":"The Oxford Shirt (White) — Trims bundle","description":"Published Trims contribution for one reference garment, version 1.5. Exact physical activity undisclosed.","amount":1,"unit":"garment_component_bundle","geography":"Aggregated supply chain; exact geography unresolved"}],"packaging":[],"manufacturing":[{"name":"The Oxford Shirt (White) — Assembly bundle","description":"Published Assembly contribution for one reference garment, version 1.5. Exact physical activity undisclosed.","amount":1,"unit":"garment_assembly_bundle","geography":"Portugal"}],"transports":[{"name":"The Oxford Shirt (White) — Transport bundle","description":"Published Transport contribution for one reference garment, version 1.5. Exact physical activity undisclosed.","amount":1,"unit":"garment_transport_bundle","origin":null,"destination":null,"transport_mode":null,"transport_medium":null,"distance":null,"weight":null}]}},"04-linen-shirt":{"summary":"ASKET The Linen Shirt — Dark Navy","value":{"sku":"FASHION-FIXTURE-04-LINEN-SHIRT","name":"ASKET The Linen Shirt — Dark Navy","description":"Production-only published-data benchmark for one garment. Product-page reference size/length and garment mass are undisclosed. Activity quantities are one published component/service bundle per garment, not measured kg, kWh or tonne-km. Main-fabric composition: 100% linen.","brand":"ASKET","customer_category":"Fashion apparel","url":"https://www.asket.com/en-us/mens-linen-shirt-dark-navy","manufacturing_location":"Portugal","physical_properties":null,"system_boundary":"cradle-to-gate","functional_unit":"One unit of product","materials":[{"name":"The Linen Shirt (Dark Navy) — Main Fabric bundle","description":"Published Main Fabric contribution for one reference garment, version 1.3. Exact physical activity undisclosed. Main-fabric composition: 100% linen.","amount":1,"unit":"garment_component_bundle","geography":"Aggregated supply chain; exact geography unresolved"},{"name":"The Linen Shirt (Dark Navy) — Trims bundle","description":"Published Trims contribution for one reference garment, version 1.3. Exact physical activity undisclosed.","amount":1,"unit":"garment_component_bundle","geography":"Aggregated supply chain; exact geography unresolved"}],"packaging":[],"manufacturing":[{"name":"The Linen Shirt (Dark Navy) — Assembly bundle","description":"Published Assembly contribution for one reference garment, version 1.3. Exact physical activity undisclosed.","amount":1,"unit":"garment_assembly_bundle","geography":"Portugal"}],"transports":[{"name":"The Linen Shirt (Dark Navy) — Transport bundle","description":"Published Transport contribution for one reference garment, version 1.3. Exact physical activity undisclosed.","amount":1,"unit":"garment_transport_bundle","origin":null,"destination":null,"transport_mode":null,"transport_medium":null,"distance":null,"weight":null}]}},"05-sweatshirt":{"summary":"ASKET The Sweatshirt — Grey Melange","value":{"sku":"FASHION-FIXTURE-05-SWEATSHIRT","name":"ASKET The Sweatshirt — Grey Melange","description":"Production-only published-data benchmark for one garment. Product-page reference size/length and garment mass are undisclosed. Activity quantities are one published component/service bundle per garment, not measured kg, kWh or tonne-km. Main-fabric composition: 100% organic cotton.","brand":"ASKET","customer_category":"Fashion apparel","url":"https://www.asket.com/en-us/mens-sweatshirt-grey-melange","manufacturing_location":"Portugal","physical_properties":null,"system_boundary":"cradle-to-gate","functional_unit":"One unit of product","materials":[{"name":"The Sweatshirt (Grey Melange) — Main Fabric bundle","description":"Published Main Fabric contribution for one reference garment, version 2.5. Exact physical activity undisclosed. Main-fabric composition: 100% organic cotton.","amount":1,"unit":"garment_component_bundle","geography":"Aggregated supply chain; exact geography unresolved"},{"name":"The Sweatshirt (Grey Melange) — Trims bundle","description":"Published Trims contribution for one reference garment, version 2.5. Exact physical activity undisclosed.","amount":1,"unit":"garment_component_bundle","geography":"Aggregated supply chain; exact geography unresolved"}],"packaging":[],"manufacturing":[{"name":"The Sweatshirt (Grey Melange) — Assembly bundle","description":"Published Assembly contribution for one reference garment, version 2.5. Exact physical activity undisclosed.","amount":1,"unit":"garment_assembly_bundle","geography":"Portugal"}],"transports":[{"name":"The Sweatshirt (Grey Melange) — Transport bundle","description":"Published Transport contribution for one reference garment, version 2.5. Exact physical activity undisclosed.","amount":1,"unit":"garment_transport_bundle","origin":null,"destination":null,"transport_mode":null,"transport_medium":null,"distance":null,"weight":null}]}},"06-hoodie":{"summary":"ASKET The Hoodie — Grey Melange","value":{"sku":"FASHION-FIXTURE-06-HOODIE","name":"ASKET The Hoodie — Grey Melange","description":"Production-only published-data benchmark for one garment. Product-page reference size/length and garment mass are undisclosed. Activity quantities are one published component/service bundle per garment, not measured kg, kWh or tonne-km. Main-fabric composition: 100% organic cotton.","brand":"ASKET","customer_category":"Fashion apparel","url":"https://www.asket.com/en-us/mens-hoodie-grey-melange","manufacturing_location":"Portugal","physical_properties":null,"system_boundary":"cradle-to-gate","functional_unit":"One unit of product","materials":[{"name":"The Hoodie (Grey Melange) — Main Fabric bundle","description":"Published Main Fabric contribution for one reference garment, version 1.4. Exact physical activity undisclosed. Main-fabric composition: 100% organic cotton.","amount":1,"unit":"garment_component_bundle","geography":"Aggregated supply chain; exact geography unresolved"},{"name":"The Hoodie (Grey Melange) — Trims bundle","description":"Published Trims contribution for one reference garment, version 1.4. Exact physical activity undisclosed.","amount":1,"unit":"garment_component_bundle","geography":"Aggregated supply chain; exact geography unresolved"}],"packaging":[],"manufacturing":[{"name":"The Hoodie (Grey Melange) — Assembly bundle","description":"Published Assembly contribution for one reference garment, version 1.4. Exact physical activity undisclosed.","amount":1,"unit":"garment_assembly_bundle","geography":"Portugal"}],"transports":[{"name":"The Hoodie (Grey Melange) — Transport bundle","description":"Published Transport contribution for one reference garment, version 1.4. Exact physical activity undisclosed.","amount":1,"unit":"garment_transport_bundle","origin":null,"destination":null,"transport_mode":null,"transport_medium":null,"distance":null,"weight":null}]}},"07-jeans":{"summary":"ASKET The Regular Jeans — Mid Blue Wash","value":{"sku":"FASHION-FIXTURE-07-JEANS","name":"ASKET The Regular Jeans — Mid Blue Wash","description":"Production-only published-data benchmark for one garment. Product-page reference size/length and garment mass are undisclosed. Activity quantities are one published component/service bundle per garment, not measured kg, kWh or tonne-km. Main-fabric composition: 100% organic cotton; pocket lining 100% organic cotton.","brand":"ASKET","customer_category":"Fashion apparel","url":"https://www.asket.com/en-us/mens-regular-jeans-mid-blue-wash","manufacturing_location":"Italy","physical_properties":null,"system_boundary":"cradle-to-gate","functional_unit":"One unit of product","materials":[{"name":"The Regular Jeans (Mid Blue Wash) — Main Fabric bundle","description":"Published Main Fabric contribution for one reference garment, version 2.0. Exact physical activity undisclosed. Main-fabric composition: 100% organic cotton; pocket lining 100% organic cotton.","amount":1,"unit":"garment_component_bundle","geography":"Aggregated supply chain; exact geography unresolved"},{"name":"The Regular Jeans (Mid Blue Wash) — Lining bundle","description":"Published Lining contribution for one reference garment, version 2.0. Exact physical activity undisclosed.","amount":1,"unit":"garment_component_bundle","geography":"Aggregated supply chain; exact geography unresolved"},{"name":"The Regular Jeans (Mid Blue Wash) — Trims bundle","description":"Published Trims contribution for one reference garment, version 2.0. Exact physical activity undisclosed.","amount":1,"unit":"garment_component_bundle","geography":"Aggregated supply chain; exact geography unresolved"}],"packaging":[],"manufacturing":[{"name":"The Regular Jeans (Mid Blue Wash) — Assembly bundle","description":"Published Assembly contribution for one reference garment, version 2.0. Exact physical activity undisclosed.","amount":1,"unit":"garment_assembly_bundle","geography":"Italy"}],"transports":[{"name":"The Regular Jeans (Mid Blue Wash) — Transport bundle","description":"Published Transport contribution for one reference garment, version 2.0. Exact physical activity undisclosed.","amount":1,"unit":"garment_transport_bundle","origin":null,"destination":null,"transport_mode":null,"transport_medium":null,"distance":null,"weight":null}]}},"08-chino":{"summary":"ASKET The Regular Chino — Khaki Green","value":{"sku":"FASHION-FIXTURE-08-CHINO","name":"ASKET The Regular Chino — Khaki Green","description":"Production-only published-data benchmark for one garment. Product-page reference size/length and garment mass are undisclosed. Activity quantities are one published component/service bundle per garment, not measured kg, kWh or tonne-km. Main-fabric composition: 98% organic cotton, 2% elastane; pocket lining 100% organic cotton.","brand":"ASKET","customer_category":"Fashion apparel","url":"https://www.asket.com/en-us/mens-regular-chino-khaki-green","manufacturing_location":"Portugal","physical_properties":null,"system_boundary":"cradle-to-gate","functional_unit":"One unit of product","materials":[{"name":"The Regular Chino (Khaki Green) — Main Fabric bundle","description":"Published Main Fabric contribution for one reference garment, version 1.1. Exact physical activity undisclosed. Main-fabric composition: 98% organic cotton, 2% elastane; pocket lining 100% organic cotton.","amount":1,"unit":"garment_component_bundle","geography":"Aggregated supply chain; exact geography unresolved"},{"name":"The Regular Chino (Khaki Green) — Lining bundle","description":"Published Lining contribution for one reference garment, version 1.1. Exact physical activity undisclosed.","amount":1,"unit":"garment_component_bundle","geography":"Aggregated supply chain; exact geography unresolved"},{"name":"The Regular Chino (Khaki Green) — Trims bundle","description":"Published Trims contribution for one reference garment, version 1.1. Exact physical activity undisclosed.","amount":1,"unit":"garment_component_bundle","geography":"Aggregated supply chain; exact geography unresolved"}],"packaging":[],"manufacturing":[{"name":"The Regular Chino (Khaki Green) — Assembly bundle","description":"Published Assembly contribution for one reference garment, version 1.1. Exact physical activity undisclosed.","amount":1,"unit":"garment_assembly_bundle","geography":"Portugal"}],"transports":[{"name":"The Regular Chino (Khaki Green) — Transport bundle","description":"Published Transport contribution for one reference garment, version 1.1. Exact physical activity undisclosed.","amount":1,"unit":"garment_transport_bundle","origin":null,"destination":null,"transport_mode":null,"transport_medium":null,"distance":null,"weight":null}]}},"09-merino-sweater":{"summary":"ASKET The Merino Sweater — Dark Navy","value":{"sku":"FASHION-FIXTURE-09-MERINO-SWEATER","name":"ASKET The Merino Sweater — Dark Navy","description":"Production-only published-data benchmark for one garment. Product-page reference size/length and garment mass are undisclosed. Activity quantities are one published component/service bundle per garment, not measured kg, kWh or tonne-km. Main-fabric composition: 100% merino wool.","brand":"ASKET","customer_category":"Fashion apparel","url":"https://www.asket.com/en-us/mens-merino-sweater-dark-navy","manufacturing_location":"Romania","physical_properties":null,"system_boundary":"cradle-to-gate","functional_unit":"One unit of product","materials":[{"name":"The Merino Sweater (Dark Navy) — Main Fabric bundle","description":"Published Main Fabric contribution for one reference garment, version 1.4. Exact physical activity undisclosed. Main-fabric composition: 100% merino wool.","amount":1,"unit":"garment_component_bundle","geography":"Aggregated supply chain; exact geography unresolved"},{"name":"The Merino Sweater (Dark Navy) — Trims bundle","description":"Published Trims contribution for one reference garment, version 1.4. Exact physical activity undisclosed.","amount":1,"unit":"garment_component_bundle","geography":"Aggregated supply chain; exact geography unresolved"}],"packaging":[],"manufacturing":[{"name":"The Merino Sweater (Dark Navy) — Assembly bundle","description":"Published Assembly contribution for one reference garment, version 1.4. Exact physical activity undisclosed.","amount":1,"unit":"garment_assembly_bundle","geography":"Romania"}],"transports":[{"name":"The Merino Sweater (Dark Navy) — Transport bundle","description":"Published Transport contribution for one reference garment, version 1.4. Exact physical activity undisclosed.","amount":1,"unit":"garment_transport_bundle","origin":null,"destination":null,"transport_mode":null,"transport_medium":null,"distance":null,"weight":null}]}},"10-cashmere-sweater":{"summary":"ASKET The Recycled Cashmere Sweater — Light Grey","value":{"sku":"FASHION-FIXTURE-10-CASHMERE-SWEATER","name":"ASKET The Recycled Cashmere Sweater — Light Grey","description":"Production-only published-data benchmark for one garment. Product-page reference size/length and garment mass are undisclosed. Activity quantities are one published component/service bundle per garment, not measured kg, kWh or tonne-km. Main-fabric composition: 97% recycled cashmere, 3% recycled wool.","brand":"ASKET","customer_category":"Fashion apparel","url":"https://www.asket.com/en-us/mens-recycled-cashmere-sweater-light-grey","manufacturing_location":"Romania","physical_properties":null,"system_boundary":"cradle-to-gate","functional_unit":"One unit of product","materials":[{"name":"The Recycled Cashmere Sweater (Light Grey) — Main Fabric bundle","description":"Published Main Fabric contribution for one reference garment, version 2.1. Exact physical activity undisclosed. Main-fabric composition: 97% recycled cashmere, 3% recycled wool.","amount":1,"unit":"garment_component_bundle","geography":"Aggregated supply chain; exact geography unresolved"},{"name":"The Recycled Cashmere Sweater (Light Grey) — Trims bundle","description":"Published Trims contribution for one reference garment, version 2.1. Exact physical activity undisclosed.","amount":1,"unit":"garment_component_bundle","geography":"Aggregated supply chain; exact geography unresolved"}],"packaging":[],"manufacturing":[{"name":"The Recycled Cashmere Sweater (Light Grey) — Assembly bundle","description":"Published Assembly contribution for one reference garment, version 2.1. Exact physical activity undisclosed.","amount":1,"unit":"garment_assembly_bundle","geography":"Romania"}],"transports":[{"name":"The Recycled Cashmere Sweater (Light Grey) — Transport bundle","description":"Published Transport contribution for one reference garment, version 2.1. Exact physical activity undisclosed.","amount":1,"unit":"garment_transport_bundle","origin":null,"destination":null,"transport_mode":null,"transport_medium":null,"distance":null,"weight":null}]}},"example-flexible":{"summary":"HydroFlow bottle · flexible","value":{"sku":"WB-1000","name":"HydroFlow Reusable Bottle","manufacturing_location":"United States","functional_unit":"One unit of product","system_boundary":"cradle-to-gate"}},"example-strict":{"summary":"HydroFlow bottle · strict","value":{"sku":"WB-1000","name":"HydroFlow Reusable Bottle","description":"750ml stainless steel reusable water bottle","brand":"HydroFlow","customer_category":"Drinkware","url":"https://example.com/products/wb-1000","physical_properties":{"weight":0.32,"weight_unit":"kg","volume":0.75,"volume_unit":"L","density":null,"density_unit":null},"system_boundary":"cradle-to-gate","functional_unit":"One unit of product","circularity":null,"use_stage":null,"market_mix":null,"end_of_life":null,"materials":[{"name":"Stainless steel","description":null,"unit":"kg","geography":"China","geography_code":null,"geography_name":null,"amount":0.3,"percentage":null,"supplier":null,"manufacturer":null,"organic":null,"recycled":false,"certification":null}],"packaging":[{"name":"Cardboard box","description":null,"unit":"kg","geography":"United States","geography_code":null,"geography_name":null,"amount":0.05,"percentage":null,"supplier":null,"manufacturer":null,"organic":null,"recycled":true,"certification":null}],"transports":[{"name":"Ocean freight CN to US","description":null,"unit":null,"geography":null,"amount":null,"origin":"China","destination":"United States","transport_mode":"container_ship","distance":11000,"distance_unit":"km","weight":0.3,"weight_unit":"kg","transport_medium":"sea"}],"manufacturing":[{"name":"Injection moulding","description":null,"unit":"kg","geography":"United States","geography_code":null,"geography_name":null,"amount":0.3}],"manufacturing_location":"United States"}}}}}}}},"/v1/batch/calculate":{"post":{"tags":["Products"],"summary":"Calculate a batch of product LCAs","description":"Submit 1–100 product objects in an items array. Products are processed sequentially in input order. Each result contains its zero-based index, status, and either output or error. Item failures do not stop subsequent products. A valid batch returns HTTP 200 even when some items fail; inspect each result status. The selected profile applies to all items. Each item consumes one shared quota unit, reserved before processing. Allow up to 90 seconds of calculation time per custom product. The response returns the first page (10 results by default; page_size accepts 1–100). Follow pagination.next_url to fetch subsequent pages without recalculating. Totals describe the entire batch. Completed results are retained for up to 30 minutes; restarts or cache capacity limits may remove them earlier.","operationId":"calculate_batch_v1_batch_calculate_post","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"profile","in":"query","required":false,"schema":{"enum":["flexible","strict"],"type":"string","default":"flexible","title":"Profile"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"description":"Results per page; does not limit how many products are calculated.","default":10,"title":"Page Size"},"description":"Results per page; does not limit how many products are calculated."}],"responses":{"200":{"description":"First page of ordered results, batch totals, and pagination links","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchResponse"}}}},"400":{"description":"Invalid JSON or batch envelope"},"401":{"description":"Missing or invalid API key"},"413":{"description":"Batch body exceeds 12,800 KiB"},"415":{"description":"JSON required"},"429":{"description":"Insufficient quota for the complete batch; no products processed"},"503":{"description":"Completed results exceed cache capacity"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchRequest"},"example":{"items":[{"sku":"FASHION-FIXTURE-01-T-SHIRT","name":"ASKET The T-Shirt — White","description":"Production-only published-data benchmark for one garment. Product-page reference size/length and garment mass are undisclosed. Activity quantities are one published component/service bundle per garment, not measured kg, kWh or tonne-km. Main-fabric composition: 100% organic cotton.","brand":"ASKET","customer_category":"Fashion apparel","url":"https://www.asket.com/en-us/mens-t-shirt-white","manufacturing_location":"Portugal","physical_properties":null,"system_boundary":"cradle-to-gate","functional_unit":"One unit of product","materials":[{"name":"The T-Shirt (White) — Main Fabric bundle","description":"Published Main Fabric contribution for one reference garment, version 1.3. Exact physical activity undisclosed. Main-fabric composition: 100% organic cotton.","amount":1,"unit":"garment_component_bundle","geography":"Aggregated supply chain; exact geography unresolved"},{"name":"The T-Shirt (White) — Trims bundle","description":"Published Trims contribution for one reference garment, version 1.3. Exact physical activity undisclosed.","amount":1,"unit":"garment_component_bundle","geography":"Aggregated supply chain; exact geography unresolved"}],"packaging":[],"manufacturing":[{"name":"The T-Shirt (White) — Assembly bundle","description":"Published Assembly contribution for one reference garment, version 1.3. Exact physical activity undisclosed.","amount":1,"unit":"garment_assembly_bundle","geography":"Portugal"}],"transports":[{"name":"The T-Shirt (White) — Transport bundle","description":"Published Transport contribution for one reference garment, version 1.3. Exact physical activity undisclosed.","amount":1,"unit":"garment_transport_bundle","origin":null,"destination":null,"transport_mode":null,"transport_medium":null,"distance":null,"weight":null}]},{"sku":"FASHION-FIXTURE-02-LONG-SLEEVE","name":"ASKET The Long Sleeve T-Shirt — Grey Melange","description":"Production-only published-data benchmark for one garment. Product-page reference size/length and garment mass are undisclosed. Activity quantities are one published component/service bundle per garment, not measured kg, kWh or tonne-km. Main-fabric composition: 100% organic cotton.","brand":"ASKET","customer_category":"Fashion apparel","url":"https://www.asket.com/en-us/mens-long-sleeve-t-shirt-grey-melange","manufacturing_location":"Portugal","physical_properties":null,"system_boundary":"cradle-to-gate","functional_unit":"One unit of product","materials":[{"name":"The Long Sleeve T-Shirt (Grey Melange) — Main Fabric bundle","description":"Published Main Fabric contribution for one reference garment, version 1.3. Exact physical activity undisclosed. Main-fabric composition: 100% organic cotton.","amount":1,"unit":"garment_component_bundle","geography":"Aggregated supply chain; exact geography unresolved"},{"name":"The Long Sleeve T-Shirt (Grey Melange) — Trims bundle","description":"Published Trims contribution for one reference garment, version 1.3. Exact physical activity undisclosed.","amount":1,"unit":"garment_component_bundle","geography":"Aggregated supply chain; exact geography unresolved"}],"packaging":[],"manufacturing":[{"name":"The Long Sleeve T-Shirt (Grey Melange) — Assembly bundle","description":"Published Assembly contribution for one reference garment, version 1.3. Exact physical activity undisclosed.","amount":1,"unit":"garment_assembly_bundle","geography":"Portugal"}],"transports":[{"name":"The Long Sleeve T-Shirt (Grey Melange) — Transport bundle","description":"Published Transport contribution for one reference garment, version 1.3. Exact physical activity undisclosed.","amount":1,"unit":"garment_transport_bundle","origin":null,"destination":null,"transport_mode":null,"transport_medium":null,"distance":null,"weight":null}]}]}}}}}},"/v1/batch/{batch_id}/results":{"get":{"tags":["Products"],"summary":"Retrieve a page of batch results","description":"Retrieve completed results using the batch ID returned by POST /v1/batch/calculate. Use the same tenant's API key. Page numbers start at 1; totals cover the entire batch. Reading pages does not recalculate products or consume calculation quota. Results expire after 30 minutes and may be removed earlier by a restart or cache capacity limits.","operationId":"batch_results_v1_batch__batch_id__results_get","security":[{"APIKeyHeader":[]}],"parameters":[{"name":"batch_id","in":"path","required":true,"schema":{"type":"string","title":"Batch Id"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1,"default":1,"title":"Page"}},{"name":"page_size","in":"query","required":false,"schema":{"type":"integer","maximum":100,"minimum":1,"default":10,"title":"Page Size"}}],"responses":{"200":{"description":"Page of results and whole-batch totals","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BatchResponse"}}}},"400":{"description":"Page is outside the batch result range"},"401":{"description":"Missing or invalid API key"},"404":{"description":"Batch not found, expired, or unavailable to this tenant"},"422":{"description":"Validation Error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HTTPValidationError"}}}}}}}},"components":{"schemas":{"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"},"InputProduct":{"$schema":"https://json-schema.org/draft/2020-12/schema","title":"Zeropact ProductInput Shared Contract","description":"Shared JSON Schema definitions for customer product input. Two entry profiles exist: product-input-flexible.schema.json (minimum viable declaration) and product-input-strict.schema.json (full lifecycle inventory for calculation). The FLEXIBLE profile is the product's default customer lane -- five core fields, no lifecycle knowledge required, gaps filled by enrichment/inference; STRICT is an opt-in contract for complete, calculation-ready payloads (API-to-API integrations, mature customers), and its line-item requirements (including transport mode-or-medium) only bind payloads that claim that completeness. Product identity fields such as product_id and product_version are assigned at ingest and must not appear in customer input. Methodology tracking is intentionally deferred from this input contract.","$ref":"#/components/schemas/InputProduct/$defs/InputProductFlexible","$defs":{"UseStageArchetype":{"description":"Target vocabulary. Membership does not imply an active reference model; see use_stage/data-model.md §4.10.","type":"string","enum":["washable_textile","non_washable_wearable","plug_in_continuous_appliance","plug_in_cycle_appliance","battery_powered_portable","fuel_consuming_device","water_consuming_fixture","cosmetic_consumable","durable_static","single_use_consumable"]},"UseStageCompositionArchetype":{"description":"Named for materials only. Never repeats the archetype or the product type.","type":"string","enum":["cotton","cotton_polyester_blend","synthetic_textile","leather","synthetic_leather","generic"]},"DurationUnit":{"type":"string","enum":["day","week","month","year"]},"LifetimeBasis":{"type":"string","enum":["lifetime_uses","lifetime_cycles","service_life_years","lifetime_distance"]},"WasteTreatmentType":{"description":"Terminal fates only. The non-terminal diagnostic values (OPEN_BURNING, MBT, RDF_PRODUCTION, UNACCOUNTED) are deliberately absent: they never enter a partition. See eol/waste-treatment-types.md §1.2.","type":"string","enum":["RECYCLING_MATERIAL","RECYCLING_COMPOST","PREP_REUSE","ENERGY_RECOVERY_INCIN","INCINERATION_NO_RECOVERY","LANDFILL_SANITARY","LANDFILL_UNSANITARY","OPEN_DUMP","LANDFILL_UNSPECIFIED","UNCOLLECTED","OTHER_DISPOSAL"]},"MaterialRecyclability":{"description":"Mutually exclusive. `compostable` is not `organic`: an organic-certified textile is `recyclable`.","type":"string","enum":["compostable","recyclable","not_recyclable"]},"Share":{"description":"A fraction of one. The field is named `share` everywhere; `fraction` is not an alias.","type":"number","minimum":0,"maximum":1},"NonNegativeNumber":{"type":"number","minimum":0},"Quantity":{"description":"Every reference-pack value is {value, unit}, never a bare number. A unit mismatch against the declared parameter unit is a load error, not a runtime coercion.","type":"object","additionalProperties":false,"required":["value","unit"],"properties":{"value":{"type":"number"},"unit":{"type":"string","minLength":1}}},"EvidenceProof":{"description":"A reference to an approved evidence object, never a free-floating URL.","type":"object","additionalProperties":false,"required":["document_name","source_reference"],"properties":{"document_name":{"type":"string","minLength":1},"source_reference":{"type":"string","minLength":1}}},"InputMultiplier":{"description":"`multiplier: null` means not provided. It does not mean zero and does not override a reference default. Omitting the whole object resolves the same way but records no object-level provenance.","type":"object","additionalProperties":false,"required":["multiplier"],"properties":{"multiplier":{"type":["number","null"],"exclusiveMinimum":0},"proof":{"anyOf":[{"$ref":"#/components/schemas/InputProduct/$defs/EvidenceProof"},{"type":"null"}]}},"allOf":[{"description":"A proof may not be supplied without a non-null multiplier.","if":{"required":["proof"],"properties":{"proof":{"type":"object"}}},"then":{"properties":{"multiplier":{"type":"number"}}}}]},"InputLifetime":{"type":"object","additionalProperties":false,"required":["duration","unit"],"properties":{"duration":{"type":"number","exclusiveMinimum":0,"default":1},"unit":{"$ref":"#/components/schemas/InputProduct/$defs/DurationUnit"}}},"UsesPerDurationQuantity":{"description":"Typed usage frequency. The unit is part of the value, so 3/year cannot be confused with 3/month. An active usage model must resolve a strictly positive value.","type":"object","additionalProperties":false,"required":["value","unit"],"properties":{"value":{"$ref":"#/components/schemas/InputProduct/$defs/NonNegativeNumber"},"unit":{"$ref":"#/components/schemas/InputProduct/$defs/DurationUnit"}}},"InputCircularity":{"description":"Product-level circularity characteristics. Applies in both use-stage input modes: the Specific DoS is the per-use denominator regardless of whether the customer supplied mode-A parameters or mode-B inventories. `total_uses` is optional when duration x uses_per_duration_unit resolves; when supplied it is authoritative and the derived value is kept only as a diagnostic.","type":"object","additionalProperties":false,"properties":{"uses_per_duration_unit":{"anyOf":[{"$ref":"#/components/schemas/InputProduct/$defs/UsesPerDurationQuantity"},{"type":"null"}]},"lifetime":{"anyOf":[{"$ref":"#/components/schemas/InputProduct/$defs/InputLifetime"},{"type":"null"}]},"total_uses":{"type":["number","null"],"exclusiveMinimum":0},"durability":{"anyOf":[{"$ref":"#/components/schemas/InputProduct/$defs/InputMultiplier"},{"type":"null"}]},"repairability":{"anyOf":[{"$ref":"#/components/schemas/InputProduct/$defs/InputMultiplier"},{"type":"null"}]}}},"WashableTextileOverrides":{"description":"Mode-A overrides for `washable_textile`. All optional. Every key here is consumed by the archetype formula (use_stage/data-model.md §12.3); `air_dry_share` is the one parameter with no inventory term, because air drying carries no burden.","type":"object","additionalProperties":false,"required":["archetype"],"properties":{"archetype":{"const":"washable_textile"},"uses_before_washing":{"type":["number","null"],"exclusiveMinimum":0},"machine_wash_share":{"$ref":"#/components/schemas/InputProduct/$defs/NullableShare"},"hand_wash_share":{"$ref":"#/components/schemas/InputProduct/$defs/NullableShare"},"dry_clean_share":{"$ref":"#/components/schemas/InputProduct/$defs/NullableShare"},"tumble_dry_share":{"$ref":"#/components/schemas/InputProduct/$defs/NullableShare"},"air_dry_share":{"$ref":"#/components/schemas/InputProduct/$defs/NullableShare"},"ironing_share":{"$ref":"#/components/schemas/InputProduct/$defs/NullableShare"},"soap_per_wash":{"$ref":"#/components/schemas/InputProduct/$defs/NullableNonNegative"},"water_per_wash":{"$ref":"#/components/schemas/InputProduct/$defs/NullableNonNegative"},"elec_per_wash":{"$ref":"#/components/schemas/InputProduct/$defs/NullableNonNegative"},"soap_per_hand_wash":{"$ref":"#/components/schemas/InputProduct/$defs/NullableNonNegative"},"water_per_hand_wash":{"$ref":"#/components/schemas/InputProduct/$defs/NullableNonNegative"},"elec_per_hand_wash":{"$ref":"#/components/schemas/InputProduct/$defs/NullableNonNegative"},"service_per_dry_clean":{"$ref":"#/components/schemas/InputProduct/$defs/NullableNonNegative"},"elec_per_dry":{"$ref":"#/components/schemas/InputProduct/$defs/NullableNonNegative"},"elec_per_ironing":{"$ref":"#/components/schemas/InputProduct/$defs/NullableNonNegative"},"number_of_washes":{"$ref":"#/components/schemas/InputProduct/$defs/NullableNonNegative"},"number_of_machine_washes":{"$ref":"#/components/schemas/InputProduct/$defs/NullableNonNegative"},"number_of_hand_washes":{"$ref":"#/components/schemas/InputProduct/$defs/NullableNonNegative"},"number_of_dry_cleans":{"$ref":"#/components/schemas/InputProduct/$defs/NullableNonNegative"},"number_of_dries":{"$ref":"#/components/schemas/InputProduct/$defs/NullableNonNegative"},"number_of_ironings":{"$ref":"#/components/schemas/InputProduct/$defs/NullableNonNegative"}}},"PlugInCycleApplianceOverrides":{"type":"object","additionalProperties":false,"required":["archetype"],"properties":{"archetype":{"const":"plug_in_cycle_appliance"},"cycles_per_duration_unit":{"$ref":"#/components/schemas/InputProduct/$defs/NullableNonNegative"},"energy_per_cycle":{"$ref":"#/components/schemas/InputProduct/$defs/NullableNonNegative"},"number_of_cycles":{"$ref":"#/components/schemas/InputProduct/$defs/NullableNonNegative"}}},"NullableShare":{"description":"A share, or null. `null` means the parameter does not apply to this scope; `0` means it applies and is zero. The two are NOT interchangeable, and neither is ever renormalized.","anyOf":[{"$ref":"#/components/schemas/InputProduct/$defs/Share"},{"type":"null"}]},"NullableNonNegative":{"description":"A non-negative number, or null. `null` means not supplied and resolves from defaults; `0` means a declared zero and suppresses the activity.","anyOf":[{"$ref":"#/components/schemas/InputProduct/$defs/NonNegativeNumber"},{"type":"null"}]},"UseStageParamOverrides":{"description":"Discriminated on `archetype`. One member per UseStageArchetype; only the archetypes with an active reference model are listed here.","oneOf":[{"$ref":"#/components/schemas/InputProduct/$defs/WashableTextileOverrides"},{"$ref":"#/components/schemas/InputProduct/$defs/PlugInCycleApplianceOverrides"}]},"InputUseStageInventoryLine":{"type":"object","additionalProperties":false,"required":["input","amount","unit"],"properties":{"input":{"description":"Conceptual descriptor, never a Zeropact process ID. Customer scenarios go through the normal mapping path.","type":"string","minLength":1},"amount":{"$ref":"#/components/schemas/InputProduct/$defs/NonNegativeNumber"},"unit":{"type":"string","minLength":1},"process_hint":{"type":["string","null"]}}},"InputUseStageGeographyInventory":{"type":"object","additionalProperties":false,"required":["country","inventory_basis","inventories"],"properties":{"country":{"$ref":"#/components/schemas/InputProduct/$defs/CustomerCountry"},"inventory_basis":{"description":"LifecycleQuantityBasis on the wire: true use or product lifetime. specific_use is a calc reporting cut after the DoS factor and is rejected on input.","type":"string","enum":["use","product_lifetime"]},"inventories":{"type":"array","minItems":1,"items":{"$ref":"#/components/schemas/InputProduct/$defs/InputUseStageInventoryLine"}}}},"InputUseStage":{"description":"Modes A and B are mutually exclusive. Supplying both is a validation error, not a merge: mode B replaces the formula, so a parameter override against a formula that no longer runs would silently do nothing.","type":"object","additionalProperties":false,"properties":{"parameters":{"anyOf":[{"$ref":"#/components/schemas/InputProduct/$defs/UseStageParamOverrides"},{"type":"null"}]},"inventories":{"anyOf":[{"type":"array","minItems":1,"items":{"$ref":"#/components/schemas/InputProduct/$defs/InputUseStageGeographyInventory"}},{"type":"null"}]}},"not":{"description":"Rejects mode A and mode B supplied together.","required":["parameters","inventories"],"properties":{"parameters":{"type":"object"},"inventories":{"type":"array"}}}},"CustomerCountry":{"description":"Customer-supplied country descriptor (ISO code, English name, or curated alias). Ingest must resolve it to an ISO country via normalize_country_code / resolve_country_identity; unresolved values (including process scopes and regions) are validation errors. Regions may be accepted later once reference aggregations exist. Resolved geography identity is not part of the input contract.","type":"string","minLength":2},"InputMarket":{"description":"One customer-declared market country. Country-level only in v1 (no in-country location). No resolved identity and no source field — declaration provenance is assigned later by enrichment, same track as materials / manufacturing.","type":"object","additionalProperties":false,"required":["country","share"],"properties":{"country":{"$ref":"#/components/schemas/InputProduct/$defs/CustomerCountry"},"share":{"$ref":"#/components/schemas/InputProduct/$defs/Share"}}},"SystemBoundary":{"type":"string","enum":["cradle-to-gate","cradle-to-grave","cradle-to-cradle"]},"InputMarketReference":{"description":"Customer-supplied market identity reused by EoL treatment shares. It deliberately carries no market-mix share and no resolved geography ID. Country-level only in v1.","type":"object","additionalProperties":false,"required":["country"],"properties":{"country":{"$ref":"#/components/schemas/InputProduct/$defs/CustomerCountry"}}},"InputEoLTreatmentShare":{"type":"object","additionalProperties":false,"required":["market","waste_treatment_type","share"],"properties":{"market":{"$ref":"#/components/schemas/InputProduct/$defs/InputMarketReference"},"waste_treatment_type":{"$ref":"#/components/schemas/InputProduct/$defs/WasteTreatmentType"},"share":{"$ref":"#/components/schemas/InputProduct/$defs/Share"}}},"InputEndOfLife":{"description":"Customer-declared EoL treatment distribution. RECYCLING_MATERIAL is the product recycling share (R2); all other terminal treatment shares form the remaining distribution according to the EoL methodology.","type":"object","additionalProperties":false,"required":["treatment_shares"],"properties":{"treatment_shares":{"type":"array","minItems":1,"items":{"$ref":"#/components/schemas/InputProduct/$defs/InputEoLTreatmentShare"}}},"x-ingest-validation":{"phase":"after_market_mix_resolution","rules":["Shares grouped by market must sum to 1.0.","The (market, waste_treatment_type) pair must be unique.","When market_mix is supplied, EoL markets must exactly match its resolved markets.","Shares must be non-negative.","Only terminal WasteTreatmentType values are allowed.","RECYCLING_MATERIAL is the R2 share; no separate R2 field exists."]}},"PhysicalProperties":{"description":"Customer-declared physical properties. Units are free-form strings (same pattern as materials.unit), resolved to id+name refs on the output contract.","type":"object","additionalProperties":false,"properties":{"weight":{"type":["number","null"],"minimum":0},"weight_unit":{"type":["string","null"]},"volume":{"type":["number","null"],"minimum":0},"volume_unit":{"type":["string","null"]},"density":{"type":["number","null"],"minimum":0},"density_unit":{"type":["string","null"]}}},"InputMaterialLoose":{"description":"Customer material or packaging row (flexible profile). No required fields at line-item level.","type":"object","additionalProperties":false,"properties":{"name":{"type":["string","null"]},"description":{"type":["string","null"]},"unit":{"type":["string","null"]},"geography":{"type":["string","null"]},"geography_code":{"type":["string","null"]},"geography_name":{"type":["string","null"]},"amount":{"type":["number","null"],"minimum":0},"percentage":{"$ref":"#/components/schemas/InputProduct/$defs/NullableShare"},"supplier":{"type":["string","null"]},"manufacturer":{"type":["string","null"]},"organic":{"type":["boolean","null"]},"recycled":{"type":["boolean","null"]},"certification":{"type":["string","null"],"enum":[null,"sustainable forest management","conventional forest management","BCI"]}}},"InputMaterialStrict":{"description":"Material row (strict profile): name plus either (amount and unit) or (percentage with product physical_properties.weight).","allOf":[{"$ref":"#/components/schemas/InputProduct/$defs/InputMaterialLoose"},{"required":["name"],"properties":{"name":{"type":"string","minLength":1}},"oneOf":[{"required":["amount","unit"],"properties":{"amount":{"$ref":"#/components/schemas/InputProduct/$defs/NonNegativeNumber"},"unit":{"type":"string","minLength":1}}},{"required":["percentage"],"properties":{"percentage":{"$ref":"#/components/schemas/InputProduct/$defs/Share"}}}]}]},"InputPackagingStrict":{"description":"Packaging row (strict profile): name, amount, and unit are all required.","allOf":[{"$ref":"#/components/schemas/InputProduct/$defs/InputMaterialLoose"},{"required":["name","amount","unit"],"properties":{"name":{"type":"string","minLength":1},"amount":{"$ref":"#/components/schemas/InputProduct/$defs/NonNegativeNumber"},"unit":{"type":"string","minLength":1}}}]},"InputTransportLoose":{"description":"Customer transport row (flexible profile). No required fields at line-item level. Transport geography IS origin/destination, so geography_code/geography_name are deliberately absent; `geography` remains only as an optional mapping hint. Evidence is unit-ful: `weight`+`weight_unit` and `distance`+`distance_unit`, with kg/km defaults when the unit is omitted (a unit without its value is rejected). Canonical conversion of non-default units (lbs, mi, ...) lands with the transport-evidence unit-normalization rule on the field-rule execution lane (#566); until then a non-canonical unit is rejected by the strict profile and treated as unusable evidence by the flexible profile -- never silently misconverted.","type":"object","additionalProperties":false,"properties":{"name":{"type":["string","null"]},"description":{"type":["string","null"]},"unit":{"type":["string","null"]},"geography":{"type":["string","null"]},"amount":{"type":["number","null"],"minimum":0},"origin":{"type":["string","null"]},"destination":{"type":["string","null"]},"transport_mode":{"type":["string","null"],"enum":[null,"very_heavy_truck","heavy_truck","medium_truck","light_truck","biodiesel_truck","van_light","passenger_car_small","passenger_car_medium","passenger_car_large","passenger_car_electric","passenger_car_average","bus","trolleybus","tractor","aircraft_long_haul","aircraft_medium_haul","aircraft_short_haul","aircraft_very_short_haul","aircraft_unspecified","barge","barge_tanker","container_ship","ferry","tanker","train","pipeline"]},"transport_medium":{"type":["string","null"],"enum":[null,"road","air","inland_waterway","sea","rail","pipeline"]},"distance":{"type":["number","null"],"minimum":0},"distance_unit":{"type":["string","null"],"default":"km"},"weight":{"type":["number","null"],"minimum":0},"weight_unit":{"type":["string","null"],"default":"kg"}},"allOf":[{"if":{"properties":{"distance_unit":{"type":"string","minLength":1}},"required":["distance_unit"]},"then":{"required":["distance"],"properties":{"distance":{"$ref":"#/components/schemas/InputProduct/$defs/NonNegativeNumber"}}}},{"if":{"properties":{"weight_unit":{"type":"string","minLength":1}},"required":["weight_unit"]},"then":{"required":["weight"],"properties":{"weight":{"$ref":"#/components/schemas/InputProduct/$defs/NonNegativeNumber"}}}}]},"InputTransportStrict":{"description":"Transport row (strict profile): name (the matching key for candidate retrieval), origin, destination, distance, weight, and transport_mode or transport_medium. Units default to kg/km when omitted; a non-canonical unit (anything other than kg/km) is rejected until the transport-evidence unit-normalization rule lands (#566). When both mode and medium are supplied they must agree (mode -> medium derivation, enforced by the Pydantic profile; JSON Schema cannot express the mapping).","allOf":[{"$ref":"#/components/schemas/InputProduct/$defs/InputTransportLoose"},{"required":["name","origin","destination","distance","weight"],"properties":{"name":{"type":"string","minLength":1},"origin":{"type":"string","minLength":1},"destination":{"type":"string","minLength":1},"distance":{"$ref":"#/components/schemas/InputProduct/$defs/NonNegativeNumber"},"weight":{"$ref":"#/components/schemas/InputProduct/$defs/NonNegativeNumber"}}},{"anyOf":[{"required":["transport_mode"],"not":{"properties":{"transport_mode":{"const":null}}}},{"required":["transport_medium"],"not":{"properties":{"transport_medium":{"const":null}}}}]},{"if":{"properties":{"distance_unit":{"type":"string","minLength":1}},"required":["distance_unit"]},"then":{"properties":{"distance_unit":{"type":"string","pattern":"^[kK][mM]$"}}}},{"if":{"properties":{"weight_unit":{"type":"string","minLength":1}},"required":["weight_unit"]},"then":{"properties":{"weight_unit":{"type":"string","pattern":"^[kK][gG]$"}}}},{"if":{"properties":{"unit":{"type":"string","minLength":1}},"required":["unit"]},"then":{"required":["amount"],"properties":{"amount":{"$ref":"#/components/schemas/InputProduct/$defs/NonNegativeNumber"}}}}]},"InputManufacturingLoose":{"description":"Customer manufacturing row (flexible profile). No required fields at line-item level.","type":"object","additionalProperties":false,"properties":{"name":{"type":["string","null"]},"description":{"type":["string","null"]},"unit":{"type":["string","null"]},"geography":{"type":["string","null"]},"geography_code":{"type":["string","null"]},"geography_name":{"type":["string","null"]},"amount":{"type":["number","null"],"minimum":0}}},"InputManufacturingStrict":{"description":"Manufacturing row (strict profile): name, amount, and unit are all required.","allOf":[{"$ref":"#/components/schemas/InputProduct/$defs/InputManufacturingLoose"},{"required":["name","amount","unit"],"properties":{"name":{"type":"string","minLength":1},"amount":{"$ref":"#/components/schemas/InputProduct/$defs/NonNegativeNumber"},"unit":{"type":"string","minLength":1}}}]},"InputProductCoreProperties":{"type":"object","additionalProperties":false,"properties":{"sku":{"type":"string","minLength":1},"name":{"type":"string","minLength":1},"description":{"type":["string","null"]},"brand":{"type":["string","null"]},"customer_category":{"type":["string","null"]},"url":{"type":["string","null"]},"manufacturing_location":{"description":"Raw customer descriptor (code, name, or alias), resolved to OutputProduct.geography_id at ingest.","type":"string","minLength":1},"physical_properties":{"anyOf":[{"$ref":"#/components/schemas/InputProduct/$defs/PhysicalProperties"},{"type":"null"}]},"system_boundary":{"$ref":"#/components/schemas/InputProduct/$defs/SystemBoundary"},"functional_unit":{"type":"string","enum":["One unit of product","One kilogram of product"]},"circularity":{"anyOf":[{"$ref":"#/components/schemas/InputProduct/$defs/InputCircularity"},{"type":"null"}]},"use_stage":{"anyOf":[{"$ref":"#/components/schemas/InputProduct/$defs/InputUseStage"},{"type":"null"}]},"market_mix":{"description":"Customer-declared product market mix. Empty array is invalid when declared; omit/null means undeclared.","anyOf":[{"type":"array","minItems":1,"items":{"$ref":"#/components/schemas/InputProduct/$defs/InputMarket"}},{"type":"null"}]},"end_of_life":{"anyOf":[{"$ref":"#/components/schemas/InputProduct/$defs/InputEndOfLife"},{"type":"null"}]},"materials":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/InputProduct/$defs/InputMaterialLoose"}},{"type":"null"}]},"packaging":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/InputProduct/$defs/InputMaterialLoose"}},{"type":"null"}]},"transports":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/InputProduct/$defs/InputTransportLoose"}},{"type":"null"}]},"manufacturing":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/InputProduct/$defs/InputManufacturingLoose"}},{"type":"null"}]}}},"InputProductFlexible":{"description":"Flexible customer product input: requires sku, name, manufacturing_location, functional_unit, and system_boundary only. Lifecycle lists and all other fields may be omitted, null, or empty.","allOf":[{"$ref":"#/components/schemas/InputProduct/$defs/InputProductCoreProperties"},{"required":["sku","name","manufacturing_location","functional_unit","system_boundary"]}]},"InputProductStrict":{"description":"Strict customer product input: flexible requirements plus at least one row in each lifecycle list with line-item rules documented on the strict row defs.","allOf":[{"$ref":"#/components/schemas/InputProduct/$defs/InputProductFlexible"},{"required":["materials","packaging","transports","manufacturing"],"properties":{"materials":{"type":"array","minItems":1,"items":{"$ref":"#/components/schemas/InputProduct/$defs/InputMaterialStrict"}},"packaging":{"type":"array","minItems":1,"items":{"$ref":"#/components/schemas/InputProduct/$defs/InputPackagingStrict"}},"transports":{"type":"array","minItems":1,"items":{"$ref":"#/components/schemas/InputProduct/$defs/InputTransportStrict"}},"manufacturing":{"type":"array","minItems":1,"items":{"$ref":"#/components/schemas/InputProduct/$defs/InputManufacturingStrict"}}}},{"if":{"properties":{"materials":{"contains":{"required":["percentage"],"not":{"required":["amount"]}}}},"required":["materials"]},"then":{"required":["physical_properties"],"properties":{"physical_properties":{"type":"object","required":["weight"],"properties":{"weight":{"type":"number","exclusiveMinimum":0}}}}}}]},"InputMaterial":{"description":"Deprecated alias for InputMaterialLoose.","$ref":"#/components/schemas/InputProduct/$defs/InputMaterialLoose"},"InputTransport":{"description":"Deprecated alias for InputTransportLoose.","$ref":"#/components/schemas/InputProduct/$defs/InputTransportLoose"},"InputManufacturing":{"description":"Deprecated alias for InputManufacturingLoose.","$ref":"#/components/schemas/InputProduct/$defs/InputManufacturingLoose"},"InputProduct":{"description":"Deprecated alias for InputProductFlexible.","$ref":"#/components/schemas/InputProduct/$defs/InputProductFlexible"}}},"ProductOutput":{"$schema":"https://json-schema.org/draft/2020-12/schema","title":"Zeropact ProductOutput Contract","description":"Canonical output contract for one product's calculation run: product-level data (mirroring OutputProduct), the enriched per-lifecycle-type output classes (materials/packaging/transports/manufacturing/market_mix), the calc-ready inventory, calc results per inventory item and aggregated, and rule/mapping traceability. This is the target persisted/API shape, paired with product-input-flexible.schema.json / product-input-strict.schema.json (InputProduct in, ProductOutput out) -- not yet wired to the ingest worker or packages/compute. Two deliberate simplifications for this version: (1) lookup-table versioning (which revision of a Unit/Geography/ImpactIndicator/etc. was used) is intentionally omitted everywhere, pending a follow-up on how these tables are actually versioned at load time; every id here is a CURRENT id, not a point-in-time-pinned one. (2) issues/traces are typed (RuleIssue/RuleTrace, packages/shared/rules/contracts.py) but always empty for now -- nothing in the ingest path produces RuleOutput values yet; that is packages/rule#510's field-rule execution runner. Deliberately keeps every internal id (process id, inventory item id, impact indicator id, etc.) alongside its resolved name: this is the full traceability record, not a redacted customer-facing view.","$ref":"#/components/schemas/ProductOutput/$defs/ProductOutput","$defs":{"Uuid":{"type":"string","format":"uuid"},"LifecycleStage":{"description":"Wire spelling matches LifecycleStage.value (packages/shared/enum.py), e.g. 'Raw Materials'.","type":"string","enum":["Raw Materials","Packaging","Manufacturing","Transportation","Use Stage","End of Life"]},"CalculationGroupingStage":{"description":"LifecycleStage plus TOTAL (CalculationGroupingType, packages/shared/enum.py). Used for aggregated_results.stage, never for inventory line items.","type":"string","enum":["Raw Materials","Packaging","Manufacturing","Transportation","Use Stage","End of Life","Total"]},"AggregationBasis":{"description":"LifecycleQuantityBasis cut a ImpactAggregated row was computed under. USE is wire-inventory-only and never appears here.","type":"string","enum":["PRODUCT_LIFETIME","SPECIFIC_USE"]},"SystemBoundary":{"type":"string","enum":["cradle-to-gate","cradle-to-grave","cradle-to-cradle"]},"FunctionalUnit":{"type":"string","enum":["One unit of product","One kilogram of product"]},"TransportMode":{"type":["string","null"],"enum":[null,"very_heavy_truck","heavy_truck","medium_truck","light_truck","biodiesel_truck","van_light","passenger_car_small","passenger_car_medium","passenger_car_large","passenger_car_electric","passenger_car_average","bus","trolleybus","tractor","aircraft_long_haul","aircraft_medium_haul","aircraft_short_haul","aircraft_very_short_haul","aircraft_unspecified","barge","barge_tanker","container_ship","ferry","tanker","train","pipeline"]},"TransportMedium":{"description":"TransportMedium (packages/shared/enum.py): the broad carrier category behind a transport_mode (e.g. 'container_ship' -> 'sea').","type":["string","null"],"enum":[null,"road","air","inland_waterway","sea","rail","pipeline"]},"MaterialCertification":{"type":["string","null"],"enum":[null,"sustainable forest management","conventional forest management","BCI"]},"UnitRef":{"description":"A resolved unit of measure. `id` is desc_unit's row id; `name` is the resolved display string (e.g. 'kg'). No version -- see the top-level description.","type":"object","additionalProperties":false,"required":["id","name"],"properties":{"id":{"$ref":"#/components/schemas/ProductOutput/$defs/Uuid"},"name":{"type":"string"}}},"GeographyRef":{"description":"A resolved geography. Not nullable by itself -- use NullableGeographyRef where the underlying *_id column is optional (Product.manufacturing_location, InventoryItemRecord.geography, OutputTransportRecord.origin/destination). Everywhere else (ProcessRef, OutputMaterialRecord, OutputManufacturingRecord, OutputMarketMixRecord) the backing geography_id column is NOT NULL, so the bare $ref is required and non-null.","type":"object","additionalProperties":false,"required":["id","name","short_name"],"properties":{"id":{"$ref":"#/components/schemas/ProductOutput/$defs/Uuid"},"name":{"type":"string"},"short_name":{"type":"string"}}},"NullableGeographyRef":{"description":"GeographyRef or null, for optional *_id columns. The key must still be present on the wire object; use null when resolution failed or the input was absent.","anyOf":[{"$ref":"#/components/schemas/ProductOutput/$defs/GeographyRef"},{"type":"null"}]},"ProductCategoryRef":{"description":"Resolved desc_product_category row. Nullable: OutputProduct.category_id is optional.","anyOf":[{"type":"object","additionalProperties":false,"required":["id","name","description"],"properties":{"id":{"$ref":"#/components/schemas/ProductOutput/$defs/Uuid"},"name":{"type":"string"},"description":{"type":["string","null"]}}},{"type":"null"}]},"ImpactMethodRef":{"type":"object","additionalProperties":false,"required":["id","name"],"properties":{"id":{"$ref":"#/components/schemas/ProductOutput/$defs/Uuid"},"name":{"type":"string"}}},"ImpactCategoryRef":{"description":"Flat, not nested under method -- see ImpactIndicatorRef, which carries category and method as siblings rather than category.method.","type":"object","additionalProperties":false,"required":["id","name"],"properties":{"id":{"$ref":"#/components/schemas/ProductOutput/$defs/Uuid"},"name":{"type":"string"}}},"ImpactIndicatorRef":{"description":"e.g. {name: 'Climate change, biogenic', unit: 'kg CO2 eq', category: {name: 'Climate change'}, method: {name: 'EF 3.1'}}. `unit` here is ImpactIndicator.unit, an inline string column on the indicator itself, not a unit_id FK. `category` and `method` are flattened to one level each (both direct children of the indicator) rather than method nested inside category, since a consumer almost always wants both at once.","type":"object","additionalProperties":false,"required":["id","name","unit","category","method"],"properties":{"id":{"$ref":"#/components/schemas/ProductOutput/$defs/Uuid"},"name":{"type":"string"},"unit":{"type":"string"},"category":{"$ref":"#/components/schemas/ProductOutput/$defs/ImpactCategoryRef"},"method":{"$ref":"#/components/schemas/ProductOutput/$defs/ImpactMethodRef"}}},"BackgroundDataSourceRef":{"description":"Which background LCI database a process came from, e.g. {name: 'ecoinvent', version: '3.12', system_model: 'cutoff'} (data/models/descriptor.py BackgroundDataSource, joined via Process.source_id). `version` here is a real dataset-release string, unrelated to the per-row lookup-versioning question dropped elsewhere in this schema. Nullable: Process.source_id is optional.","anyOf":[{"type":"object","additionalProperties":false,"required":["id","name","version","system_model"],"properties":{"id":{"$ref":"#/components/schemas/ProductOutput/$defs/Uuid"},"name":{"type":"string"},"version":{"type":"string"},"system_model":{"type":"string"}}},{"type":"null"}]},"ProcessRef":{"description":"The background process/activity an input was mapped to. `beautified_name` is first: it is the intended display name, joined from ProcessClassificationProperties (one-to-one on process_id+process_version, via `assign_beautified_name` in packages/lcia/.../process_classifier.py) -- a LEFT join, since classification is not guaranteed to exist for every process, so it is nullable; it never includes geography, and keeps organic/recycled wording when present in the underlying ecoinvent name rather than stripping it. `id` is our internal LCIA_PROCESS row id. ecoinvent's own external identifiers (activity_id/reference_product_id) and the raw, unformatted activity_name/ref_product_name are deliberately NOT included -- beautified_name is the one display name this contract carries.","type":"object","additionalProperties":false,"required":["beautified_name","id","geography","unit","source"],"properties":{"beautified_name":{"type":["string","null"]},"id":{"$ref":"#/components/schemas/ProductOutput/$defs/Uuid"},"geography":{"$ref":"#/components/schemas/ProductOutput/$defs/GeographyRef"},"unit":{"$ref":"#/components/schemas/ProductOutput/$defs/UnitRef"},"source":{"$ref":"#/components/schemas/ProductOutput/$defs/BackgroundDataSourceRef"}}},"MaterialProcessRef":{"description":"ProcessRef plus the material-specific attributes of THIS mapping (organic/recycled/certification live on OutputMaterial/OutputPackagingMaterial, not on the background process itself -- ecoinvent's process has no notion of 'this customer's cotton was organic'). Used by materials/packaging; transports and manufacturing use the base ProcessRef.","type":"object","additionalProperties":false,"required":["beautified_name","id","geography","unit","source","organic","recycled","certification"],"properties":{"beautified_name":{"type":["string","null"]},"id":{"$ref":"#/components/schemas/ProductOutput/$defs/Uuid"},"geography":{"$ref":"#/components/schemas/ProductOutput/$defs/GeographyRef"},"unit":{"$ref":"#/components/schemas/ProductOutput/$defs/UnitRef"},"source":{"$ref":"#/components/schemas/ProductOutput/$defs/BackgroundDataSourceRef"},"organic":{"type":["boolean","null"]},"recycled":{"type":["boolean","null"]},"certification":{"$ref":"#/components/schemas/ProductOutput/$defs/MaterialCertification"}}},"PhysicalProperties":{"description":"OutputProduct.physical_properties, a passthrough JSON blob (data/models/lci.py). Units are resolved refs here (id + name), unlike the input contract's bare unit strings -- this is a read-time resolution, not a modeled relationship, so it depends on whatever built this document actually doing the join.","anyOf":[{"type":"object","additionalProperties":false,"properties":{"weight":{"type":["number","null"],"minimum":0},"weight_unit":{"anyOf":[{"$ref":"#/components/schemas/ProductOutput/$defs/UnitRef"},{"type":"null"}]},"volume":{"type":["number","null"],"minimum":0},"volume_unit":{"anyOf":[{"$ref":"#/components/schemas/ProductOutput/$defs/UnitRef"},{"type":"null"}]},"density":{"type":["number","null"],"minimum":0},"density_unit":{"anyOf":[{"$ref":"#/components/schemas/ProductOutput/$defs/UnitRef"},{"type":"null"}]}}},{"type":"null"}]},"OutputMaterialRecord":{"description":"One row per OutputMaterial or OutputPackagingMaterial (LCI_OUTPUT_MATERIAL / LCI_OUTPUT_PACKAGING_MATERIAL) -- the same shape either way; which top-level array (materials vs packaging) a record is in is what distinguishes them, since neither table carries a lifecycle_stage column itself. `technical_name` is reserved for a normalized/technical form of `name`; not populated by any mapping/enrichment code yet.","type":"object","additionalProperties":false,"required":["id","name","technical_name","amount","unit","geography","mapped_process"],"properties":{"id":{"$ref":"#/components/schemas/ProductOutput/$defs/Uuid"},"name":{"type":"string"},"technical_name":{"type":["string","null"]},"amount":{"type":["number","null"]},"unit":{"$ref":"#/components/schemas/ProductOutput/$defs/UnitRef"},"geography":{"$ref":"#/components/schemas/ProductOutput/$defs/GeographyRef"},"mapped_process":{"$ref":"#/components/schemas/ProductOutput/$defs/MaterialProcessRef"}}},"OutputTransportRecord":{"description":"One row per OutputTransport (LCI_OUTPUT_TRANSPORT). `origin`/`destination` are best-effort resolutions of the customer's real-world locations (OutputTransport.origin_id/destination_id) and are independent of `mapped_process.geography`, which is the matched background process's own operating geography (e.g. 'GLO' for a generic freight process) -- the three need not agree. `distance_km`/`weight_kg` are the customer-declared route evidence behind the amount synthesis (weight_kg x distance_km / 1000 when the customer did not supply an explicit activity amount); null means not declared.","type":"object","additionalProperties":false,"required":["id","name","description","amount","unit","origin","destination","transport_mode","transport_medium","distance_km","weight_kg","mapped_process"],"properties":{"id":{"$ref":"#/components/schemas/ProductOutput/$defs/Uuid"},"name":{"type":"string"},"description":{"type":["string","null"]},"amount":{"type":["number","null"]},"unit":{"$ref":"#/components/schemas/ProductOutput/$defs/UnitRef"},"origin":{"$ref":"#/components/schemas/ProductOutput/$defs/NullableGeographyRef"},"destination":{"$ref":"#/components/schemas/ProductOutput/$defs/NullableGeographyRef"},"transport_mode":{"$ref":"#/components/schemas/ProductOutput/$defs/TransportMode"},"transport_medium":{"$ref":"#/components/schemas/ProductOutput/$defs/TransportMedium"},"distance_km":{"type":["number","null"],"minimum":0},"weight_kg":{"type":["number","null"],"minimum":0},"mapped_process":{"$ref":"#/components/schemas/ProductOutput/$defs/ProcessRef"}}},"OutputManufacturingRecord":{"description":"One row per OutputManufacturing (LCI_OUTPUT_MANUFACTURING).","type":"object","additionalProperties":false,"required":["id","name","description","amount","unit","geography","mapped_process"],"properties":{"id":{"$ref":"#/components/schemas/ProductOutput/$defs/Uuid"},"name":{"type":"string"},"description":{"type":["string","null"]},"amount":{"type":["number","null"]},"unit":{"$ref":"#/components/schemas/ProductOutput/$defs/UnitRef"},"geography":{"$ref":"#/components/schemas/ProductOutput/$defs/GeographyRef"},"mapped_process":{"$ref":"#/components/schemas/ProductOutput/$defs/ProcessRef"}}},"OutputMarketMixRecord":{"description":"One row per OutputMarketMix (LCI_OUTPUT_MARKET_MIX): one resolved market country and its share.","type":"object","additionalProperties":false,"required":["id","country","share","geography"],"properties":{"id":{"$ref":"#/components/schemas/ProductOutput/$defs/Uuid"},"country":{"description":"Canonical ISO country code after resolution; 'GLO' is the reserved generated fallback.","type":"string"},"share":{"type":"number","minimum":0,"maximum":1},"geography":{"$ref":"#/components/schemas/ProductOutput/$defs/GeographyRef"}}},"InventoryItemRecord":{"description":"One row per InventoryItem (LCI_INVENTORY_ITEM), joined out to its unit, geography, and matched process -- the calc-ready form, one entry per physical input line, amounts only, no calculated impact. `name` is the customer's original input string (InventoryItem.name), never the matched process's name.","type":"object","additionalProperties":false,"required":["inventory_item_id","inventory_id","name","lifecycle_stage","amount","unit","geography","converted_amount","converted_unit","mapped_process"],"properties":{"inventory_item_id":{"$ref":"#/components/schemas/ProductOutput/$defs/Uuid"},"inventory_id":{"$ref":"#/components/schemas/ProductOutput/$defs/Uuid"},"name":{"type":"string"},"lifecycle_stage":{"$ref":"#/components/schemas/ProductOutput/$defs/LifecycleStage"},"amount":{"type":"number"},"unit":{"$ref":"#/components/schemas/ProductOutput/$defs/UnitRef"},"geography":{"$ref":"#/components/schemas/ProductOutput/$defs/NullableGeographyRef"},"converted_amount":{"type":["number","null"]},"converted_unit":{"anyOf":[{"$ref":"#/components/schemas/ProductOutput/$defs/UnitRef"},{"type":"null"}]},"mapped_process":{"$ref":"#/components/schemas/ProductOutput/$defs/ProcessRef"}}},"InventoryItemBriefRef":{"description":"The originating inventory item, denormalized onto each ImpactByInventoryItemRecord so a consumer reading impacts_by_inventory_item alone (without cross-referencing `inventory`) still knows what the impact is for. `description` is the customer's free-text line description when the builder has it (from the matched output row); null when absent.","type":"object","additionalProperties":false,"required":["inventory_item_id","name","description","unit"],"properties":{"inventory_item_id":{"description":"References InventoryItemRecord.inventory_item_id in this same ProductOutput.","$ref":"#/components/schemas/ProductOutput/$defs/Uuid"},"name":{"type":"string"},"description":{"type":["string","null"]},"unit":{"$ref":"#/components/schemas/ProductOutput/$defs/UnitRef"}}},"ImpactByInventoryItemRecord":{"description":"One row per (inventory item x impact indicator), mirroring ImpactByInventoryItem (CALC_IMPACT_BY_INVENTORY_ITEM) but joined out to the indicator's full name/category/method and the originating item/process, rather than bare ids.","type":"object","additionalProperties":false,"required":["inventory_item","mapped_process","impact_indicator","amount"],"properties":{"inventory_item":{"$ref":"#/components/schemas/ProductOutput/$defs/InventoryItemBriefRef"},"mapped_process":{"$ref":"#/components/schemas/ProductOutput/$defs/ProcessRef"},"impact_indicator":{"$ref":"#/components/schemas/ProductOutput/$defs/ImpactIndicatorRef"},"amount":{"type":"number"}}},"AggregatedResultRecord":{"description":"One row per (lifecycle stage x impact indicator), plus a TOTAL row per indicator, mirroring ImpactAggregated (CALC_IMPACT_AGGREGATED). Packaging inputs contribute to their own 'Packaging' stage rows here, same as any other stage.","type":"object","additionalProperties":false,"required":["stage","aggregation_basis","impact_indicator","amount"],"properties":{"stage":{"$ref":"#/components/schemas/ProductOutput/$defs/CalculationGroupingStage"},"aggregation_basis":{"$ref":"#/components/schemas/ProductOutput/$defs/AggregationBasis"},"impact_indicator":{"$ref":"#/components/schemas/ProductOutput/$defs/ImpactIndicatorRef"},"amount":{"type":"number"}}},"RuleIssueSeverity":{"type":"string","enum":["error","warning","info"]},"RuleIssue":{"description":"Mirrors zeropact_shared.diagnostics.RuleIssue verbatim. An expected data or policy problem, not an exception.","type":"object","additionalProperties":false,"required":["code","severity","message","entity_path","field"],"properties":{"code":{"type":"string","minLength":1},"severity":{"$ref":"#/components/schemas/ProductOutput/$defs/RuleIssueSeverity"},"message":{"type":"string","minLength":1},"entity_path":{"type":["string","null"],"maxLength":256},"field":{"type":["string","null"],"maxLength":128}}},"RuleStage":{"type":"string","enum":["conversion","input_validation","resolution","candidate_generation","support_assessment","mapping","persistence","calculation","artifact"]},"RuleTraceSource":{"type":"string","enum":["customer_input","deterministic_rule","governed_source","model_candidate","system"]},"RuleTraceJsonAtom":{"anyOf":[{"type":"null"},{"type":"boolean"},{"type":"integer"},{"type":"number"},{"type":"string","maxLength":1024}]},"RuleTraceValue":{"anyOf":[{"$ref":"#/components/schemas/ProductOutput/$defs/RuleTraceJsonAtom"},{"type":"array","maxItems":32,"items":{"$ref":"#/components/schemas/ProductOutput/$defs/RuleTraceJsonAtom"}}]},"RuleTrace":{"description":"Mirrors zeropact_shared.diagnostics.RuleTrace verbatim. `entity_path` is a string path (e.g. 'materials[2].name'), deliberately not a DB id. `details` is the rule-owned diagnostic bag (cosine similarity, second-best candidate, ...): each rule defines its own keys, consumers must not rely on keys across rules; bounded to atoms-or-one-nesting values and ~2KB serialized.","type":"object","additionalProperties":false,"required":["rule_id","stage","entity_path","source","field","before","after","metadata"],"properties":{"rule_id":{"type":"string","minLength":1},"stage":{"$ref":"#/components/schemas/ProductOutput/$defs/RuleStage"},"entity_path":{"type":"string","minLength":1,"maxLength":256},"source":{"$ref":"#/components/schemas/ProductOutput/$defs/RuleTraceSource"},"field":{"type":["string","null"],"maxLength":128},"before":{"$ref":"#/components/schemas/ProductOutput/$defs/RuleTraceValue"},"after":{"$ref":"#/components/schemas/ProductOutput/$defs/RuleTraceValue"},"metadata":{"type":"object","propertyNames":{"enum":["method_id","method_version","validator_id","validator_version","legacy_validation_code","reason_code","unit_id","source_locator_id","mapping_decision_id"]},"additionalProperties":{"$ref":"#/components/schemas/ProductOutput/$defs/RuleTraceJsonAtom"}},"details":{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":64},"additionalProperties":{"anyOf":[{"$ref":"#/components/schemas/ProductOutput/$defs/RuleTraceValue"},{"type":"object","propertyNames":{"type":"string","minLength":1,"maxLength":64},"additionalProperties":{"$ref":"#/components/schemas/ProductOutput/$defs/RuleTraceJsonAtom"},"maxProperties":32}]}}}},"Product":{"description":"Product-level data, mirroring OutputProduct (data/models/lci.py) minus its list relationships (materials/packaging/transports/manufacturing/market_mix/aggregated_results/inventory_items/impacts_by_inventory_item), which are their own top-level ProductOutput arrays instead of being nested here. sku is today's sole customer-declared identity (BaseProductCore.sku); there is no persisted product-variant concept yet -- BaseProductCore carries a literal '# TODO Add productVariant class'. `manufacturing_location` is the resolved form of InputProduct.manufacturing_location (OutputProduct.geography_id joined out to a GeographyRef), not a market/sales geography -- that is what `market_mix` is for.","type":"object","additionalProperties":false,"required":["product_id","product_version","tenant_id","run_id","sku","name","description","brand","customer_category","url","category","manufacturing_location","is_active","physical_properties","system_boundary","functional_unit"],"properties":{"product_id":{"$ref":"#/components/schemas/ProductOutput/$defs/Uuid"},"product_version":{"description":"OutputProduct's own composite-PK version. Kept as a literal timestamp here (unlike the lookup-table versions dropped elsewhere): it is OUR row identity, already load-bearing throughout the codebase (fk_composite_product), not the deferred lookup-versioning question.","type":"string","format":"date-time"},"tenant_id":{"$ref":"#/components/schemas/ProductOutput/$defs/Uuid"},"run_id":{"anyOf":[{"$ref":"#/components/schemas/ProductOutput/$defs/Uuid"},{"type":"null"}]},"sku":{"type":"string","minLength":1},"name":{"type":"string","minLength":1},"description":{"type":["string","null"]},"brand":{"type":["string","null"]},"customer_category":{"type":["string","null"]},"url":{"type":["string","null"]},"category":{"$ref":"#/components/schemas/ProductOutput/$defs/ProductCategoryRef"},"manufacturing_location":{"$ref":"#/components/schemas/ProductOutput/$defs/NullableGeographyRef"},"is_active":{"type":"boolean"},"physical_properties":{"$ref":"#/components/schemas/ProductOutput/$defs/PhysicalProperties"},"system_boundary":{"anyOf":[{"$ref":"#/components/schemas/ProductOutput/$defs/SystemBoundary"},{"type":"null"}]},"functional_unit":{"anyOf":[{"$ref":"#/components/schemas/ProductOutput/$defs/FunctionalUnit"},{"type":"null"}]}}},"ProductOutput":{"type":"object","additionalProperties":false,"required":["product","materials","packaging","transports","manufacturing","market_mix","inventory","impacts_by_inventory_item","aggregated_results","issues","traces"],"properties":{"product":{"$ref":"#/components/schemas/ProductOutput/$defs/Product"},"materials":{"type":"array","items":{"$ref":"#/components/schemas/ProductOutput/$defs/OutputMaterialRecord"}},"packaging":{"description":"Same record shape as materials (OutputMaterialRecord) -- LCI_OUTPUT_PACKAGING_MATERIAL is a separate table from LCI_OUTPUT_MATERIAL, distinguished by which array a record is in, not by a field on the record itself.","type":"array","items":{"$ref":"#/components/schemas/ProductOutput/$defs/OutputMaterialRecord"}},"transports":{"type":"array","items":{"$ref":"#/components/schemas/ProductOutput/$defs/OutputTransportRecord"}},"manufacturing":{"type":"array","items":{"$ref":"#/components/schemas/ProductOutput/$defs/OutputManufacturingRecord"}},"market_mix":{"type":"array","items":{"$ref":"#/components/schemas/ProductOutput/$defs/OutputMarketMixRecord"}},"inventory":{"type":"array","items":{"$ref":"#/components/schemas/ProductOutput/$defs/InventoryItemRecord"}},"impacts_by_inventory_item":{"type":"array","items":{"$ref":"#/components/schemas/ProductOutput/$defs/ImpactByInventoryItemRecord"}},"aggregated_results":{"type":"array","items":{"$ref":"#/components/schemas/ProductOutput/$defs/AggregatedResultRecord"}},"issues":{"type":"array","items":{"$ref":"#/components/schemas/ProductOutput/$defs/RuleIssue"}},"traces":{"type":"array","items":{"$ref":"#/components/schemas/ProductOutput/$defs/RuleTrace"}}}}}},"BatchRequest":{"type":"object","additionalProperties":false,"required":["items"],"properties":{"items":{"type":"array","minItems":1,"maxItems":100,"items":{"$ref":"#/components/schemas/InputProduct/$defs/InputProductFlexible"}}}},"BatchItemResult":{"oneOf":[{"type":"object","additionalProperties":false,"required":["index","status","output"],"properties":{"index":{"type":"integer","minimum":0},"status":{"const":200},"output":{"$ref":"#/components/schemas/ProductOutput"}}},{"type":"object","additionalProperties":false,"required":["index","status","error"],"properties":{"index":{"type":"integer","minimum":0},"status":{"type":"integer","enum":[400,413,429,502,503,504]},"error":{"oneOf":[{"type":"string"},{"type":"object"}]},"retry_after":{"type":"integer","minimum":0}}}]},"BatchResponse":{"type":"object","additionalProperties":false,"required":["batch_id","expires_at","results","total","succeeded","failed","pagination"],"properties":{"results":{"type":"array","items":{"$ref":"#/components/schemas/BatchItemResult"}},"batch_id":{"type":"string","format":"uuid"},"expires_at":{"type":"string","format":"date-time"},"pagination":{"type":"object","additionalProperties":false,"required":["page","page_size","total_pages","next_page","next_url"],"properties":{"page":{"type":"integer","minimum":1},"page_size":{"type":"integer","minimum":1,"maximum":100},"total_pages":{"type":"integer","minimum":1},"next_page":{"type":["integer","null"],"minimum":1},"next_url":{"type":["string","null"]}}},"total":{"type":"integer"},"succeeded":{"type":"integer"},"failed":{"type":"integer"}}}},"securitySchemes":{"APIKeyHeader":{"type":"apiKey","in":"header","name":"X-API-Key"}}}}