{
  "openapi" : "3.1.0",
  "info" : {
    "title" : "LiveMap Routing — v2 Navigation",
    "description" : "v2 turn-by-turn navigation: emits OSRM-compatible JSON for clients such as Ferrostar.",
    "version" : "11.0-livemap-1.1-SNAPSHOT"
  },
  "tags" : [ {
    "name" : "Navigation v2",
    "description" : "Turn-by-turn navigation. Emits OSRM-compatible JSON (GraphHopper's type=mapbox output) for clients such as Ferrostar; /route takes a single product profile, /plan takes several."
  } ],
  "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" : "openApi",
        "responses" : {
          "200" : {
            "description" : "OpenAPI 3.1 JSON document",
            "content" : {
              "application/json" : {
                "schema" : { }
              }
            }
          }
        }
      }
    },
    "/api/v2/routing/plan" : {
      "post" : {
        "tags" : [ "Navigation v2" ],
        "summary" : "Calculate one navigable route per profile (pre-trip plan)",
        "description" : "Routes several catalog product profiles in one request and returns a profile-keyed wrapper of standalone OSRM-compatible JSON documents — one per profile — for pre-trip search/alternatives. The client builds a chooser from the wrapper and hands the picked sub-response to the navigation client verbatim. Unsupported top-level request fields are stripped (and logged) before mapping.",
        "operationId" : "plan",
        "requestBody" : {
          "content" : {
            "application/json" : {
              "schema" : {
                "$ref" : "#/components/schemas/LivemapNavigationPlanRequest"
              }
            }
          },
          "required" : true
        },
        "responses" : {
          "200" : {
            "description" : "Profile-keyed wrapper {\"profiles\": {<name>: {<OSRM-compatible response>}}}. Returned whenever the request is valid, even if some or all profiles are NoRoute — each sub-response carries its own code.",
            "content" : {
              "application/json" : {
                "schema" : {
                  "additionalProperties" : true
                }
              }
            }
          },
          "400" : {
            "description" : "Invalid request body, profile, or bucket (code InvalidInput)",
            "content" : {
              "application/json" : {
                "schema" : {
                  "$ref" : "#/components/schemas/MapboxError"
                }
              }
            }
          },
          "500" : {
            "description" : "Unexpected server error (code InternalError)",
            "content" : {
              "application/json" : {
                "schema" : {
                  "$ref" : "#/components/schemas/MapboxError"
                }
              }
            }
          }
        }
      }
    },
    "/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.",
        "operationId" : "route",
        "requestBody" : {
          "content" : {
            "application/json" : {
              "schema" : {
                "$ref" : "#/components/schemas/LivemapNavigationRequest"
              }
            }
          },
          "required" : true
        },
        "responses" : {
          "200" : {
            "description" : "OSRM-compatible response (code, routes[], waypoints[]). 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" : { }
              }
            }
          },
          "400" : {
            "description" : "Invalid request body, profile, or bucket (code InvalidInput)",
            "content" : {
              "application/json" : {
                "schema" : {
                  "$ref" : "#/components/schemas/MapboxError"
                }
              }
            }
          },
          "500" : {
            "description" : "Unexpected server error (code InternalError)",
            "content" : {
              "application/json" : {
                "schema" : {
                  "$ref" : "#/components/schemas/MapboxError"
                }
              }
            }
          }
        }
      }
    }
  },
  "components" : {
    "schemas" : {
      "LivemapNavigationPlanRequest" : {
        "description" : "v2 multi-profile plan request. Routes each requested catalog profile and returns one standalone OSRM-compatible document per profile.",
        "properties" : {
          "profiles" : {
            "type" : "array",
            "description" : "Product profiles to route, e.g. [\"foot_fast\", \"foot_safe\"]. Each becomes a key in the response wrapper.",
            "example" : [ "foot_fast", "foot_safe" ],
            "items" : {
              "type" : "string",
              "description" : "Product profiles to route, e.g. [\"foot_fast\", \"foot_safe\"]. Each becomes a key in the response wrapper.",
              "example" : "[\"foot_fast\",\"foot_safe\"]"
            }
          },
          "points" : {
            "type" : "array",
            "description" : "Ordered waypoints as [longitude, latitude] pairs (at least 2).",
            "example" : [ [ 8.5417, 47.3769 ], [ 8.55, 47.38 ] ],
            "items" : {
              "type" : "array",
              "description" : "Ordered waypoints as [longitude, latitude] pairs (at least 2).",
              "example" : [ [ 8.5417, 47.3769 ], [ 8.55, 47.38 ] ],
              "items" : {
                "type" : "number",
                "format" : "double",
                "description" : "Ordered waypoints as [longitude, latitude] pairs (at least 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", "profiles" ]
      },
      "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 alternative paths GraphHopper may return.",
            "example" : 2,
            "minimum" : 1
          },
          "max_weight_factor" : {
            "type" : "number",
            "format" : "double",
            "description" : "Maximum alternative weight factor. Must be greater than 1.",
            "example" : 1.4,
            "minimum" : 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,
            "minimum" : 0
          }
        }
      },
      "LivemapNavigationRequest" : {
        "description" : "v2 navigation request. Unlike v1, takes a single product profile per request.",
        "properties" : {
          "profile" : {
            "type" : "string",
            "description" : "Single product profile to route, e.g. foot_fast, foot_safe, foot_calm.",
            "example" : "foot_safe"
          },
          "points" : {
            "type" : "array",
            "description" : "Ordered waypoints as [longitude, latitude] pairs (at least 2).",
            "example" : [ [ 8.5417, 47.3769 ], [ 8.55, 47.38 ] ],
            "items" : {
              "type" : "array",
              "description" : "A single [longitude, latitude] pair.",
              "items" : {
                "type" : "number",
                "format" : "double",
                "description" : "A single [longitude, latitude] pair."
              }
            },
            "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" : [ "profile" ]
      }
    }
  }
}