{
  "openapi" : "3.1.0",
  "info" : {
    "title" : "LiveMap Routing — v2 Navigation",
    "description" : "## Choose this contract for navigation\nv2 emits the documented OSRM-compatible subset with Mapbox voice/banner extensions,\nnot the complete Mapbox API. Geometry is encoded polyline6 (precision 1e-6 degrees);\ndistances are meters and durations are seconds.\n\n## Client workflow\n1. Read `GET /api/v2/routing/profiles` for available product IDs and lifecycle metadata.\n2. Use `POST /api/v2/routing/route` with singular `profile` for guidance/rerouting,\n   or `POST /api/v2/routing/plan` with just `points` for engine-selected planning.\n   An optional plural `profiles` list selects explicit-profile compatibility mode.\n3. Inspect each response's `code`. Start navigation only for `Ok` with a nonempty `routes` array.\n   For `/plan`, inspect each document in `profiles`, not the wrapper itself.\n   `NoRoute` is HTTP 200 with empty routes/waypoints; only an explicit-profile plan\n   can mix success and failure. Automatic mode omits unavailable alternatives\n   and returns only the baseline document when that baseline is `NoRoute`.\n4. Capture `resolvedBucket` and send it as `bucket` on later requests if bucket continuity is needed.\n   This pins the temporal bucket, not every time-dependent policy input.\n\n`/plan` with omitted `profiles` returns the configured baseline (normally `foot_fast`)\nplus active-profile alternatives strictly less than 1.5 times the baseline distance.\nUnavailable and over-limit alternatives are absent; baseline-only means none qualify.\nIf the baseline is unreachable or zero-length, only its response is returned.\nWith explicit `profiles`, every requested key is preserved without filtering, including\ndeprecated profiles and `NoRoute` documents. Explicit null/empty lists remain invalid.\nNeither mode applies a geometry-overlap/deduplication gate or emits `NoAlternative`.\nProfile deprecation does not change an ID's routing meaning.\nExisting GeoJSON/millisecond clients must keep using [v1](/api/v1/routing/openapi.json)\nuntil explicitly adapted.\n\n## Scope and deployment\nThis is the routing **engine** contract, not the frontend's public facade.\nFrontend authentication, payload dispatch, presentation/localization, and proxy 502/504 errors\nare owned by that facade and are not described here. The engine defines no bearer-token scheme;\na deployment gateway may impose its own access controls.\nUse `Content-Type: application/json` for POST requests. Examples are illustrative, not a\npromise of route availability or an exhaustive profile catalog.\nThis document describes the serving build; `info.version` is its service version.\nRead `/api/version` separately for build/data identity. Rendered documentation is at `/docs`.\n",
    "version" : "1.0.0-SNAPSHOT"
  },
  "servers" : [ {
    "url" : "/",
    "description" : "Same-origin routing engine or reverse proxy"
  } ],
  "tags" : [ {
    "name" : "Navigation v2",
    "description" : "Turn-by-turn navigation with OSRM-compatible route documents (GraphHopper's type=mapbox output) for clients such as Ferrostar. /route takes one product profile and returns a bare document; /plan wraps documents by profile, selecting profiles automatically when omitted or preserving one or more explicitly requested profiles."
  } ],
  "paths" : {
    "/api/v2/routing/openapi.json" : {
      "get" : {
        "tags" : [ "Navigation v2" ],
        "summary" : "Return the v2 OpenAPI document",
        "description" : "OpenAPI 3.1 contract for the v2 navigation API, generated at runtime from the live resource.",
        "operationId" : "v2GetOpenApi",
        "responses" : {
          "200" : {
            "description" : "OpenAPI 3.1 JSON document",
            "content" : {
              "application/json" : {
                "schema" : { }
              }
            }
          }
        }
      }
    },
    "/api/v2/routing/plan" : {
      "post" : {
        "tags" : [ "Navigation v2" ],
        "summary" : "Plan a walk with reasonable alternatives or explicit profiles",
        "description" : "**Automatic planning (omit `profiles`):** routes the configured baseline (`foot_fast` in the shipped config) and active, non-deprecated catalog profiles. Keeps the baseline and only successful alternatives whose first-route distance is **strictly less than 1.5 times** the baseline distance. Exactly 50% longer is excluded. Unavailable or over-limit alternatives have no entry; there is no `NoAlternative` code. No overlap/deduplication gate is applied. If no alternative qualifies, only the baseline is returned. If the baseline is `NoRoute` or has zero distance, no alternatives are evaluated. A missing or deprecated configured baseline is a server configuration error.\n\n**Explicit-profile compatibility mode (provide `profiles`):** preserves every requested key, including deprecated profiles and per-profile `NoRoute` documents, without distance or overlap filtering. `profiles: null`, an empty list, duplicate IDs and unknown IDs remain invalid. This mode retains the contract used by existing frontend callers.\n\nBoth modes return `{\"profiles\": {\"profile_id\": {...}}}` containing standalone OSRM-compatible documents. The client builds a chooser from the wrapper and hands a picked `Ok` sub-response with nonempty `routes` to the navigation client verbatim. Do not start navigation for `NoRoute`. Unsupported top-level request fields are stripped (and logged) before mapping. `bucket` defaults to `auto` (re-resolved from the Europe/Zurich wall clock per request); each sub-document echoes the applied `resolvedBucket` so a client can pin it as an explicit `bucket` on later requests.",
        "operationId" : "v2PostPlan",
        "requestBody" : {
          "content" : {
            "application/json" : {
              "schema" : {
                "$ref" : "#/components/schemas/LivemapNavigationPlanRequest"
              },
              "examples" : {
                "Automatic plan" : {
                  "summary" : "Engine-selected profiles and the strict 50% distance cap",
                  "description" : "Automatic plan",
                  "value" : {
                    "points" : [ [ 8.5417, 47.3769 ], [ 8.55, 47.38 ] ],
                    "bucket" : "auto"
                  }
                },
                "Multi-profile plan" : {
                  "summary" : "Compatibility mode: every requested profile, without filtering",
                  "description" : "Multi-profile plan",
                  "value" : {
                    "profiles" : [ "foot_fast", "foot_lowcrash" ],
                    "points" : [ [ 8.5417, 47.3769 ], [ 8.55, 47.38 ] ],
                    "voice_units" : "metric",
                    "bucket" : "auto"
                  }
                }
              }
            }
          },
          "required" : true
        },
        "responses" : {
          "200" : {
            "description" : "Profile-keyed wrapper `{\"profiles\": {\"profile_id\": {...}}}`. Automatic mode keeps the baseline plus qualifying alternatives only. Explicit mode keeps every requested key, even for `NoRoute`. Each sub-response carries its own code and its own resolvedBucket. HTTP 200 does not guarantee a usable route.",
            "content" : {
              "application/json" : {
                "schema" : {
                  "$ref" : "#/components/schemas/NavigationPlanResponse"
                },
                "examples" : {
                  "Success" : {
                    "value" : {
                      "profiles" : {
                        "foot_fast" : {
                          "code" : "Ok",
                          "uuid" : "d03362a440d14996a8b418bda86612d0",
                          "resolvedBucket" : "wd_am",
                          "waypoints" : [ {
                            "name" : "",
                            "location" : [ 8.54, 47.37 ]
                          }, {
                            "name" : "",
                            "location" : [ 8.541, 47.371 ]
                          } ],
                          "routes" : [ {
                            "geometry" : "_pfjyA_ufhOo}@o}@",
                            "weight_name" : "routability",
                            "weight" : 90,
                            "duration" : 90,
                            "distance" : 120,
                            "voiceLocale" : "en",
                            "legs" : [ {
                              "summary" : "GraphHopper Route 0",
                              "weight" : 90,
                              "duration" : 90,
                              "distance" : 120,
                              "steps" : [ {
                                "intersections" : [ ],
                                "driving_side" : "right",
                                "geometry" : "_pfjyA_ufhOo}@o}@",
                                "mode" : "walking",
                                "maneuver" : {
                                  "bearing_before" : 0,
                                  "bearing_after" : 0,
                                  "location" : [ 8.54, 47.37 ],
                                  "type" : "depart",
                                  "instruction" : "Continue"
                                },
                                "weight" : 120,
                                "duration" : 90,
                                "name" : "",
                                "distance" : 120,
                                "voiceInstructions" : [ ],
                                "bannerInstructions" : [ ]
                              } ]
                            } ]
                          } ]
                        },
                        "foot_green" : {
                          "code" : "Ok",
                          "uuid" : "d03362a440d14996a8b418bda86612d0",
                          "resolvedBucket" : "wd_am",
                          "waypoints" : [ {
                            "name" : "",
                            "location" : [ 8.54, 47.37 ]
                          }, {
                            "name" : "",
                            "location" : [ 8.541, 47.371 ]
                          } ],
                          "routes" : [ {
                            "geometry" : "_pfjyA_ufhOo}@o}@",
                            "weight_name" : "routability",
                            "weight" : 90,
                            "duration" : 90,
                            "distance" : 120,
                            "voiceLocale" : "en",
                            "legs" : [ {
                              "summary" : "GraphHopper Route 0",
                              "weight" : 90,
                              "duration" : 90,
                              "distance" : 120,
                              "steps" : [ {
                                "intersections" : [ ],
                                "driving_side" : "right",
                                "geometry" : "_pfjyA_ufhOo}@o}@",
                                "mode" : "walking",
                                "maneuver" : {
                                  "bearing_before" : 0,
                                  "bearing_after" : 0,
                                  "location" : [ 8.54, 47.37 ],
                                  "type" : "depart",
                                  "instruction" : "Continue"
                                },
                                "weight" : 120,
                                "duration" : 90,
                                "name" : "",
                                "distance" : 120,
                                "voiceInstructions" : [ ],
                                "bannerInstructions" : [ ]
                              } ]
                            } ]
                          } ]
                        }
                      }
                    }
                  },
                  "Partial success" : {
                    "value" : {
                      "profiles" : {
                        "foot_fast" : {
                          "code" : "Ok",
                          "uuid" : "d03362a440d14996a8b418bda86612d0",
                          "resolvedBucket" : "wd_am",
                          "waypoints" : [ {
                            "name" : "",
                            "location" : [ 8.54, 47.37 ]
                          }, {
                            "name" : "",
                            "location" : [ 8.541, 47.371 ]
                          } ],
                          "routes" : [ {
                            "geometry" : "_pfjyA_ufhOo}@o}@",
                            "weight_name" : "routability",
                            "weight" : 90,
                            "duration" : 90,
                            "distance" : 120,
                            "voiceLocale" : "en",
                            "legs" : [ {
                              "summary" : "GraphHopper Route 0",
                              "weight" : 90,
                              "duration" : 90,
                              "distance" : 120,
                              "steps" : [ {
                                "intersections" : [ ],
                                "driving_side" : "right",
                                "geometry" : "_pfjyA_ufhOo}@o}@",
                                "mode" : "walking",
                                "maneuver" : {
                                  "bearing_before" : 0,
                                  "bearing_after" : 0,
                                  "location" : [ 8.54, 47.37 ],
                                  "type" : "depart",
                                  "instruction" : "Continue"
                                },
                                "weight" : 120,
                                "duration" : 90,
                                "name" : "",
                                "distance" : 120,
                                "voiceInstructions" : [ ],
                                "bannerInstructions" : [ ]
                              } ]
                            } ]
                          } ]
                        },
                        "foot_green" : {
                          "code" : "NoRoute",
                          "message" : "No route found",
                          "resolvedBucket" : "wd_am",
                          "routes" : [ ],
                          "waypoints" : [ ]
                        }
                      }
                    },
                    "summary" : "Explicit-profile mode preserves a NoRoute entry alongside success."
                  },
                  "No route" : {
                    "value" : {
                      "profiles" : {
                        "foot_fast" : {
                          "code" : "NoRoute",
                          "message" : "No route found",
                          "resolvedBucket" : "wd_am",
                          "routes" : [ ],
                          "waypoints" : [ ]
                        },
                        "foot_green" : {
                          "code" : "NoRoute",
                          "message" : "No route found",
                          "resolvedBucket" : "wd_am",
                          "routes" : [ ],
                          "waypoints" : [ ]
                        }
                      }
                    },
                    "summary" : "Explicit-profile mode preserves every requested NoRoute entry."
                  },
                  "Automatic baseline only" : {
                    "value" : {
                      "profiles" : {
                        "foot_fast" : {
                          "code" : "Ok",
                          "uuid" : "d03362a440d14996a8b418bda86612d0",
                          "resolvedBucket" : "wd_am",
                          "waypoints" : [ {
                            "name" : "",
                            "location" : [ 8.54, 47.37 ]
                          }, {
                            "name" : "",
                            "location" : [ 8.541, 47.371 ]
                          } ],
                          "routes" : [ {
                            "geometry" : "_pfjyA_ufhOo}@o}@",
                            "weight_name" : "routability",
                            "weight" : 90,
                            "duration" : 90,
                            "distance" : 120,
                            "voiceLocale" : "en",
                            "legs" : [ {
                              "summary" : "GraphHopper Route 0",
                              "weight" : 90,
                              "duration" : 90,
                              "distance" : 120,
                              "steps" : [ {
                                "intersections" : [ ],
                                "driving_side" : "right",
                                "geometry" : "_pfjyA_ufhOo}@o}@",
                                "mode" : "walking",
                                "maneuver" : {
                                  "bearing_before" : 0,
                                  "bearing_after" : 0,
                                  "location" : [ 8.54, 47.37 ],
                                  "type" : "depart",
                                  "instruction" : "Continue"
                                },
                                "weight" : 120,
                                "duration" : 90,
                                "name" : "",
                                "distance" : 120,
                                "voiceInstructions" : [ ],
                                "bannerInstructions" : [ ]
                              } ]
                            } ]
                          } ]
                        }
                      }
                    }
                  },
                  "Automatic no route" : {
                    "value" : {
                      "profiles" : {
                        "foot_fast" : {
                          "code" : "NoRoute",
                          "message" : "No route found",
                          "resolvedBucket" : "wd_am",
                          "routes" : [ ],
                          "waypoints" : [ ]
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "400" : {
            "description" : "Invalid routing input or undecodable JSON. Routing validation uses a string code; the framework JSON-decoding response uses numeric code 400.",
            "content" : {
              "application/json" : {
                "schema" : {
                  "oneOf" : [ {
                    "$ref" : "#/components/schemas/NavigationValidationError"
                  }, {
                    "$ref" : "#/components/schemas/JsonDecodingError"
                  } ]
                },
                "examples" : {
                  "Validation error" : {
                    "value" : {
                      "code" : "InvalidInput",
                      "message" : "points must contain at least two [lng, lat] tuples"
                    }
                  },
                  "Malformed JSON" : {
                    "value" : {
                      "code" : 400,
                      "message" : "Unable to process JSON"
                    }
                  }
                }
              }
            }
          },
          "500" : {
            "description" : "Unexpected server error (code InternalError)",
            "content" : {
              "application/json" : {
                "schema" : {
                  "$ref" : "#/components/schemas/NavigationInternalError"
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/routing/profiles" : {
      "get" : {
        "tags" : [ "Navigation v2" ],
        "summary" : "Return the product profile catalog with every policy block",
        "description" : "Each profile carries base_profile, the per-dimension weights, and the policy blocks the custom model is built from (noise, lights, green, water, tree, accident, ordinal, incline, main_roads), in exactly the shape of livemap.routing.profiles in the service config. This is what the local demo loads as its baseline; the deprecated v1 catalog serves weights only.",
        "operationId" : "v2GetProfiles",
        "responses" : {
          "200" : {
            "description" : "Profile catalog keyed by product profile id. This endpoint is the authority for which ids exist; an entry flagged `deprecated` carries `superseded_by`.",
            "content" : {
              "application/json" : {
                "schema" : {
                  "$ref" : "#/components/schemas/ProfileCatalogV2"
                },
                "examples" : {
                  "Active profile" : {
                    "value" : {
                      "foot_fast" : {
                        "base_profile" : "foot_base",
                        "weights" : {
                          "tree" : 0.0,
                          "lights" : 0.0,
                          "accident" : 0.0,
                          "crime" : 0.0,
                          "presence" : 0.0,
                          "noise" : 0.0,
                          "water" : 0.0,
                          "green" : 0.0,
                          "incline" : 0.0,
                          "main_roads" : 0.0
                        },
                        "noise" : {
                          "source" : "ordinal",
                          "thresholds" : {
                            "day" : [ 55.0, 65.0 ],
                            "night" : [ 45.0, 55.0 ]
                          },
                          "full_weight_targets" : [ 0.9, 0.7, 0.45 ],
                          "min_receiver_count" : 1,
                          "evidence_kind_factors" : {
                            "direct_p90" : null,
                            "los_ring_p90" : null,
                            "ring_p90_occluded" : null,
                            "no_receiver_in_range" : 0.9,
                            "out_of_source_extent" : 0.9
                          }
                        },
                        "lights" : {
                          "source" : null,
                          "bands_pct" : [ 25, 75 ],
                          "full_weight_targets" : [ 1.25, 1.5 ]
                        },
                        "green" : {
                          "source" : "ordinal",
                          "thresholds_pct" : [ 1, 6, 51 ],
                          "full_weight_targets" : [ 1.0, 1.1, 1.25, 1.5 ]
                        },
                        "water" : {
                          "source" : "ordinal",
                          "thresholds_pct" : [ 1, 6, 51 ],
                          "full_weight_targets" : [ 1.0, 1.1, 1.25, 1.5 ]
                        },
                        "tree" : {
                          "source" : "ordinal",
                          "thresholds_pct" : [ 1, 6, 51 ],
                          "full_weight_targets" : [ 1.0, 1.1, 1.25, 1.5 ]
                        },
                        "accident" : {
                          "source" : "ordinal",
                          "severity_weights" : {
                            "fatal" : 8.0,
                            "serious" : 4.0,
                            "total" : 1.0
                          },
                          "predicate" : {
                            "min_fatal" : 1,
                            "min_serious" : 3,
                            "min_total" : 10
                          },
                          "severity_threshold" : 4.0,
                          "full_weight_targets" : [ 0.45, 0.7, 0.9 ]
                        },
                        "ordinal" : {
                          "thresholds" : [ 1, 2, 4 ],
                          "penalty_targets" : [ 0.9, 0.7, 0.45 ],
                          "reward_targets" : [ 1.1, 1.25, 1.5 ]
                        },
                        "incline" : {
                          "thresholds_pct" : [ 6, 12 ],
                          "full_weight_targets" : [ 0.7, 0.45 ]
                        },
                        "main_roads" : {
                          "full_weight_targets" : {
                            "trunk_primary" : 0.45,
                            "secondary" : 0.7,
                            "tertiary" : 0.9
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v2/routing/route" : {
      "post" : {
        "tags" : [ "Navigation v2" ],
        "summary" : "Calculate a turn-by-turn navigation route (OSRM-compatible JSON)",
        "description" : "Routes a single product profile and returns OSRM-compatible JSON (the OSRM route-service shape plus Mapbox banner/voice extensions) via GraphHopper's NavigateResponseConverter, consumable as-is by clients that speak it, such as Ferrostar. Unsupported top-level request fields are stripped (and logged) before mapping. `bucket` defaults to `auto`, which re-resolves the time-of-day safety weighting from the Europe/Zurich wall clock on every request — so a reroute can land in a different bucket mid-trip. The response echoes the applied bucket as a top-level `resolvedBucket`; to pin a stable profile across a trip, send that value back as `bucket` on subsequent requests.",
        "operationId" : "v2PostRoute",
        "requestBody" : {
          "content" : {
            "application/json" : {
              "schema" : {
                "$ref" : "#/components/schemas/LivemapNavigationRequest"
              },
              "examples" : {
                "Minimal route" : {
                  "summary" : "Single profile, no alternatives (alternative_route is optional)",
                  "description" : "Minimal route",
                  "value" : {
                    "profile" : "foot_lowcrash",
                    "points" : [ [ 8.5417, 47.3769 ], [ 8.55, 47.38 ] ],
                    "voice_units" : "metric",
                    "bucket" : "auto"
                  }
                },
                "With alternatives" : {
                  "summary" : "Request up to one alternative with valid tuning bounds",
                  "description" : "With alternatives",
                  "value" : {
                    "profile" : "foot_lowcrash",
                    "points" : [ [ 8.5417, 47.3769 ], [ 8.55, 47.38 ] ],
                    "voice_units" : "metric",
                    "bucket" : "auto",
                    "alternative_route" : {
                      "max_paths" : 2,
                      "max_weight_factor" : 1.4,
                      "max_share_factor" : 0.6
                    }
                  }
                }
              }
            }
          },
          "required" : true
        },
        "responses" : {
          "200" : {
            "description" : "OSRM-compatible response (code, routes[], waypoints[]), plus a top-level \"resolvedBucket\" echoing the time bucket that weighted the route (for reroute pinning). A routable failure is also 200, with code \"NoRoute\" and routes: []. Field reference: https://docs.mapbox.com/api/navigation/directions/#response-object",
            "content" : {
              "application/json" : {
                "schema" : {
                  "$ref" : "#/components/schemas/NavigationResponse"
                },
                "examples" : {
                  "Success" : {
                    "value" : {
                      "code" : "Ok",
                      "uuid" : "d03362a440d14996a8b418bda86612d0",
                      "resolvedBucket" : "wd_am",
                      "waypoints" : [ {
                        "name" : "",
                        "location" : [ 8.54, 47.37 ]
                      }, {
                        "name" : "",
                        "location" : [ 8.541, 47.371 ]
                      } ],
                      "routes" : [ {
                        "geometry" : "_pfjyA_ufhOo}@o}@",
                        "weight_name" : "routability",
                        "weight" : 90,
                        "duration" : 90,
                        "distance" : 120,
                        "voiceLocale" : "en",
                        "legs" : [ {
                          "summary" : "GraphHopper Route 0",
                          "weight" : 90,
                          "duration" : 90,
                          "distance" : 120,
                          "steps" : [ {
                            "intersections" : [ ],
                            "driving_side" : "right",
                            "geometry" : "_pfjyA_ufhOo}@o}@",
                            "mode" : "walking",
                            "maneuver" : {
                              "bearing_before" : 0,
                              "bearing_after" : 0,
                              "location" : [ 8.54, 47.37 ],
                              "type" : "depart",
                              "instruction" : "Continue"
                            },
                            "weight" : 120,
                            "duration" : 90,
                            "name" : "",
                            "distance" : 120,
                            "voiceInstructions" : [ ],
                            "bannerInstructions" : [ ]
                          } ]
                        } ]
                      } ]
                    }
                  },
                  "No route" : {
                    "value" : {
                      "code" : "NoRoute",
                      "message" : "No route found",
                      "resolvedBucket" : "wd_am",
                      "routes" : [ ],
                      "waypoints" : [ ]
                    }
                  }
                }
              }
            }
          },
          "400" : {
            "description" : "Invalid routing input or undecodable JSON. Routing validation uses a string code; the framework JSON-decoding response uses numeric code 400.",
            "content" : {
              "application/json" : {
                "schema" : {
                  "oneOf" : [ {
                    "$ref" : "#/components/schemas/NavigationValidationError"
                  }, {
                    "$ref" : "#/components/schemas/JsonDecodingError"
                  } ]
                },
                "examples" : {
                  "Validation error" : {
                    "value" : {
                      "code" : "InvalidInput",
                      "message" : "points must contain at least two [lng, lat] tuples"
                    }
                  },
                  "Malformed JSON" : {
                    "value" : {
                      "code" : 400,
                      "message" : "Unable to process JSON"
                    }
                  }
                }
              }
            }
          },
          "500" : {
            "description" : "Unexpected server error (code InternalError)",
            "content" : {
              "application/json" : {
                "schema" : {
                  "$ref" : "#/components/schemas/NavigationInternalError"
                }
              }
            }
          }
        }
      }
    }
  },
  "components" : {
    "schemas" : {
      "LivemapNavigationPlanRequest" : {
        "description" : "v2 multi-profile plan request. Omit profiles for product planning, or provide profiles to route exactly those catalog ids without filtering. Returns a profile-keyed wrapper of standalone OSRM-compatible documents.",
        "properties" : {
          "profiles" : {
            "type" : "array",
            "description" : "Optional product profile ids to route, at least one when provided; null and empty arrays are invalid. Omit for product planning: retain the configured baseline and return successful non-deprecated alternatives whose first-route distance is strictly less than 1.5 times the baseline distance, without overlap filtering or deduplication. An unreachable or zero-distance baseline is returned alone. When provided, every requested id is returned, including deprecated profiles and NoRoute documents, without filtering. The authoritative list is served by GET /api/v2/routing/profiles — the catalog is deployment config, not a fixed enum, so do not hard-code it; an entry flagged `deprecated` still routes and names its replacements in `superseded_by`. Each id becomes a key of the `profiles` object in the response wrapper. An unknown id, or the same id twice, is a 400.",
            "example" : [ "foot_fast", "foot_lowcrash" ],
            "items" : {
              "type" : "string",
              "minLength" : 1
            },
            "minItems" : 1,
            "uniqueItems" : true
          },
          "points" : {
            "type" : "array",
            "description" : "Ordered waypoints as [longitude, latitude] pairs (at least 2). Each pair has exactly two finite numbers: longitude in [-180, 180], latitude in [-90, 90].",
            "example" : [ [ 8.5417, 47.3769 ], [ 8.55, 47.38 ] ],
            "items" : {
              "type" : "array",
              "items" : {
                "type" : "number",
                "description" : "WGS84 degrees"
              },
              "minItems" : 2,
              "maxItems" : 2,
              "description" : "Exactly [longitude, latitude], WGS84 degrees.",
              "prefixItems" : [ {
                "type" : "number",
                "description" : "Longitude",
                "minimum" : -180,
                "maximum" : 180
              }, {
                "type" : "number",
                "description" : "Latitude",
                "minimum" : -90,
                "maximum" : 90
              } ]
            },
            "minItems" : 2
          },
          "locale" : {
            "type" : "string",
            "default" : "en",
            "description" : "Instruction language."
          },
          "voice_units" : {
            "type" : "string",
            "default" : "metric",
            "description" : "Units for voice/banner instructions.",
            "enum" : [ "metric", "imperial" ]
          },
          "bucket" : {
            "type" : "string",
            "default" : "auto",
            "description" : "Temporal safety/presence bucket. \"auto\" resolves against Europe/Zurich wall-clock time (weekday/weekend x morning/afternoon/night).",
            "enum" : [ "auto", "wd_am", "wd_pm", "wd_nt", "we_am", "we_pm", "we_nt" ]
          }
        },
        "required" : [ "points" ]
      },
      "MapboxError" : {
        "description" : "OSRM/Mapbox-style error body. Note: a routable-failure (code NoRoute) is returned with HTTP 200 and routes: [], not as an error.",
        "properties" : {
          "code" : {
            "type" : "string",
            "description" : "Mapbox error code",
            "enum" : [ "InvalidInput", "NoRoute", "InternalError" ],
            "example" : "InvalidInput"
          },
          "message" : {
            "type" : "string",
            "description" : "Human-readable detail"
          }
        }
      },
      "AlternativeRoute" : {
        "description" : "Optional alternative-route tuning passed through to GraphHopper.",
        "properties" : {
          "max_paths" : {
            "type" : "integer",
            "format" : "int32",
            "description" : "Maximum number of paths GraphHopper may return, counting the primary route. Must be at least 2 (2 yields the primary route plus up to one alternative).",
            "example" : 2,
            "minimum" : 2
          },
          "max_weight_factor" : {
            "type" : "number",
            "format" : "double",
            "description" : "Maximum alternative weight factor. Must be greater than 1.",
            "example" : 1.4,
            "exclusiveMinimum" : 1
          },
          "max_share_factor" : {
            "type" : "number",
            "format" : "double",
            "description" : "Maximum route-share factor for alternatives. Must be greater than 0 and at most 1.",
            "example" : 0.6,
            "maximum" : 1,
            "exclusiveMinimum" : 0
          }
        }
      },
      "LivemapNavigationRequest" : {
        "description" : "v2 navigation request. Unlike v1, takes a single product profile per request.",
        "properties" : {
          "profile" : {
            "type" : "string",
            "description" : "The single product profile id to route. The authoritative list is served by GET /api/v2/routing/profiles; an entry flagged `deprecated` there still routes and names its replacements in `superseded_by`. An unknown id is a 400.",
            "example" : "foot_lowcrash",
            "minLength" : 1
          },
          "points" : {
            "type" : "array",
            "description" : "Ordered waypoints as [longitude, latitude] pairs (at least 2). Each pair has exactly two finite numbers: longitude in [-180, 180], latitude in [-90, 90].",
            "example" : [ [ 8.5417, 47.3769 ], [ 8.55, 47.38 ] ],
            "items" : {
              "type" : "array",
              "items" : {
                "type" : "number",
                "description" : "WGS84 degrees"
              },
              "minItems" : 2,
              "maxItems" : 2,
              "description" : "Exactly [longitude, latitude], WGS84 degrees.",
              "prefixItems" : [ {
                "type" : "number",
                "description" : "Longitude",
                "minimum" : -180,
                "maximum" : 180
              }, {
                "type" : "number",
                "description" : "Latitude",
                "minimum" : -90,
                "maximum" : 90
              } ]
            },
            "minItems" : 2
          },
          "locale" : {
            "type" : "string",
            "default" : "en",
            "description" : "Instruction language."
          },
          "type" : {
            "type" : "string",
            "default" : "mapbox",
            "description" : "GraphHopper response-format selector. Only the OSRM-compatible (type=mapbox) shape is produced.",
            "enum" : [ "mapbox" ]
          },
          "voice_units" : {
            "type" : "string",
            "default" : "metric",
            "description" : "Units for voice/banner instructions.",
            "enum" : [ "metric", "imperial" ]
          },
          "bucket" : {
            "type" : "string",
            "default" : "auto",
            "description" : "Temporal safety/presence bucket. \"auto\" resolves against Europe/Zurich wall-clock time (weekday/weekend x morning/afternoon/night).",
            "enum" : [ "auto", "wd_am", "wd_pm", "wd_nt", "we_am", "we_pm", "we_nt" ]
          },
          "alternative_route" : {
            "$ref" : "#/components/schemas/AlternativeRoute"
          }
        },
        "required" : [ "points", "profile" ]
      },
      "ResponseCoordinate" : {
        "type" : "array",
        "items" : {
          "type" : "number",
          "description" : "WGS84 degrees"
        },
        "minItems" : 2,
        "maxItems" : 2,
        "description" : "Exactly [longitude, latitude], WGS84 degrees.",
        "prefixItems" : [ {
          "type" : "number",
          "description" : "Longitude",
          "minimum" : -180,
          "maximum" : 180
        }, {
          "type" : "number",
          "description" : "Latitude",
          "minimum" : -90,
          "maximum" : 90
        } ]
      },
      "ResolvedBucket" : {
        "type" : "string",
        "enum" : [ "wd_am", "wd_pm", "wd_nt", "we_am", "we_pm", "we_nt" ]
      },
      "ProfileWeights" : {
        "type" : "object",
        "properties" : {
          "tree" : {
            "type" : "number",
            "description" : "Preference weight"
          },
          "lights" : {
            "type" : "number",
            "description" : "Preference weight"
          },
          "accident" : {
            "type" : "number",
            "description" : "Preference weight"
          },
          "crime" : {
            "type" : "number",
            "description" : "Preference weight"
          },
          "presence" : {
            "type" : "number",
            "description" : "Preference weight"
          },
          "noise" : {
            "type" : "number",
            "description" : "Preference weight"
          },
          "water" : {
            "type" : "number",
            "description" : "Preference weight"
          },
          "green" : {
            "type" : "number",
            "description" : "Preference weight"
          },
          "incline" : {
            "type" : "number",
            "description" : "Preference weight"
          },
          "main_roads" : {
            "type" : "number",
            "description" : "Preference weight"
          }
        },
        "required" : [ "tree", "lights", "accident", "crime", "presence", "noise", "water", "green", "incline", "main_roads" ]
      },
      "ProfileV1" : {
        "type" : "object",
        "properties" : {
          "base_profile" : {
            "type" : "string"
          },
          "weights" : {
            "$ref" : "#/components/schemas/ProfileWeights"
          },
          "deprecated" : {
            "type" : "boolean",
            "enum" : [ true ],
            "description" : "Present only when deprecated; omission means active."
          },
          "superseded_by" : {
            "type" : "array",
            "items" : {
              "type" : "string"
            },
            "description" : "Replacement product IDs; omitted when empty."
          },
          "sunset" : {
            "type" : "string",
            "format" : "date",
            "description" : "Agreed removal date, YYYY-MM-DD; absent until agreed, including on deprecated profiles."
          }
        },
        "required" : [ "base_profile", "weights" ]
      },
      "ProfileV2" : {
        "type" : "object",
        "properties" : {
          "base_profile" : {
            "type" : "string"
          },
          "weights" : {
            "$ref" : "#/components/schemas/ProfileWeights"
          },
          "deprecated" : {
            "type" : "boolean",
            "enum" : [ true ],
            "description" : "Present only when deprecated; omission means active."
          },
          "superseded_by" : {
            "type" : "array",
            "items" : {
              "type" : "string"
            },
            "description" : "Replacement product IDs; omitted when empty."
          },
          "sunset" : {
            "type" : "string",
            "format" : "date",
            "description" : "Agreed removal date, YYYY-MM-DD; absent until agreed, including on deprecated profiles."
          },
          "noise" : {
            "$ref" : "#/components/schemas/ProfilePolicy_noise"
          },
          "lights" : {
            "$ref" : "#/components/schemas/ProfilePolicy_lights"
          },
          "green" : {
            "$ref" : "#/components/schemas/ProfilePolicy_green"
          },
          "water" : {
            "$ref" : "#/components/schemas/ProfilePolicy_water"
          },
          "tree" : {
            "$ref" : "#/components/schemas/ProfilePolicy_tree"
          },
          "accident" : {
            "$ref" : "#/components/schemas/ProfilePolicy_accident"
          },
          "ordinal" : {
            "$ref" : "#/components/schemas/ProfilePolicy_ordinal"
          },
          "incline" : {
            "$ref" : "#/components/schemas/ProfilePolicy_incline"
          },
          "main_roads" : {
            "$ref" : "#/components/schemas/ProfilePolicy_main_roads"
          }
        },
        "required" : [ "base_profile", "weights", "noise", "lights", "green", "water", "tree", "accident", "ordinal", "incline", "main_roads" ]
      },
      "ProfilePolicy_noise" : {
        "type" : "object",
        "properties" : {
          "source" : {
            "type" : "string",
            "enum" : [ "ordinal", "raw" ]
          },
          "thresholds" : {
            "type" : "object",
            "properties" : {
              "day" : {
                "type" : "array",
                "items" : {
                  "type" : "number",
                  "description" : "Configured policy value"
                }
              },
              "night" : {
                "type" : "array",
                "items" : {
                  "type" : "number",
                  "description" : "Configured policy value"
                }
              }
            },
            "required" : [ "day", "night" ]
          },
          "full_weight_targets" : {
            "type" : "array",
            "items" : {
              "type" : "number",
              "description" : "Configured policy value"
            }
          },
          "min_receiver_count" : {
            "type" : "integer",
            "description" : "Configured policy value"
          },
          "evidence_kind_factors" : {
            "type" : "object",
            "properties" : {
              "direct_p90" : {
                "anyOf" : [ {
                  "type" : "number",
                  "description" : "Evidence attenuation factor"
                }, {
                  "type" : "null"
                } ]
              },
              "los_ring_p90" : {
                "anyOf" : [ {
                  "type" : "number",
                  "description" : "Evidence attenuation factor"
                }, {
                  "type" : "null"
                } ]
              },
              "ring_p90_occluded" : {
                "anyOf" : [ {
                  "type" : "number",
                  "description" : "Evidence attenuation factor"
                }, {
                  "type" : "null"
                } ]
              },
              "no_receiver_in_range" : {
                "type" : "number",
                "description" : "Configured policy value"
              },
              "out_of_source_extent" : {
                "type" : "number",
                "description" : "Configured policy value"
              }
            },
            "required" : [ "direct_p90", "los_ring_p90", "ring_p90_occluded", "no_receiver_in_range", "out_of_source_extent" ]
          }
        },
        "required" : [ "source", "thresholds", "full_weight_targets", "min_receiver_count", "evidence_kind_factors" ]
      },
      "ProfilePolicy_lights" : {
        "type" : "object",
        "properties" : {
          "source" : {
            "anyOf" : [ {
              "type" : "string",
              "enum" : [ "ordinal", "lit_fraction_bands" ]
            }, {
              "type" : "null"
            } ]
          },
          "bands_pct" : {
            "type" : "array",
            "items" : {
              "type" : "integer",
              "description" : "Configured policy value"
            }
          },
          "full_weight_targets" : {
            "type" : "array",
            "items" : {
              "type" : "number",
              "description" : "Configured policy value"
            }
          }
        },
        "required" : [ "source", "bands_pct", "full_weight_targets" ]
      },
      "ProfilePolicy_green" : {
        "type" : "object",
        "properties" : {
          "source" : {
            "type" : "string",
            "enum" : [ "ordinal", "raw_fraction" ]
          },
          "thresholds_pct" : {
            "type" : "array",
            "items" : {
              "type" : "integer",
              "description" : "Configured policy value"
            }
          },
          "full_weight_targets" : {
            "type" : "array",
            "items" : {
              "type" : "number",
              "description" : "Configured policy value"
            }
          }
        },
        "required" : [ "source", "thresholds_pct", "full_weight_targets" ]
      },
      "ProfilePolicy_water" : {
        "type" : "object",
        "properties" : {
          "source" : {
            "type" : "string",
            "enum" : [ "ordinal", "raw_fraction" ]
          },
          "thresholds_pct" : {
            "type" : "array",
            "items" : {
              "type" : "integer",
              "description" : "Configured policy value"
            }
          },
          "full_weight_targets" : {
            "type" : "array",
            "items" : {
              "type" : "number",
              "description" : "Configured policy value"
            }
          }
        },
        "required" : [ "source", "thresholds_pct", "full_weight_targets" ]
      },
      "ProfilePolicy_tree" : {
        "type" : "object",
        "properties" : {
          "source" : {
            "type" : "string",
            "enum" : [ "ordinal", "raw_fraction" ]
          },
          "thresholds_pct" : {
            "type" : "array",
            "items" : {
              "type" : "integer",
              "description" : "Configured policy value"
            }
          },
          "full_weight_targets" : {
            "type" : "array",
            "items" : {
              "type" : "number",
              "description" : "Configured policy value"
            }
          }
        },
        "required" : [ "source", "thresholds_pct", "full_weight_targets" ]
      },
      "ProfilePolicy_accident" : {
        "type" : "object",
        "properties" : {
          "source" : {
            "type" : "string",
            "enum" : [ "ordinal", "raw_counts" ]
          },
          "severity_weights" : {
            "type" : "object",
            "properties" : {
              "fatal" : {
                "type" : "number",
                "description" : "Configured policy value"
              },
              "serious" : {
                "type" : "number",
                "description" : "Configured policy value"
              },
              "total" : {
                "type" : "number",
                "description" : "Configured policy value"
              }
            },
            "required" : [ "fatal", "serious", "total" ]
          },
          "predicate" : {
            "type" : "object",
            "properties" : {
              "min_fatal" : {
                "type" : "integer",
                "description" : "Configured policy value"
              },
              "min_serious" : {
                "type" : "integer",
                "description" : "Configured policy value"
              },
              "min_total" : {
                "type" : "integer",
                "description" : "Configured policy value"
              }
            },
            "required" : [ "min_fatal", "min_serious", "min_total" ]
          },
          "severity_threshold" : {
            "type" : "number",
            "description" : "Configured policy value"
          },
          "full_weight_targets" : {
            "type" : "array",
            "items" : {
              "type" : "number",
              "description" : "Configured policy value"
            }
          }
        },
        "required" : [ "source", "severity_weights", "predicate", "severity_threshold", "full_weight_targets" ]
      },
      "ProfilePolicy_ordinal" : {
        "type" : "object",
        "properties" : {
          "thresholds" : {
            "type" : "array",
            "items" : {
              "type" : "integer",
              "description" : "Configured policy value"
            }
          },
          "penalty_targets" : {
            "type" : "array",
            "items" : {
              "type" : "number",
              "description" : "Configured policy value"
            }
          },
          "reward_targets" : {
            "type" : "array",
            "items" : {
              "type" : "number",
              "description" : "Configured policy value"
            }
          }
        },
        "required" : [ "thresholds", "penalty_targets", "reward_targets" ]
      },
      "ProfilePolicy_incline" : {
        "type" : "object",
        "properties" : {
          "thresholds_pct" : {
            "type" : "array",
            "items" : {
              "type" : "integer",
              "description" : "Configured policy value"
            }
          },
          "full_weight_targets" : {
            "type" : "array",
            "items" : {
              "type" : "number",
              "description" : "Configured policy value"
            }
          }
        },
        "required" : [ "thresholds_pct", "full_weight_targets" ]
      },
      "ProfilePolicy_main_roads" : {
        "type" : "object",
        "properties" : {
          "full_weight_targets" : {
            "type" : "object",
            "properties" : {
              "trunk_primary" : {
                "type" : "number",
                "description" : "Configured policy value"
              },
              "secondary" : {
                "type" : "number",
                "description" : "Configured policy value"
              },
              "tertiary" : {
                "type" : "number",
                "description" : "Configured policy value"
              }
            },
            "required" : [ "trunk_primary", "secondary", "tertiary" ]
          }
        },
        "required" : [ "full_weight_targets" ]
      },
      "ProfileCatalogV1" : {
        "type" : "object",
        "additionalProperties" : {
          "$ref" : "#/components/schemas/ProfileV1"
        }
      },
      "ProfileCatalogV2" : {
        "type" : "object",
        "additionalProperties" : {
          "$ref" : "#/components/schemas/ProfileV2"
        }
      },
      "NavigationWaypoint" : {
        "type" : "object",
        "properties" : {
          "name" : {
            "type" : "string"
          },
          "location" : {
            "$ref" : "#/components/schemas/ResponseCoordinate"
          }
        },
        "required" : [ "name", "location" ]
      },
      "NavigationIntersection" : {
        "type" : "object",
        "properties" : {
          "location" : {
            "$ref" : "#/components/schemas/ResponseCoordinate"
          },
          "entry" : {
            "type" : "array",
            "items" : {
              "type" : "boolean"
            }
          },
          "bearings" : {
            "type" : "array",
            "items" : {
              "type" : "integer",
              "description" : "Bearing in degrees clockwise from north"
            }
          },
          "in" : {
            "type" : "integer",
            "description" : "Index into bearings for the incoming edge"
          },
          "out" : {
            "type" : "integer",
            "description" : "Index into bearings for the outgoing edge"
          }
        },
        "required" : [ "location", "entry", "bearings" ]
      },
      "NavigationManeuver" : {
        "type" : "object",
        "properties" : {
          "bearing_before" : {
            "type" : "integer",
            "description" : "Degrees clockwise from north"
          },
          "bearing_after" : {
            "type" : "integer",
            "description" : "Degrees clockwise from north"
          },
          "location" : {
            "$ref" : "#/components/schemas/ResponseCoordinate"
          },
          "type" : {
            "type" : "string",
            "enum" : [ "depart", "arrive", "turn", "roundabout" ]
          },
          "instruction" : {
            "type" : "string"
          },
          "modifier" : {
            "type" : "string"
          },
          "exit" : {
            "type" : "integer",
            "description" : "Roundabout exit number"
          }
        },
        "required" : [ "bearing_before", "bearing_after", "location", "type", "instruction" ]
      },
      "NavigationVoiceInstruction" : {
        "type" : "object",
        "properties" : {
          "distanceAlongGeometry" : {
            "type" : "number",
            "description" : "Meters before the upcoming maneuver"
          },
          "announcement" : {
            "type" : "string"
          },
          "ssmlAnnouncement" : {
            "type" : "string"
          }
        },
        "required" : [ "distanceAlongGeometry", "announcement", "ssmlAnnouncement" ]
      },
      "NavigationBannerComponent" : {
        "type" : "object",
        "properties" : {
          "text" : {
            "type" : "string"
          },
          "type" : {
            "type" : "string",
            "enum" : [ "text" ]
          }
        },
        "required" : [ "text", "type" ]
      },
      "NavigationBannerContent" : {
        "type" : "object",
        "properties" : {
          "text" : {
            "type" : "string"
          },
          "type" : {
            "type" : "string",
            "enum" : [ "turn", "arrive", "roundabout" ]
          },
          "components" : {
            "type" : "array",
            "items" : {
              "$ref" : "#/components/schemas/NavigationBannerComponent"
            }
          },
          "modifier" : {
            "type" : "string"
          },
          "degrees" : {
            "anyOf" : [ {
              "type" : "number",
              "description" : "Roundabout turn angle in degrees"
            }, {
              "type" : "null"
            } ]
          }
        },
        "required" : [ "text", "type", "components" ]
      },
      "NavigationBannerInstruction" : {
        "type" : "object",
        "properties" : {
          "distanceAlongGeometry" : {
            "type" : "number",
            "description" : "Meters before the upcoming maneuver"
          },
          "primary" : {
            "$ref" : "#/components/schemas/NavigationBannerContent"
          },
          "secondary" : {
            "type" : "null"
          },
          "sub" : {
            "$ref" : "#/components/schemas/NavigationBannerContent"
          }
        },
        "required" : [ "distanceAlongGeometry", "primary", "secondary" ]
      },
      "NavigationStep" : {
        "type" : "object",
        "properties" : {
          "intersections" : {
            "type" : "array",
            "items" : {
              "$ref" : "#/components/schemas/NavigationIntersection"
            }
          },
          "driving_side" : {
            "type" : "string",
            "enum" : [ "right" ]
          },
          "geometry" : {
            "type" : "string",
            "description" : "Encoded polyline6, precision 1e-6 degrees, 2D; not GeoJSON or polyline5."
          },
          "mode" : {
            "type" : "string",
            "enum" : [ "walking", "cycling", "ferry" ]
          },
          "maneuver" : {
            "$ref" : "#/components/schemas/NavigationManeuver"
          },
          "weight" : {
            "type" : "number",
            "description" : "Converter step weight, currently distance in meters"
          },
          "duration" : {
            "type" : "number",
            "description" : "Seconds"
          },
          "name" : {
            "type" : "string"
          },
          "distance" : {
            "type" : "number",
            "description" : "Meters"
          },
          "voiceInstructions" : {
            "type" : "array",
            "items" : {
              "$ref" : "#/components/schemas/NavigationVoiceInstruction"
            }
          },
          "bannerInstructions" : {
            "type" : "array",
            "items" : {
              "$ref" : "#/components/schemas/NavigationBannerInstruction"
            }
          }
        },
        "required" : [ "intersections", "driving_side", "geometry", "mode", "maneuver", "weight", "duration", "name", "distance", "voiceInstructions", "bannerInstructions" ]
      },
      "NavigationLeg" : {
        "type" : "object",
        "properties" : {
          "steps" : {
            "type" : "array",
            "items" : {
              "$ref" : "#/components/schemas/NavigationStep"
            }
          },
          "summary" : {
            "type" : "string"
          },
          "weight" : {
            "type" : "number",
            "description" : "Converter leg weight, currently time in seconds"
          },
          "duration" : {
            "type" : "number",
            "description" : "Seconds"
          },
          "distance" : {
            "type" : "number",
            "description" : "Meters"
          },
          "annotation" : {
            "type" : "object",
            "properties" : {
              "maxspeed" : {
                "type" : "array",
                "items" : {
                  "type" : "object",
                  "properties" : {
                    "speed" : {
                      "type" : "number",
                      "description" : "Speed in the stated unit"
                    },
                    "unit" : {
                      "type" : "string",
                      "enum" : [ "km/h", "mph" ]
                    }
                  },
                  "required" : [ "speed", "unit" ]
                }
              }
            },
            "required" : [ "maxspeed" ]
          }
        },
        "required" : [ "steps", "summary", "weight", "duration", "distance" ]
      },
      "NavigationRoute" : {
        "type" : "object",
        "properties" : {
          "geometry" : {
            "type" : "string",
            "description" : "Encoded polyline6, precision 1e-6 degrees, 2D; not GeoJSON or polyline5."
          },
          "legs" : {
            "type" : "array",
            "items" : {
              "$ref" : "#/components/schemas/NavigationLeg"
            }
          },
          "weight_name" : {
            "type" : "string",
            "enum" : [ "routability" ]
          },
          "weight" : {
            "type" : "number",
            "description" : "Engine routing weight; not travel time"
          },
          "duration" : {
            "type" : "number",
            "description" : "Seconds"
          },
          "distance" : {
            "type" : "number",
            "description" : "Meters"
          },
          "voiceLocale" : {
            "type" : "string"
          }
        },
        "required" : [ "geometry", "legs", "weight_name", "weight", "duration", "distance", "voiceLocale" ]
      },
      "NavigationSuccess" : {
        "type" : "object",
        "properties" : {
          "code" : {
            "type" : "string",
            "enum" : [ "Ok" ]
          },
          "uuid" : {
            "type" : "string"
          },
          "resolvedBucket" : {
            "$ref" : "#/components/schemas/ResolvedBucket"
          },
          "routes" : {
            "type" : "array",
            "items" : {
              "$ref" : "#/components/schemas/NavigationRoute"
            },
            "minItems" : 1
          },
          "waypoints" : {
            "type" : "array",
            "items" : {
              "$ref" : "#/components/schemas/NavigationWaypoint"
            }
          }
        },
        "required" : [ "code", "uuid", "resolvedBucket", "routes", "waypoints" ]
      },
      "NavigationNoRoute" : {
        "type" : "object",
        "properties" : {
          "code" : {
            "type" : "string",
            "enum" : [ "NoRoute" ]
          },
          "message" : {
            "type" : "string"
          },
          "resolvedBucket" : {
            "$ref" : "#/components/schemas/ResolvedBucket"
          },
          "routes" : {
            "type" : "array",
            "items" : {
              "$ref" : "#/components/schemas/NavigationRoute"
            },
            "maxItems" : 0
          },
          "waypoints" : {
            "type" : "array",
            "items" : {
              "$ref" : "#/components/schemas/NavigationWaypoint"
            },
            "maxItems" : 0
          }
        },
        "required" : [ "code", "message", "resolvedBucket", "routes", "waypoints" ]
      },
      "NavigationResponse" : {
        "oneOf" : [ {
          "$ref" : "#/components/schemas/NavigationSuccess"
        }, {
          "$ref" : "#/components/schemas/NavigationNoRoute"
        } ]
      },
      "NavigationPlanResponse" : {
        "type" : "object",
        "properties" : {
          "profiles" : {
            "type" : "object",
            "additionalProperties" : {
              "$ref" : "#/components/schemas/NavigationResponse"
            },
            "minProperties" : 1
          }
        },
        "required" : [ "profiles" ],
        "description" : "Automatic mode: baseline plus qualifying active-profile alternatives on the baseline graph. Explicit profiles: one unfiltered document per requested ID, including NoRoute."
      },
      "NavigationValidationError" : {
        "type" : "object",
        "properties" : {
          "code" : {
            "type" : "string",
            "enum" : [ "InvalidInput" ]
          },
          "message" : {
            "type" : "string"
          }
        },
        "required" : [ "code", "message" ]
      },
      "NavigationInternalError" : {
        "type" : "object",
        "properties" : {
          "code" : {
            "type" : "string",
            "enum" : [ "InternalError" ]
          },
          "message" : {
            "type" : "string"
          }
        },
        "required" : [ "code", "message" ]
      },
      "JsonDecodingError" : {
        "type" : "object",
        "properties" : {
          "code" : {
            "type" : "integer",
            "enum" : [ 400 ]
          },
          "message" : {
            "type" : "string"
          }
        },
        "required" : [ "code", "message" ],
        "description" : "Framework response before routing validation when JSON cannot be decoded. Unlike routing errors, code is the numeric HTTP status."
      }
    }
  },
  "security" : [ ]
}