{ "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" } } } } } }