{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://www.freightutils.com/schema/consignment.v1.json",
  "title": "FreightUtils Consignment v1",
  "description": "Canonical request/response contract for the FreightUtils consignment calculator (POST /api/consignment and the consignment_calculator MCP tool). Deterministic freight metrics only (CBM, loading metres, volumetric and mode-specific chargeable weight) plus advisory objective flags. Reference data and arithmetic — not regulatory, customs, or dangerous-goods compliance advice.",
  "type": "object",
  "properties": {
    "mode": {
      "type": "string",
      "enum": ["sea", "air", "road"],
      "default": "road",
      "description": "Transport mode; selects the chargeable-weight basis (sea: weight-or-measure; air: volumetric; road: loading metres)."
    },
    "lines": {
      "type": "array",
      "minItems": 1,
      "maxItems": 50,
      "description": "Canonical consignment lines (preferred).",
      "items": { "$ref": "#/$defs/LineItem" }
    },
    "items": {
      "type": "array",
      "minItems": 1,
      "maxItems": 50,
      "description": "Deprecated backward-compatible alias: flat items with dimensions in cm and weight in kg. Prefer `lines`.",
      "items": { "$ref": "#/$defs/LegacyItem" }
    },
    "options": { "$ref": "#/$defs/Options" }
  },
  "anyOf": [
    { "required": ["lines"] },
    { "required": ["items"] }
  ],
  "additionalProperties": false,
  "$defs": {
    "LengthUnit": { "type": "string", "enum": ["mm", "cm", "m", "in"] },
    "WeightUnit": { "type": "string", "enum": ["kg", "g", "t", "lb"] },
    "LineItem": {
      "type": "object",
      "required": ["quantity", "dims", "weight"],
      "additionalProperties": false,
      "properties": {
        "description": { "type": "string", "maxLength": 200 },
        "quantity": { "type": "integer", "minimum": 1, "maximum": 100000 },
        "dims": {
          "type": "object",
          "required": ["l", "w", "h", "unit"],
          "additionalProperties": false,
          "properties": {
            "l": { "type": "number", "exclusiveMinimum": 0 },
            "w": { "type": "number", "exclusiveMinimum": 0 },
            "h": { "type": "number", "exclusiveMinimum": 0 },
            "unit": { "$ref": "#/$defs/LengthUnit" }
          }
        },
        "weight": {
          "type": "object",
          "required": ["value", "unit"],
          "additionalProperties": false,
          "properties": {
            "value": { "type": "number", "exclusiveMinimum": 0 },
            "unit": { "$ref": "#/$defs/WeightUnit" }
          }
        },
        "hs_code": { "type": "string", "pattern": "^\\d{6,10}$" },
        "un_number": { "type": "string", "pattern": "^(UN)?\\d{4}$" },
        "stackable": { "type": "boolean" }
      }
    },
    "LegacyItem": {
      "type": "object",
      "required": ["length", "width", "height"],
      "description": "Legacy flat item. Dimensions cm, weight kg. Field aliases accepted by the endpoint (length/length_cm/l, gross_weight/weight, quantity/qty) but the canonical names are shown here.",
      "properties": {
        "description": { "type": "string" },
        "length": { "type": "number", "exclusiveMinimum": 0 },
        "width": { "type": "number", "exclusiveMinimum": 0 },
        "height": { "type": "number", "exclusiveMinimum": 0 },
        "quantity": { "type": "integer", "minimum": 1 },
        "gross_weight": { "type": "number", "exclusiveMinimum": 0 },
        "stackable": { "type": "boolean" },
        "pallet_type": { "type": "string", "enum": ["none", "euro", "uk", "us", "custom"] },
        "un_number": { "type": "string" },
        "hs_code": { "type": "string" }
      }
    },
    "Options": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "air_volumetric_divisor": { "type": "number", "exclusiveMinimum": 0, "maximum": 10000, "default": 6000, "description": "IATA volumetric divisor (cm³/kg). Only affects air." },
        "container_number": { "type": "string", "maxLength": 20, "description": "ISO 6346 container number; check-digit validated, advisory only." },
        "awb_number": { "type": "string", "maxLength": 20, "description": "IATA 11-digit air waybill; check-digit validated, advisory only." }
      }
    },
    "Flag": {
      "type": "object",
      "required": ["level", "code", "message"],
      "additionalProperties": false,
      "description": "Advisory objective observation. Never a verdict (never states permitted/compliant/prohibited).",
      "properties": {
        "level": { "type": "string", "enum": ["warning", "info"] },
        "code": { "type": "string" },
        "message": { "type": "string" }
      }
    },
    "PerLineResult": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "description": { "type": "string" },
        "quantity": { "type": "integer" },
        "cbm": { "type": "number" },
        "gross_weight_kg": { "type": "number" },
        "density_kg_per_m3": { "type": "number" },
        "volumetric_weight_kg": { "type": "number" },
        "ldm": { "type": "number" },
        "revenue_tonnes": { "type": "number" },
        "chargeable_weight_kg": { "type": "number" }
      }
    },
    "ConsignmentResult": {
      "type": "object",
      "required": ["schema_version", "mode", "per_line", "totals", "flags", "disclaimer"],
      "additionalProperties": false,
      "description": "Response shape returned by POST /api/consignment and the consignment_calculator MCP tool.",
      "properties": {
        "schema_version": { "type": "string", "const": "consignment.v1" },
        "mode": { "type": "string", "enum": ["sea", "air", "road"] },
        "air_volumetric_divisor": { "type": "number" },
        "disclaimer": { "type": "string" },
        "per_line": { "type": "array", "items": { "$ref": "#/$defs/PerLineResult" } },
        "totals": {
          "type": "object",
          "additionalProperties": false,
          "properties": {
            "cbm": { "type": "number" },
            "gross_weight_kg": { "type": "number" },
            "ldm": { "type": "number" },
            "volumetric_weight_kg": { "type": "number" },
            "revenue_tonnes": { "type": "number" },
            "chargeable_weight_kg": { "type": "number" },
            "line_count": { "type": "integer" },
            "piece_count": { "type": "integer" },
            "billing_basis": { "type": "string", "enum": ["weight", "volume"] }
          }
        },
        "flags": { "type": "array", "items": { "$ref": "#/$defs/Flag" } }
      }
    }
  }
}
