{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/thinair-co/json-schema/thinair-co-directions-request-schema.json",
  "title": "DirectionsRequest",
  "description": "Routing request — origin + destination (free text or coordinate pair), optional waypoints, costing model, and per-mode parameters. Traffic is post-route ETA enrichment only; it does not change the selected path.",
  "x-generated": "2026-10-30",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/geo-thinair-co-openapi.json#/components/schemas/DirectionsRequest",
  "type": "object",
  "properties": {
    "origin": {
      "anyOf": [
        {
          "type": "string",
          "minLength": 1,
          "maxLength": 2000
        },
        {
          "type": "object",
          "properties": {
            "lat": {
              "type": "number",
              "minimum": -90,
              "maximum": 90
            },
            "lon": {
              "type": "number",
              "minimum": -180,
              "maximum": 180
            }
          },
          "required": [
            "lat",
            "lon"
          ]
        }
      ],
      "description": "Free-text address ('Houston, TX', '4131 Center St, Houston, TX 77007') OR a coordinate pair { lat, lon }."
    },
    "destination": {
      "anyOf": [
        {
          "type": "string",
          "minLength": 1,
          "maxLength": 2000
        },
        {
          "type": "object",
          "properties": {
            "lat": {
              "type": "number",
              "minimum": -90,
              "maximum": 90
            },
            "lon": {
              "type": "number",
              "minimum": -180,
              "maximum": 180
            }
          },
          "required": [
            "lat",
            "lon"
          ]
        }
      ],
      "description": "Free-text address ('Houston, TX', '4131 Center St, Houston, TX 77007') OR a coordinate pair { lat, lon }."
    },
    "via": {
      "type": "array",
      "items": {
        "anyOf": [
          {
            "type": "string",
            "minLength": 1,
            "maxLength": 2000
          },
          {
            "type": "object",
            "properties": {
              "lat": {
                "type": "number",
                "minimum": -90,
                "maximum": 90
              },
              "lon": {
                "type": "number",
                "minimum": -180,
                "maximum": 180
              }
            },
            "required": [
              "lat",
              "lon"
            ]
          }
        ],
        "description": "Free-text address ('Houston, TX', '4131 Center St, Houston, TX 77007') OR a coordinate pair { lat, lon }."
      },
      "maxItems": 48,
      "description": "Intermediate stops in order. Same shape as origin/destination. Up to 48 waypoints (max 50 total locations)."
    },
    "alternates": {
      "type": "integer",
      "minimum": 0,
      "maximum": 2,
      "description": "Number of genuine motorized alternate routes to request (0, 1, or 2). Positive values require no via waypoints."
    },
    "costing": {
      "type": "string",
      "enum": [
        "auto",
        "truck",
        "bicycle",
        "pedestrian",
        "motorcycle"
      ],
      "description": "Transport mode. Default: auto."
    },
    "preset": {
      "type": "string",
      "maxLength": 64,
      "description": "Routing preset — one of: car_default, truck_53, truck_box26, truck_tanker, truck_flatbed, truck_step_deck, truck_auto_carrier, truck_sprinter, truck_double, truck_oversize, motorcycle, scooter, bike, walk, transit. Sets costing AND dimensions together. NOTE: these are NOT the `vehicle_profile` names — passing a vehicle_profile id here is not recognised and currently falls back to a CAR route."
    },
    "vehicle_profile": {
      "type": "string",
      "maxLength": 64,
      "description": "Truck dimension profile (10): DRY_VAN_53, FLATBED_48, FLATBED_40, STEP_DECK, TANKER, BOX_TRUCK_26, AUTO_CARRIER, SPRINTER_VAN, DOUBLE_TRAILER, OVERSIZE. Sets height/weight/length/axles. Distinct from `preset`, which also sets costing."
    },
    "truck_height": {
      "type": "number",
      "exclusiveMinimum": 0,
      "maximum": 30,
      "description": "Truck height (m)"
    },
    "truck_weight": {
      "type": "number",
      "exclusiveMinimum": 0,
      "maximum": 200,
      "description": "Truck weight (metric tons)"
    },
    "truck_width": {
      "type": "number",
      "exclusiveMinimum": 0,
      "maximum": 10
    },
    "truck_length": {
      "type": "number",
      "exclusiveMinimum": 0,
      "maximum": 60
    },
    "hazmat": {
      "type": "boolean",
      "description": "Routing avoids hazmat-restricted roads when true."
    },
    "axle_load": {
      "type": "number",
      "exclusiveMinimum": 0,
      "maximum": 100
    },
    "axle_count": {
      "type": "integer",
      "exclusiveMinimum": 0,
      "maximum": 20
    },
    "top_speed": {
      "type": "number",
      "exclusiveMinimum": 0,
      "maximum": 300
    },
    "use_highways": {
      "type": "number",
      "minimum": 0,
      "maximum": 1
    },
    "use_ferry": {
      "type": "number",
      "minimum": 0,
      "maximum": 1
    },
    "avoid_tolls": {
      "type": "boolean"
    },
    "include_traffic": {
      "type": "boolean",
      "description": "Apply post-route live-traffic ETA enrichment. Default: true. Traffic does not change the returned path (path_influenced=false); truck adjustments are slowdown-only."
    },
    "include_weather": {
      "type": "boolean"
    },
    "include_elevation": {
      "type": "boolean",
      "description": "When true, include available route elevation fields. Point elevation may be returned for the origin and destination. Cumulative gain/loss is returned only when route-profile elevation is available. Default: false (an extra upstream lookup, opt-in only)."
    },
    "units": {
      "type": "string",
      "enum": [
        "miles",
        "kilometers"
      ],
      "description": "Distance units. Default: miles. Accepts 'km'/'mi' as aliases."
    },
    "depart_at": {
      "type": "string",
      "format": "date-time",
      "description": "Departure time (ISO 8601). Default: now."
    },
    "include_geometry": {
      "type": "string",
      "enum": [
        "none",
        "encoded",
        "full"
      ],
      "description": "Route geometry shape control. \"none\" returns origin/destination Points only. \"encoded\" returns an encoded polyline6 string in a top-level `geometry` field plus origin/destination Points (≈95% smaller than raw GeoJSON; decode with @mapbox/polyline at precision 6). \"full\" emits decoded coordinates as a LineString in `geojson.features[0]`. When omitted (default), small routes use \"full\" and long routes auto-downgrade to \"encoded\" with a `geometry_truncated` warning."
    }
  },
  "required": [
    "origin",
    "destination"
  ]
}