{
  "openapi": "3.1.0",
  "info": {
    "title": "JustRouting API",
    "version": "v1",
    "description": "OSRM-compatible routing services (route, table, match, trip, nearest) and a hosted VROOM vehicle routing solver (optimize). All requests require a Bearer API key. Coordinates use `lng,lat` order and must be within a single country (Southeast Asia).",
    "contact": {
      "email": "hello@justrouting.tech",
      "name": "JustRouting",
      "url": "https://justrouting.tech"
    }
  },
  "servers": [
    {
      "url": "https://api.justrouting.tech",
      "description": "Production"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "tags": [
    {
      "name": "route",
      "description": "Directions between coordinates"
    },
    {
      "name": "table",
      "description": "NxN travel time/distance matrix"
    },
    {
      "name": "match",
      "description": "Map matching for GPS traces"
    },
    {
      "name": "trip",
      "description": "Traveling salesman optimization"
    },
    {
      "name": "nearest",
      "description": "Snap a coordinate to the road network"
    },
    {
      "name": "optimize",
      "description": "Hosted VROOM vehicle routing solver"
    },
    {
      "name": "geocode",
      "description": "Forward geocoding: place name or address into coordinates"
    }
  ],
  "paths": {
    "/route/v1/{profile}/{coordinates}": {
      "get": {
        "tags": [
          "route"
        ],
        "summary": "Find the fastest route between coordinates in order",
        "operationId": "getRoute",
        "x-mint": {
          "metadata": {
            "title": "route",
            "sidebarTitle": "route",
            "description": "Find the fastest route between coordinates in order"
          }
        },
        "parameters": [
          {
            "name": "profile",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "driving",
                "motorcycle"
              ]
            },
            "description": "Vehicle profile. `driving` for cars, `motorcycle` for motorcycles."
          },
          {
            "name": "coordinates",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Semicolon-separated `{lng},{lat}` pairs, up to 100, visited in order. All coordinates must be in the same country.",
            "example": "103.708362,1.357371;103.984748,1.352212"
          },
          {
            "$ref": "#/components/parameters/Overview"
          },
          {
            "$ref": "#/components/parameters/Steps"
          },
          {
            "$ref": "#/components/parameters/Alternatives"
          },
          {
            "$ref": "#/components/parameters/Geometries"
          },
          {
            "$ref": "#/components/parameters/Annotations"
          },
          {
            "$ref": "#/components/parameters/ContinueStraight"
          },
          {
            "$ref": "#/components/parameters/Bearings"
          },
          {
            "$ref": "#/components/parameters/Radiuses"
          },
          {
            "$ref": "#/components/parameters/Hints"
          },
          {
            "$ref": "#/components/parameters/Exclude"
          },
          {
            "$ref": "#/components/parameters/Approaches"
          },
          {
            "$ref": "#/components/parameters/Snapping"
          },
          {
            "$ref": "#/components/parameters/GenerateHints"
          },
          {
            "$ref": "#/components/parameters/SkipWaypoints"
          },
          {
            "$ref": "#/components/parameters/Waypoints"
          }
        ],
        "responses": {
          "200": {
            "description": "Route found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RouteResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OsrmError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthError"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining today"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          }
        }
      }
    },
    "/table/v1/{profile}/{coordinates}": {
      "get": {
        "tags": [
          "table"
        ],
        "summary": "Compute durations/distances between all pairs of coordinates",
        "operationId": "getTable",
        "x-mint": {
          "metadata": {
            "title": "table",
            "sidebarTitle": "table",
            "description": "Compute durations/distances between all pairs of coordinates"
          }
        },
        "parameters": [
          {
            "name": "profile",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "driving",
                "motorcycle"
              ]
            }
          },
          {
            "name": "coordinates",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Semicolon-separated `{lng},{lat}` pairs, all in the same country."
          },
          {
            "$ref": "#/components/parameters/Sources"
          },
          {
            "$ref": "#/components/parameters/Destinations"
          },
          {
            "name": "annotations",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "duration",
                "distance",
                "duration,distance"
              ],
              "default": "duration"
            },
            "description": "Which table(s) to return."
          },
          {
            "name": "fallback_speed",
            "in": "query",
            "schema": {
              "type": "number",
              "exclusiveMinimum": 0
            },
            "description": "For unreachable pairs, estimate duration from crow-fly distance at this speed (km/h equivalent meters per second ratio)."
          },
          {
            "name": "fallback_coordinate",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "input",
                "snapped"
              ],
              "default": "input"
            }
          },
          {
            "name": "scale_factor",
            "in": "query",
            "schema": {
              "type": "number",
              "exclusiveMinimum": 0
            },
            "description": "Scale all durations by this factor."
          },
          {
            "$ref": "#/components/parameters/Bearings"
          },
          {
            "$ref": "#/components/parameters/Radiuses"
          },
          {
            "$ref": "#/components/parameters/Hints"
          },
          {
            "$ref": "#/components/parameters/Approaches"
          },
          {
            "$ref": "#/components/parameters/Exclude"
          },
          {
            "$ref": "#/components/parameters/Snapping"
          },
          {
            "$ref": "#/components/parameters/GenerateHints"
          },
          {
            "$ref": "#/components/parameters/SkipWaypoints"
          }
        ],
        "responses": {
          "200": {
            "description": "Matrix computed",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TableResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OsrmError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthError"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          }
        }
      }
    },
    "/match/v1/{profile}/{coordinates}": {
      "get": {
        "tags": [
          "match"
        ],
        "summary": "Snap a GPS trace to the road network",
        "operationId": "getMatch",
        "x-mint": {
          "metadata": {
            "title": "match",
            "sidebarTitle": "match",
            "description": "Snap a GPS trace to the road network"
          }
        },
        "parameters": [
          {
            "name": "profile",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "driving",
                "motorcycle"
              ]
            }
          },
          {
            "name": "coordinates",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Trace points `{lng},{lat};...` in time order."
          },
          {
            "name": "timestamps",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "UNIX timestamps (seconds) for each point, monotonically increasing, one per coordinate."
          },
          {
            "name": "radiuses",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "GPS accuracy in meters per point (standard deviation). Use device-reported accuracy when available."
          },
          {
            "$ref": "#/components/parameters/Steps"
          },
          {
            "$ref": "#/components/parameters/Geometries"
          },
          {
            "$ref": "#/components/parameters/Overview"
          },
          {
            "name": "gaps",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "split",
                "ignore"
              ],
              "default": "split"
            },
            "description": "Whether large timestamp gaps split the trace into multiple matchings."
          },
          {
            "name": "tidy",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            },
            "description": "Allow removing noisy points to improve matching quality."
          },
          {
            "$ref": "#/components/parameters/Bearings"
          },
          {
            "$ref": "#/components/parameters/Hints"
          },
          {
            "$ref": "#/components/parameters/Approaches"
          },
          {
            "$ref": "#/components/parameters/Exclude"
          },
          {
            "$ref": "#/components/parameters/Snapping"
          },
          {
            "$ref": "#/components/parameters/GenerateHints"
          },
          {
            "$ref": "#/components/parameters/SkipWaypoints"
          },
          {
            "$ref": "#/components/parameters/Annotations"
          },
          {
            "$ref": "#/components/parameters/Waypoints"
          }
        ],
        "responses": {
          "200": {
            "description": "Trace matched",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MatchResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OsrmError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthError"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          }
        }
      }
    },
    "/trip/v1/{profile}/{coordinates}": {
      "get": {
        "tags": [
          "trip"
        ],
        "summary": "Solve the traveling salesman problem for the given coordinates",
        "operationId": "getTrip",
        "x-mint": {
          "metadata": {
            "title": "trip",
            "sidebarTitle": "trip",
            "description": "Solve the traveling salesman problem for the given coordinates"
          }
        },
        "parameters": [
          {
            "name": "profile",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "driving",
                "motorcycle"
              ]
            }
          },
          {
            "name": "coordinates",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "roundtrip",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": true
            }
          },
          {
            "name": "source",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "any",
                "first"
              ],
              "default": "any"
            }
          },
          {
            "name": "destination",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": [
                "any",
                "last"
              ],
              "default": "any"
            }
          },
          {
            "$ref": "#/components/parameters/Steps"
          },
          {
            "$ref": "#/components/parameters/Geometries"
          },
          {
            "$ref": "#/components/parameters/Overview"
          },
          {
            "$ref": "#/components/parameters/Bearings"
          },
          {
            "$ref": "#/components/parameters/Radiuses"
          },
          {
            "$ref": "#/components/parameters/Hints"
          },
          {
            "$ref": "#/components/parameters/Approaches"
          },
          {
            "$ref": "#/components/parameters/Exclude"
          },
          {
            "$ref": "#/components/parameters/Snapping"
          },
          {
            "$ref": "#/components/parameters/GenerateHints"
          },
          {
            "$ref": "#/components/parameters/SkipWaypoints"
          },
          {
            "$ref": "#/components/parameters/Annotations"
          }
        ],
        "responses": {
          "200": {
            "description": "Trip found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TripResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OsrmError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthError"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          }
        }
      }
    },
    "/nearest/v1/{profile}/{coordinates}": {
      "get": {
        "tags": [
          "nearest"
        ],
        "summary": "Snap a single coordinate to the nearest routable segments",
        "operationId": "getNearest",
        "x-mint": {
          "metadata": {
            "title": "nearest",
            "sidebarTitle": "nearest",
            "description": "Snap a single coordinate to the nearest routable segments"
          }
        },
        "parameters": [
          {
            "name": "profile",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "driving",
                "motorcycle"
              ]
            }
          },
          {
            "name": "coordinates",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "A single `{lng},{lat}` pair."
          },
          {
            "name": "number",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            },
            "description": "Number of nearest segments to return."
          },
          {
            "$ref": "#/components/parameters/Bearings"
          },
          {
            "$ref": "#/components/parameters/Radiuses"
          },
          {
            "$ref": "#/components/parameters/Hints"
          },
          {
            "$ref": "#/components/parameters/Approaches"
          },
          {
            "$ref": "#/components/parameters/Exclude"
          },
          {
            "$ref": "#/components/parameters/Snapping"
          },
          {
            "$ref": "#/components/parameters/GenerateHints"
          },
          {
            "$ref": "#/components/parameters/SkipWaypoints"
          }
        ],
        "responses": {
          "200": {
            "description": "Snapped segments",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/NearestResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad request",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OsrmError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthError"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          }
        }
      }
    },
    "/optimize": {
      "post": {
        "tags": [
          "optimize"
        ],
        "summary": "Solve a vehicle routing problem",
        "operationId": "solveOptimize",
        "x-mint": {
          "metadata": {
            "title": "optimize",
            "sidebarTitle": "optimize",
            "description": "Solve a vehicle routing problem"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/VroomInput"
              },
              "examples": {
                "twoVehiclesSixJobs": {
                  "summary": "Two vehicles, six jobs",
                  "value": {
                    "vehicles": [
                      {
                        "id": 1,
                        "profile": "car",
                        "start": [
                          103.79234106,
                          1.32463108
                        ],
                        "end": [
                          103.79234106,
                          1.32463108
                        ]
                      },
                      {
                        "id": 2,
                        "profile": "car",
                        "start": [
                          103.82324228,
                          1.32408622
                        ],
                        "end": [
                          103.82324228,
                          1.32408622
                        ]
                      }
                    ],
                    "jobs": [
                      {
                        "id": 1,
                        "location": [
                          103.79751693,
                          1.31035001
                        ]
                      },
                      {
                        "id": 2,
                        "location": [
                          103.78432387,
                          1.31490148
                        ]
                      },
                      {
                        "id": 3,
                        "location": [
                          103.79763397,
                          1.31980519
                        ]
                      },
                      {
                        "id": 4,
                        "location": [
                          103.81234512,
                          1.31824846
                        ]
                      },
                      {
                        "id": 5,
                        "location": [
                          103.82152987,
                          1.30984208
                        ]
                      },
                      {
                        "id": 6,
                        "location": [
                          103.83701939,
                          1.32143977
                        ]
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Problem solved",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VroomOutput"
                }
              }
            }
          },
          "400": {
            "description": "Invalid input (code 2) \u2014 details in the `error` field",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VroomError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthError"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "500": {
            "description": "Internal error (code 1) — details in the `error` field",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/VroomError"
                }
              }
            }
          }
        }
      }
    },
    "/geocode/v1/search": {
      "get": {
        "tags": [
          "geocode"
        ],
        "summary": "Find a place by name or address and get its coordinates",
        "operationId": "getGeocode",
        "x-mint": {
          "metadata": {
            "title": "geocode",
            "sidebarTitle": "geocode",
            "description": "Find a place by name or address and get its coordinates"
          }
        },
        "parameters": [
          {
            "name": "text",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Free-form address to search, e.g. `Marina Bay Sands, Singapore`. Mutually exclusive with the structured fields."
          },
          {
            "name": "name",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Name of the place, e.g. `Marina Bay Sands`."
          },
          {
            "name": "housenumber",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "House or building number, e.g. `10`."
          },
          {
            "name": "street",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Street name, e.g. `Bayfront Avenue`."
          },
          {
            "name": "postcode",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Postal code, e.g. `018956`."
          },
          {
            "name": "city",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "City or locality, e.g. `Singapore`."
          },
          {
            "name": "state",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "State or region."
          },
          {
            "name": "country",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Country, e.g. `Singapore` — the strongest disambiguator for common, abbreviated, or misspelled names."
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 5
            },
            "description": "Maximum number of results to return."
          },
          {
            "name": "offset",
            "in": "query",
            "schema": {
              "type": "integer",
              "default": 0
            },
            "description": "Skip the first `offset` results before applying `limit`."
          },
          {
            "name": "filter",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Restrict results, e.g. `countrycode:sg`; repeatable, all filters apply."
          },
          {
            "name": "bias",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Steer results toward a location, e.g. `proximity:103.8,1.3`; adds a `distance` field to each result."
          },
          {
            "name": "type",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Restrict to a feature type, e.g. `street` or `city`."
          },
          {
            "name": "lang",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Preferred language for results, e.g. `en`."
          },
          {
            "name": "format",
            "in": "query",
            "schema": {
              "type": "string",
              "default": "json"
            },
            "description": "Response format; `json` is the only documented value."
          }
        ],
        "responses": {
          "200": {
            "description": "Matching places, ordered by relevance",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GeocodeResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request parameters; the upstream error body is passed through",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UpstreamError"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/AuthError"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited",
            "headers": {
              "Retry-After": {
                "schema": {
                  "type": "integer"
                },
                "description": "Seconds to wait before retrying"
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                },
                "description": "Requests remaining today"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/RateLimitError"
                }
              }
            }
          },
          "502": {
            "description": "Geocoding provider unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UpstreamError"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "API key created in the JustRouting dashboard."
      }
    },
    "parameters": {
      "Overview": {
        "name": "overview",
        "in": "query",
        "schema": {
          "type": "string",
          "enum": [
            "full",
            "simplified",
            "false",
            "by_legs"
          ],
          "default": "simplified"
        },
        "description": "How much route geometry to return."
      },
      "Steps": {
        "name": "steps",
        "in": "query",
        "schema": {
          "type": "boolean",
          "default": false
        },
        "description": "Return turn-by-turn steps."
      },
      "Alternatives": {
        "name": "alternatives",
        "in": "query",
        "schema": {
          "type": "string"
        },
        "description": "`true` for one alternative, or a number for up to that many (not guaranteed)."
      },
      "Geometries": {
        "name": "geometries",
        "in": "query",
        "schema": {
          "type": "string",
          "enum": [
            "polyline",
            "polyline6",
            "geojson"
          ],
          "default": "polyline"
        },
        "description": "Geometry encoding of the response."
      },
      "Annotations": {
        "name": "annotations",
        "in": "query",
        "schema": {
          "type": "string"
        },
        "description": "Per-coordinate metadata: `true`, or a comma list of `distance`, `duration`, `speed`, `weight`, `nodes`, `datasources`."
      },
      "ContinueStraight": {
        "name": "continue_straight",
        "in": "query",
        "schema": {
          "type": "string",
          "enum": [
            "default",
            "true",
            "false"
          ],
          "default": "default"
        },
        "description": "Force straight continuation at waypoints, constraining U-turns."
      },
      "Bearings": {
        "name": "bearings",
        "in": "query",
        "schema": {
          "type": "string"
        },
        "description": "`{bearing},{range};...` per coordinate, e.g. `0,20` = north \u00b120\u00b0."
      },
      "Radiuses": {
        "name": "radiuses",
        "in": "query",
        "schema": {
          "type": "string"
        },
        "description": "Snapping radius in meters per coordinate, or `unlimited`."
      },
      "Hints": {
        "name": "hints",
        "in": "query",
        "schema": {
          "type": "string"
        },
        "description": "Base64 hints from a previous response to speed up snapping."
      },
      "Exclude": {
        "name": "exclude",
        "in": "query",
        "schema": {
          "type": "string"
        },
        "description": "Road classes to avoid (additive list), e.g. `motorway`."
      },
      "Approaches": {
        "name": "approaches",
        "in": "query",
        "schema": {
          "type": "string"
        },
        "description": "Restrict the road direction at each waypoint: `curb` / `opposite` / `unrestricted` (default), e.g. `curb;opposite`."
      },
      "Snapping": {
        "name": "snapping",
        "in": "query",
        "schema": {
          "type": "string",
          "enum": [
            "default",
            "any"
          ],
          "default": "default"
        },
        "description": "`default` avoids edges that cannot be used as start/end points; `any` snaps to any edge in the graph."
      },
      "GenerateHints": {
        "name": "generate_hints",
        "in": "query",
        "schema": {
          "type": "boolean",
          "default": true
        },
        "description": "Add a `hint` to response waypoints for reuse in later requests."
      },
      "SkipWaypoints": {
        "name": "skip_waypoints",
        "in": "query",
        "schema": {
          "type": "boolean",
          "default": false
        },
        "description": "Remove waypoints from the response (still calculated, not serialized)."
      },
      "Waypoints": {
        "name": "waypoints",
        "in": "query",
        "schema": {
          "type": "string"
        },
        "description": "Indices of input coordinates to treat as waypoints in the response, e.g. `0;3`. Default is all input coordinates."
      },
      "Sources": {
        "name": "sources",
        "in": "query",
        "schema": {
          "type": "string"
        },
        "description": "Source indices `{i};{j};...` or `all` (default)."
      },
      "Destinations": {
        "name": "destinations",
        "in": "query",
        "schema": {
          "type": "string"
        },
        "description": "Destination indices `{i};{j};...` or `all` (default)."
      }
    },
    "schemas": {
      "Waypoint": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Street name the coordinate snapped to."
          },
          "location": {
            "type": "array",
            "items": {
              "type": "number"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "Snapped position as `[lng, lat]`."
          },
          "distance": {
            "type": "number",
            "description": "Snapping offset in meters."
          },
          "hint": {
            "type": "string",
            "description": "Opaque segment identifier, reusable as the `hints` parameter."
          },
          "nodes": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "description": "OSM node ids of the segment."
          }
        }
      },
      "StepManeuver": {
        "type": "object",
        "properties": {
          "location": {
            "type": "array",
            "items": {
              "type": "number"
            },
            "description": "[lng, lat]"
          },
          "bearing_before": {
            "type": "integer"
          },
          "bearing_after": {
            "type": "integer"
          },
          "type": {
            "type": "string",
            "description": "turn, new name, depart, arrive, merge, on ramp, off ramp, fork, end of road, continue, roundabout, rotary, roundabout turn, notification, exit roundabout, exit rotary"
          },
          "modifier": {
            "type": "string",
            "enum": [
              "uturn",
              "sharp right",
              "right",
              "slight right",
              "straight",
              "slight left",
              "left",
              "sharp left"
            ]
          },
          "exit": {
            "type": "integer",
            "description": "Number of the roundabout/rotary exit to take; absent when the destination is on the roundabout."
          }
        }
      },
      "Lane": {
        "type": "object",
        "properties": {
          "indications": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "none",
                "uturn",
                "sharp right",
                "right",
                "slight right",
                "straight",
                "slight left",
                "left",
                "sharp left"
              ]
            },
            "description": "Markings for the lane; a lane can have several."
          },
          "valid": {
            "type": "boolean",
            "description": "Whether the lane is a valid choice in the current maneuver."
          }
        }
      },
      "Intersection": {
        "type": "object",
        "properties": {
          "location": {
            "type": "array",
            "items": {
              "type": "number"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "[lng, lat]"
          },
          "bearings": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "description": "Bearings of all roads at the intersection, 0-359 (0 = true north)."
          },
          "classes": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Road classes of the exiting roads."
          },
          "entry": {
            "type": "array",
            "items": {
              "type": "boolean"
            },
            "description": "Flags 1:1 with bearings; true means the road can be entered on a valid route."
          },
          "in": {
            "type": "integer",
            "description": "Index into bearings of the road you came from; absent for depart."
          },
          "out": {
            "type": "integer",
            "description": "Index into bearings of the road you take; absent for arrive."
          },
          "lanes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Lane"
            },
            "description": "Available turn lanes; absent when there is no lane data."
          }
        }
      },
      "RouteStep": {
        "type": "object",
        "properties": {
          "distance": {
            "type": "number",
            "description": "Meters."
          },
          "duration": {
            "type": "number",
            "description": "Seconds."
          },
          "weight": {
            "type": "number"
          },
          "geometry": {
            "type": "string",
            "description": "Polyline geometry."
          },
          "name": {
            "type": "string"
          },
          "ref": {
            "type": "string"
          },
          "pronunciation": {
            "type": "string",
            "description": "IPA phonetic transcription of the name."
          },
          "destinations": {
            "type": "string",
            "description": "Destinations of the way."
          },
          "exits": {
            "type": "string",
            "description": "Exit numbers or names of the way."
          },
          "mode": {
            "type": "string"
          },
          "driving_side": {
            "type": "string",
            "enum": [
              "left",
              "right"
            ]
          },
          "rotary_name": {
            "type": "string"
          },
          "rotary_pronunciation": {
            "type": "string"
          },
          "maneuver": {
            "$ref": "#/components/schemas/StepManeuver"
          },
          "intersections": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Intersection"
            }
          }
        }
      },
      "RouteLeg": {
        "type": "object",
        "properties": {
          "distance": {
            "type": "number",
            "description": "Meters."
          },
          "duration": {
            "type": "number",
            "description": "Seconds."
          },
          "weight": {
            "type": "number"
          },
          "summary": {
            "type": "string"
          },
          "steps": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RouteStep"
            }
          },
          "annotation": {
            "$ref": "#/components/schemas/Annotation"
          }
        }
      },
      "Annotation": {
        "type": "object",
        "properties": {
          "distance": {
            "type": "array",
            "items": {
              "type": "number"
            }
          },
          "duration": {
            "type": "array",
            "items": {
              "type": "number"
            }
          },
          "weight": {
            "type": "array",
            "items": {
              "type": "number"
            }
          },
          "speed": {
            "type": "array",
            "items": {
              "type": "number"
            }
          },
          "nodes": {
            "type": "array",
            "items": {
              "type": "integer"
            }
          },
          "datasources": {
            "type": "array",
            "items": {
              "type": "integer"
            }
          },
          "metadata": {
            "type": "object",
            "properties": {
              "datasource_names": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            }
          }
        }
      },
      "RouteResponse": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "enum": [
              "Ok"
            ]
          },
          "data_version": {
            "type": "string",
            "description": "Timestamp of the OSM data used."
          },
          "routes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OsrmRoute"
            }
          },
          "waypoints": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Waypoint"
            }
          }
        }
      },
      "TableResponse": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "enum": [
              "Ok"
            ]
          },
          "durations": {
            "type": "array",
            "description": "Row-major matrix of durations in seconds; null entries mean unreachable.",
            "items": {
              "type": "array",
              "items": {
                "type": [
                  "number",
                  "null"
                ]
              }
            }
          },
          "distances": {
            "type": "array",
            "description": "Row-major matrix of distances in meters.",
            "items": {
              "type": "array",
              "items": {
                "type": [
                  "number",
                  "null"
                ]
              }
            }
          },
          "sources": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Waypoint"
            }
          },
          "destinations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Waypoint"
            }
          },
          "fallback_speed_cells": {
            "type": "array",
            "items": {
              "type": "array",
              "items": {
                "type": "integer"
              },
              "minItems": 2,
              "maxItems": 2
            }
          }
        }
      },
      "Tracepoint": {
        "allOf": [
          {
            "$ref": "#/components/schemas/Waypoint"
          },
          {
            "type": "object",
            "properties": {
              "matchings_index": {
                "type": "integer"
              },
              "waypoint_index": {
                "type": "integer"
              },
              "alternatives_count": {
                "type": "integer"
              }
            }
          }
        ]
      },
      "MatchResponse": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "enum": [
              "Ok"
            ]
          },
          "tracepoints": {
            "type": "array",
            "description": "One entry per input point; null for dropped outliers.",
            "items": {
              "oneOf": [
                {
                  "$ref": "#/components/schemas/Tracepoint"
                },
                {
                  "type": "null"
                }
              ]
            }
          },
          "matchings": {
            "type": "array",
            "items": {
              "allOf": [
                {
                  "$ref": "#/components/schemas/OsrmRoute"
                },
                {
                  "type": "object",
                  "properties": {
                    "confidence": {
                      "type": "number",
                      "minimum": 0,
                      "maximum": 1
                    }
                  }
                }
              ]
            }
          }
        }
      },
      "TripResponse": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "enum": [
              "Ok"
            ]
          },
          "waypoints": {
            "type": "array",
            "items": {
              "allOf": [
                {
                  "$ref": "#/components/schemas/Waypoint"
                },
                {
                  "type": "object",
                  "properties": {
                    "trips_index": {
                      "type": "integer"
                    },
                    "waypoint_index": {
                      "type": "integer"
                    }
                  }
                }
              ]
            }
          },
          "trips": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OsrmRoute"
            }
          }
        }
      },
      "NearestResponse": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "enum": [
              "Ok"
            ]
          },
          "waypoints": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Waypoint"
            }
          }
        }
      },
      "OsrmError": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "enum": [
              "InvalidUrl",
              "InvalidService",
              "InvalidVersion",
              "InvalidOptions",
              "InvalidQuery",
              "InvalidValue",
              "NoSegment",
              "NoRoute",
              "NoTable",
              "NoMatch",
              "NoTrips",
              "TooBig",
              "DisabledDataset",
              "NotImplemented"
            ]
          },
          "message": {
            "type": "string"
          }
        }
      },
      "AuthError": {
        "type": "object",
        "properties": {
          "error": {
            "type": "string",
            "description": "`missing Authorization header` or `invalid or revoked API key`."
          }
        }
      },
      "RateLimitError": {
        "type": "object",
        "properties": {
          "code": {
            "type": "string",
            "enum": [
              "rate_limited"
            ]
          },
          "message": {
            "type": "string"
          }
        }
      },
      "OsrmRoute": {
        "type": "object",
        "properties": {
          "distance": {
            "type": "number",
            "description": "Total distance in meters."
          },
          "duration": {
            "type": "number",
            "description": "Total duration in seconds."
          },
          "weight": {
            "type": "number"
          },
          "weight_name": {
            "type": "string",
            "example": "routability"
          },
          "geometry": {
            "oneOf": [
              {
                "type": "string",
                "description": "Encoded polyline (precision 5 or 6)."
              },
              {
                "type": "object",
                "description": "GeoJSON LineString when geometries=geojson.",
                "required": [
                  "type",
                  "coordinates"
                ],
                "properties": {
                  "type": {
                    "type": "string",
                    "enum": [
                      "LineString"
                    ]
                  },
                  "coordinates": {
                    "type": "array",
                    "items": {
                      "type": "array",
                      "items": {
                        "type": "number"
                      }
                    }
                  }
                }
              }
            ]
          },
          "legs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/RouteLeg"
            }
          }
        }
      },
      "VroomInput": {
        "type": "object",
        "required": [
          "vehicles"
        ],
        "properties": {
          "vehicles": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Vehicle"
            },
            "description": "Available vehicles. Free plan: up to 10; Hobby: up to 50."
          },
          "jobs": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Job"
            },
            "description": "Jobs to serve. Optional if `shipments` is provided. Free plan: up to 100 tasks; Hobby: up to 1,000."
          },
          "shipments": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Shipment"
            },
            "description": "Pickup-and-delivery tasks (pickup must precede delivery)."
          },
          "matrices": {
            "$ref": "#/components/schemas/CustomMatrices",
            "description": "Custom matrices per profile; skips OSRM table calls when `durations` are provided for all used profiles."
          },
          "options": {
            "$ref": "#/components/schemas/VroomOptions",
            "description": "Solver options; `g` maps to the VROOM `-g` flag."
          }
        }
      },
      "Vehicle": {
        "type": "object",
        "required": [
          "id"
        ],
        "properties": {
          "id": {
            "type": "integer"
          },
          "profile": {
            "type": "string",
            "enum": [
              "car",
              "motorcycle"
            ],
            "default": "car",
            "description": "Routing profile (defaults to `car`). JustRouting supports `car` and `motorcycle`."
          },
          "description": {
            "type": "string"
          },
          "start": {
            "type": "array",
            "items": {
              "type": "number"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "Depot as `[lng, lat]`."
          },
          "end": {
            "type": "array",
            "items": {
              "type": "number"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "Return depot as `[lng, lat]`; same as start for a round trip; omit to stop at the last task."
          },
          "start_index": {
            "type": "integer",
            "description": "Row/column in custom matrices."
          },
          "end_index": {
            "type": "integer",
            "description": "Row/column in custom matrices."
          },
          "capacity": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "description": "Multidimensional capacity (e.g. weight, volume); the load at each route step must stay below capacity."
          },
          "skills": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "description": "Job skills must be a subset of vehicle skills."
          },
          "type": {
            "type": "string",
            "description": "Vehicle type, referenced by per-type setup and service times."
          },
          "time_window": {
            "$ref": "#/components/schemas/TimeWindow"
          },
          "breaks": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Break"
            },
            "description": "Rest periods during the route."
          },
          "speed_factor": {
            "type": "number",
            "exclusiveMinimum": 0,
            "maximum": 5,
            "default": 1,
            "description": "Scales all travel times for this vehicle, range `(0, 5]`, two decimals precision (defaults to 1)."
          },
          "max_tasks": {
            "type": "integer",
            "description": "Maximum number of tasks in this vehicle's route."
          },
          "max_travel_time": {
            "type": "integer",
            "description": "Seconds."
          },
          "max_distance": {
            "type": "integer",
            "description": "Meters."
          },
          "costs": {
            "$ref": "#/components/schemas/VehicleCosts"
          },
          "steps": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/VehicleStep"
            },
            "description": "Custom route. In solving mode this warm-starts the search: only `job`, `pickup` and `delivery` steps are used and `service_*` keys are ignored."
          }
        }
      },
      "Job": {
        "type": "object",
        "required": [
          "id",
          "location"
        ],
        "properties": {
          "id": {
            "type": "integer"
          },
          "description": {
            "type": "string",
            "description": "A string describing this job."
          },
          "location": {
            "type": "array",
            "items": {
              "type": "number"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "`[lng, lat]`. Optional if custom matrices cover all used profiles (then `location_index` is required)."
          },
          "location_index": {
            "type": "integer",
            "description": "Row/column in custom matrices; required when custom matrices are provided."
          },
          "setup": {
            "type": "integer",
            "default": 0,
            "description": "Setup duration in seconds (defaults to 0)."
          },
          "service": {
            "type": "integer",
            "default": 0,
            "description": "Service duration in seconds (defaults to 0)."
          },
          "setup_per_type": {
            "type": "object",
            "additionalProperties": {
              "type": "integer"
            },
            "description": "Setup durations per vehicle type; overrides `setup` for vehicles of that type."
          },
          "service_per_type": {
            "type": "object",
            "additionalProperties": {
              "type": "integer"
            },
            "description": "Service durations per vehicle type; overrides `service` for vehicles of that type."
          },
          "delivery": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "description": "Amounts to deliver (loaded at vehicle start)."
          },
          "pickup": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "description": "Amounts to pick up (returned at vehicle end)."
          },
          "skills": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "description": "Skills required to serve this job; the vehicle must have all of them."
          },
          "priority": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100,
            "default": 0,
            "description": "Higher priority tasks are preferred when not all tasks fit."
          },
          "time_windows": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TimeWindow"
            },
            "description": "Valid slots for service start."
          }
        }
      },
      "Shipment": {
        "type": "object",
        "required": [
          "pickup",
          "delivery"
        ],
        "properties": {
          "pickup": {
            "$ref": "#/components/schemas/ShipmentStep"
          },
          "delivery": {
            "$ref": "#/components/schemas/ShipmentStep"
          },
          "amount": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "description": "Amounts loaded at the pickup and unloaded at the delivery."
          },
          "skills": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "description": "Skills required to serve this shipment; the vehicle must have all of them."
          },
          "priority": {
            "type": "integer",
            "minimum": 0,
            "maximum": 100,
            "default": 0,
            "description": "Higher priority shipments are preferred when not all tasks fit."
          }
        }
      },
      "ShipmentStep": {
        "type": "object",
        "required": [
          "id",
          "location"
        ],
        "properties": {
          "id": {
            "type": "integer"
          },
          "description": {
            "type": "string",
            "description": "A string describing this step."
          },
          "location": {
            "type": "array",
            "items": {
              "type": "number"
            },
            "minItems": 2,
            "maxItems": 2,
            "description": "`[lng, lat]`. Optional if custom matrices cover all used profiles (then `location_index` is required)."
          },
          "location_index": {
            "type": "integer",
            "description": "Row/column in custom matrices; required when custom matrices are provided."
          },
          "setup": {
            "type": "integer",
            "default": 0,
            "description": "Task setup duration in seconds (defaults to 0)."
          },
          "service": {
            "type": "integer",
            "default": 0,
            "description": "Task service duration in seconds (defaults to 0)."
          },
          "setup_per_type": {
            "type": "object",
            "additionalProperties": {
              "type": "integer"
            },
            "description": "Task setup durations per vehicle type; overrides `setup` for vehicles of that type."
          },
          "service_per_type": {
            "type": "object",
            "additionalProperties": {
              "type": "integer"
            },
            "description": "Task service durations per vehicle type; overrides `service` for vehicles of that type."
          },
          "time_windows": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TimeWindow"
            },
            "description": "Valid slots for service start."
          }
        }
      },
      "TimeWindow": {
        "type": "array",
        "minItems": 2,
        "maxItems": 2,
        "items": {
          "type": "integer"
        },
        "description": "`[start, end]` in seconds relative to the planning horizon, or absolute UNIX timestamps (consistent within one request). Both ends are inclusive."
      },
      "Break": {
        "type": "object",
        "required": [
          "id"
        ],
        "properties": {
          "id": {
            "type": "integer"
          },
          "time_windows": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/TimeWindow"
            },
            "description": "Valid slots for break start."
          },
          "service": {
            "type": "integer",
            "default": 0,
            "description": "Break duration in seconds (defaults to 0)."
          },
          "description": {
            "type": "string",
            "description": "A string describing this break."
          },
          "max_load": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "description": "Maximum vehicle load for which this break can happen."
          }
        }
      },
      "VehicleCosts": {
        "type": "object",
        "properties": {
          "fixed": {
            "type": "integer",
            "default": 0,
            "description": "Cost of using this vehicle in the solution (defaults to 0)."
          },
          "per_hour": {
            "type": "integer",
            "default": 3600,
            "description": "Cost for one hour of travel time (defaults to 3600)."
          },
          "per_task_hour": {
            "type": "integer",
            "default": 0,
            "description": "Cost for one hour of task time, setup + service (defaults to 0)."
          },
          "per_km": {
            "type": "integer",
            "default": 0,
            "description": "Cost for one kilometer of travel (defaults to 0)."
          }
        }
      },
      "VehicleStep": {
        "type": "object",
        "required": [
          "type"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "start",
              "job",
              "pickup",
              "delivery",
              "break",
              "end"
            ],
            "description": "Step type."
          },
          "id": {
            "type": "integer",
            "description": "Task id for `job`, `pickup`, `delivery` or `break` steps."
          },
          "service_at": {
            "type": "integer",
            "description": "Hard constraint on service time (plan mode only)."
          },
          "service_after": {
            "type": "integer",
            "description": "Hard constraint on service time lower bound (plan mode only)."
          },
          "service_before": {
            "type": "integer",
            "description": "Hard constraint on service time upper bound (plan mode only)."
          }
        }
      },
      "CustomMatrices": {
        "type": "object",
        "description": "Per-profile custom matrices (`durations`, `distances`, `costs`). Providing `durations` for all used profiles makes `location`, `start` and `end` optional; use the `*_index` keys instead.",
        "additionalProperties": {
          "type": "object",
          "properties": {
            "durations": {
              "type": "array",
              "items": {
                "type": "array",
                "items": {
                  "type": "integer"
                }
              },
              "description": "Custom travel-time matrix used for all timing checks."
            },
            "distances": {
              "type": "array",
              "items": {
                "type": "array",
                "items": {
                  "type": "integer"
                }
              },
              "description": "Custom distance matrix; requires `durations`."
            },
            "costs": {
              "type": "array",
              "items": {
                "type": "array",
                "items": {
                  "type": "integer"
                }
              },
              "description": "Custom cost matrix used in all route cost evaluations."
            }
          }
        }
      },
      "VroomOptions": {
        "type": "object",
        "properties": {
          "g": {
            "type": "boolean",
            "default": false,
            "description": "Add polyline geometry (and distances) to each route in the response. Same effect as VROOM's `-g` flag."
          }
        }
      },
      "VroomOutput": {
        "type": "object",
        "properties": {
          "code": {
            "type": "integer",
            "enum": [
              0,
              1,
              2,
              3
            ],
            "description": "0 = ok, 1 = internal error, 2 = input error, 3 = routing error."
          },
          "error": {
            "type": "string",
            "description": "Present when code != 0."
          },
          "summary": {
            "$ref": "#/components/schemas/Summary"
          },
          "unassigned": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "integer"
                },
                "type": {
                  "type": "string",
                  "description": "`job`, `pickup` or `delivery`."
                },
                "location": {
                  "type": "array",
                  "items": {
                    "type": "number"
                  }
                },
                "location_index": {
                  "type": "integer",
                  "description": "Row/column in custom matrices, if provided in input."
                },
                "description": {
                  "type": "string"
                }
              }
            }
          },
          "routes": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/VroomRoute"
            }
          }
        }
      },
      "Summary": {
        "type": "object",
        "properties": {
          "cost": {
            "type": "integer",
            "description": "Total cost for all routes."
          },
          "routes": {
            "type": "integer",
            "description": "Number of routes in the solution."
          },
          "unassigned": {
            "type": "integer",
            "description": "Number of tasks that could not be served."
          },
          "setup": {
            "type": "integer",
            "description": "Total setup time for all routes."
          },
          "service": {
            "type": "integer",
            "description": "Total service time for all routes."
          },
          "duration": {
            "type": "integer",
            "description": "Total travel time in seconds."
          },
          "waiting_time": {
            "type": "integer",
            "description": "Total waiting time for all routes."
          },
          "priority": {
            "type": "integer",
            "description": "Total priority sum for all assigned tasks."
          },
          "distance": {
            "type": "integer",
            "description": "Total distance in meters (with `options.g` or distance matrices)."
          },
          "delivery": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "description": "Total delivery for all routes."
          },
          "pickup": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "description": "Total pickup for all routes."
          },
          "violations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Violation"
            },
            "description": "Violation objects for all routes."
          }
        }
      },
      "Step": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "start",
              "job",
              "pickup",
              "delivery",
              "break",
              "end"
            ],
            "description": "Step type: `start`, `job`, `pickup`, `delivery`, `break` or `end`."
          },
          "id": {
            "type": "integer",
            "description": "Task id for job/pickup/delivery/break steps."
          },
          "arrival": {
            "type": "integer",
            "description": "Arrival time (same clock as input)."
          },
          "duration": {
            "type": "integer",
            "description": "Cumulated travel time in seconds."
          },
          "setup": {
            "type": "integer",
            "description": "Setup time at this step."
          },
          "service": {
            "type": "integer",
            "description": "Service time at this step."
          },
          "waiting_time": {
            "type": "integer",
            "description": "Waiting time upon arrival at this step."
          },
          "distance": {
            "type": "integer",
            "description": "Cumulated distance in meters (with `options.g`)."
          },
          "location": {
            "type": "array",
            "items": {
              "type": "number"
            },
            "description": "`[lng, lat]`, if provided in input."
          },
          "location_index": {
            "type": "integer",
            "description": "Row/column in custom matrices, if provided in input."
          },
          "load": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "description": "Vehicle load after this step."
          },
          "description": {
            "type": "string",
            "description": "Step description, if provided in input."
          },
          "violations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Violation"
            },
            "description": "Violation objects for this step."
          }
        }
      },
      "Violation": {
        "type": "object",
        "properties": {
          "cause": {
            "type": "string",
            "enum": [
              "delay",
              "lead_time",
              "load",
              "max_tasks",
              "skills",
              "precedence",
              "missing_break",
              "max_travel_time",
              "max_distance",
              "max_load"
            ],
            "description": "Violation cause."
          },
          "duration": {
            "type": "integer",
            "description": "Earliness (resp. lateness) if `cause` is `lead_time` (resp. `delay`)."
          }
        }
      },
      "VroomError": {
        "type": "object",
        "properties": {
          "code": {
            "type": "integer"
          },
          "error": {
            "type": "string"
          }
        }
      },
      "VroomRoute": {
        "type": "object",
        "properties": {
          "vehicle": {
            "type": "integer",
            "description": "Id of the vehicle assigned to this route."
          },
          "cost": {
            "type": "integer",
            "description": "Cost for this route."
          },
          "setup": {
            "type": "integer",
            "description": "Total setup time for this route."
          },
          "service": {
            "type": "integer",
            "description": "Total service time for this route."
          },
          "duration": {
            "type": "integer",
            "description": "Travel time in seconds."
          },
          "waiting_time": {
            "type": "integer",
            "description": "Total waiting time for this route."
          },
          "priority": {
            "type": "integer",
            "description": "Total priority sum for tasks in this route."
          },
          "distance": {
            "type": "integer",
            "description": "Meters (with `options.g` or distance matrices)."
          },
          "geometry": {
            "type": "string",
            "description": "Encoded polyline (when `options.g` is true)."
          },
          "delivery": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "description": "Total delivery for tasks in this route."
          },
          "pickup": {
            "type": "array",
            "items": {
              "type": "integer"
            },
            "description": "Total pickup for tasks in this route."
          },
          "description": {
            "type": "string",
            "description": "Vehicle description, if provided in input."
          },
          "steps": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Step"
            },
            "description": "Route steps."
          },
          "violations": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Violation"
            },
            "description": "Violation objects for this route."
          }
        }
      },
      "GeocodeResponse": {
        "type": "object",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/GeocodeResult"
            },
            "description": "Matching places, ordered by relevance (best first); empty when nothing matches."
          },
          "query": {
            "$ref": "#/components/schemas/GeocodeQuery",
            "description": "Echo of how the API interpreted the request."
          }
        }
      },
      "GeocodeResult": {
        "type": "object",
        "properties": {
          "datasource": {
            "$ref": "#/components/schemas/Datasource"
          },
          "name": {
            "type": "string"
          },
          "housenumber": {
            "type": "string"
          },
          "street": {
            "type": "string"
          },
          "suburb": {
            "type": "string"
          },
          "district": {
            "type": "string"
          },
          "postcode": {
            "type": "string"
          },
          "city": {
            "type": "string"
          },
          "county": {
            "type": "string"
          },
          "state": {
            "type": "string"
          },
          "country": {
            "type": "string"
          },
          "country_code": {
            "type": "string",
            "description": "ISO 3166-1 alpha-2 country code."
          },
          "lon": {
            "type": "number",
            "description": "Longitude, in the same `lng,lat` order used by the routing APIs."
          },
          "lat": {
            "type": "number",
            "description": "Latitude."
          },
          "formatted": {
            "type": "string",
            "description": "Full, human-readable address."
          },
          "address_line1": {
            "type": "string"
          },
          "address_line2": {
            "type": "string"
          },
          "category": {
            "type": "string"
          },
          "result_type": {
            "type": "string",
            "description": "Feature type, e.g. `amenity`, `building`, `street`."
          },
          "rank": {
            "$ref": "#/components/schemas/Rank"
          },
          "timezone": {
            "$ref": "#/components/schemas/Timezone"
          },
          "plus_code": {
            "type": "string"
          },
          "place_id": {
            "type": "string",
            "description": "Opaque identifier for the place."
          },
          "bbox": {
            "$ref": "#/components/schemas/BBox"
          },
          "distance": {
            "type": "number",
            "description": "Meters from the bias location; present only when `bias` is set."
          }
        }
      },
      "GeocodeQuery": {
        "type": "object",
        "properties": {
          "text": {
            "type": "string",
            "description": "Free-text query as received by the API."
          },
          "parsed": {
            "type": "object",
            "description": "The API's structured interpretation of the query."
          }
        }
      },
      "Datasource": {
        "type": "object",
        "properties": {
          "sourcename": {
            "type": "string"
          },
          "attribution": {
            "type": "string"
          },
          "license": {
            "type": "string"
          },
          "url": {
            "type": "string"
          }
        }
      },
      "Rank": {
        "type": "object",
        "properties": {
          "importance": {
            "type": "number"
          },
          "popularity": {
            "type": "number"
          },
          "confidence": {
            "type": "number"
          },
          "confidence_city_level": {
            "type": "number"
          },
          "confidence_street_level": {
            "type": "number"
          },
          "match_type": {
            "type": "string"
          }
        }
      },
      "Timezone": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "IANA time zone name."
          },
          "offset_STD": {
            "type": "string"
          },
          "offset_DST": {
            "type": "string"
          },
          "offset_STD_seconds": {
            "type": "integer"
          },
          "offset_DST_seconds": {
            "type": "integer"
          },
          "abbreviation_STD": {
            "type": "string"
          },
          "abbreviation_DST": {
            "type": "string"
          }
        }
      },
      "BBox": {
        "type": "object",
        "properties": {
          "lon1": {
            "type": "number"
          },
          "lat1": {
            "type": "number"
          },
          "lon2": {
            "type": "number"
          },
          "lat2": {
            "type": "number"
          }
        },
        "description": "Bounding box as `[lon1, lat1, lon2, lat2]`."
      },
      "UpstreamError": {
        "type": "object",
        "properties": {
          "statusCode": {
            "type": "integer"
          },
          "error": {
            "type": "string"
          },
          "message": {
            "type": "string"
          }
        }
      }
    }
  }
}