{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/carbonara-co2-org/json-schema/carbonara-co2-org-shipment-schema.json",
  "title": "Shipment",
  "description": "Give weight_kg, or teu with teu_net_tonnes or container_load; teu alone uses the dataset's \"average\" profile (GLEC, 10 t per TEU).",
  "x-generated": "2026-11-03",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/carbonara-co2-org-openapi.yaml#/components/schemas/Shipment",
  "type": "object",
  "required": [
    "legs"
  ],
  "properties": {
    "id": {
      "type": "string"
    },
    "weight_kg": {
      "type": "number",
      "exclusiveMinimum": 0
    },
    "teu": {
      "type": "number",
      "exclusiveMinimum": 0
    },
    "teu_net_tonnes": {
      "type": "number",
      "description": "Net cargo tonnes per TEU"
    },
    "container_load": {
      "type": "string",
      "description": "Profile name from the dataset's container_loads"
    },
    "cargo_type": {
      "type": "string",
      "description": "Optional GLEC cargo or load category from the dataset's cargo_types (container, temperature_controlled, light, heavy, European rail commodities); picks GLEC's value for it where the leg's vehicle has one"
    },
    "legs": {
      "type": "array",
      "minItems": 1,
      "items": {
        "$ref": "#/$defs/Leg"
      }
    },
    "hubs": {
      "type": "array",
      "items": {
        "$ref": "#/$defs/HubStop"
      }
    },
    "add_road_legs": {
      "type": "boolean",
      "default": true,
      "description": "Add road legs where the trip doesn't join up: across a gap of more than 5 km between one leg's end and the next leg's start, and to or from a port or rail terminal when a sea, rail or inland waterway leg starts or ends off its network (the leg is moved there). Added and moved legs are marked in the result. When false, gaps and inland sea ends are only warnings.\n"
    }
  },
  "$defs": {
    "DistanceType": {
      "type": "string",
      "enum": [
        "sfd",
        "gcd",
        "actual"
      ],
      "description": "Shortest feasible, great-circle, or actually travelled distance (GLEC / ISO 14083)"
    },
    "FuelUse": {
      "type": "object",
      "required": [
        "fuel",
        "amount"
      ],
      "properties": {
        "fuel": {
          "type": "string"
        },
        "amount": {
          "type": "number",
          "description": "In the fuel factor's unit"
        },
        "vehicle_tonne_km": {
          "type": "number",
          "description": "Total tonne-km on the vehicle trip, for allocation. 0 or absent = whole trip."
        },
        "factor": {
          "type": "object",
          "description": "The fuel supplier's or your own emission factor, used instead of the dataset's (fuel is then just its name).",
          "required": [
            "unit",
            "wtw_kg_per_unit",
            "source"
          ],
          "properties": {
            "unit": {
              "type": "string"
            },
            "wtw_kg_per_unit": {
              "type": "number",
              "exclusiveMinimum": 0,
              "description": "Well-to-wheel kg CO2e per unit"
            },
            "ttw_kg_per_unit": {
              "type": "number",
              "minimum": 0,
              "description": "Tank-to-wheel kg CO2e per unit",
              "part of WTW": null
            },
            "source": {
              "type": "string",
              "description": "Who gives the factor",
              "and for what": null
            },
            "biogenic_co2_kg_per_unit": {
              "type": "number",
              "minimum": 0,
              "description": "Reported apart",
              "not in WTW": null
            }
          }
        }
      }
    },
    "HubStop": {
      "type": "object",
      "required": [
        "hub_type"
      ],
      "properties": {
        "id": {
          "type": "string"
        },
        "hub_type": {
          "type": "string",
          "description": "GLEC v3.3 Table 3 hub types: transshipment, storage_transshipment, warehouse, liquid_bulk_terminal (add _mixed for ambient and temperature-controlled sites; per tonne), intermodal_terminal, intermodal_terminal_temperature_controlled (per container)"
        },
        "containers": {
          "type": "number",
          "description": "Containers handled, for per-container hub types (intermodal terminals)"
        }
      }
    },
    "Leg": {
      "type": "object",
      "required": [
        "mode"
      ],
      "properties": {
        "id": {
          "type": "string"
        },
        "mode": {
          "$ref": "#/$defs/Mode"
        },
        "cargo_type": {
          "type": "string",
          "description": "Overrides the shipment's cargo_type for this leg"
        },
        "vehicle_type": {
          "type": "string",
          "description": "Must exist in the loaded dataset; list them with GET /v1/factors"
        },
        "from": {
          "$ref": "#/$defs/Location"
        },
        "to": {
          "$ref": "#/$defs/Location"
        },
        "distance_km": {
          "type": "number",
          "description": "Overrides computed distance when > 0"
        },
        "distance_type": {
          "$ref": "#/$defs/DistanceType"
        },
        "fuel": {
          "$ref": "#/$defs/FuelUse"
        },
        "load_factor": {
          "type": "number",
          "exclusiveMinimum": 0,
          "maximum": 1,
          "description": "Load as a share of the load model's payload (DESNZ's average full load, e.g. 17.9 t for an artic over 33 t), not of the truck's rated payload; switches the leg to the dataset's load model. Give this or load_tonnes. In GLEC and EcoTransIT a load factor is a share of the rated payload, so the same value means more tonnes there: to compare, or when the weight is known, give load_tonnes.\n"
        },
        "load_tonnes": {
          "type": "number",
          "exclusiveMinimum": 0,
          "description": "Tonnes on the truck (all cargo, average over the loaded km); switches the leg to the load model. Up to 1.6 × the model's payload: above its payload the model is extended linearly.\n"
        },
        "empty_trip_factor": {
          "type": "number",
          "minimum": 0,
          "description": "Empty km per loaded km (needs load_factor or load_tonnes)"
        },
        "repositioning_km": {
          "type": "number",
          "minimum": 0,
          "description": "Trucks: km driven empty for this trip (to the pickup, or back after delivery), shared over the truck's load like empty running (added to the empty trip factor as km per actual loaded km). Without a load, the shipment is taken as the truck's whole load.\n"
        },
        "energy_kwh_per_tkm": {
          "type": "number",
          "exclusiveMinimum": 0,
          "description": "Electricity per tonne-km; with country, switches the leg to the energy method"
        },
        "country": {
          "type": "string",
          "description": "ISO 3166-1 alpha-3 country whose grid powers the leg, e.g. DNK"
        },
        "own_factor": {
          "$ref": "#/$defs/OwnFactor"
        }
      }
    },
    "Location": {
      "type": "object",
      "description": "Coordinates, or a code instead of them.",
      "properties": {
        "name": {
          "type": "string"
        },
        "code": {
          "type": "string",
          "description": "UN/LOCODE (NLRTM) or IATA airport code (CPH), used when lat and lon are not given. Find codes with GET /v1/places."
        },
        "lat": {
          "type": "number"
        },
        "lon": {
          "type": "number"
        }
      }
    },
    "Mode": {
      "type": "string",
      "enum": [
        "road",
        "rail",
        "sea",
        "air",
        "inland_waterway"
      ]
    },
    "OwnFactor": {
      "type": "object",
      "description": "The carrier's or your own intensity for a leg (primary data, ISO 14083 7.2.3), used instead of a default value.",
      "required": [
        "wtw_g_per_tkm",
        "source"
      ],
      "properties": {
        "wtw_g_per_tkm": {
          "type": "number",
          "exclusiveMinimum": 0
        },
        "ttw_g_per_tkm": {
          "type": "number",
          "minimum": 0,
          "description": "Part of WTW; the rest is WTT"
        },
        "source": {
          "type": "string",
          "description": "Who measured it",
          "and for what (e.g. the carrier's TOC report and year)": null
        },
        "distance_basis": {
          "type": "string",
          "enum": [
            "sfd",
            "gcd",
            "actual"
          ],
          "description": "Distance type the intensity is per tonne-km of. Absent = the leg's own distance type, so no DAF."
        }
      }
    }
  }
}