From Google Route Optimization
Unmap Optimize accepts the Google Maps Platform Route Optimization
OptimizeToursRequest format and returns an OptimizeToursResponse. A REST integration can
keep its request and response handling for supported fields,
then replace the host and OAuth credential with Unmap's host and API key.
Check the field table first. Unsupported constraints require changes to the request, and
travel times, solutions and some failure behaviours differ.
Unmap is not affiliated with Google, and Google does not endorse it. The product names on this page are used only to say which API Unmap's format follows.
Unmap Optimize is live on api.unmap.dev, on both Google's paths and POST /optimize.
Change the base URL
Unmap serves Google's own paths, so the smallest change is the host:
| Unmap | |
|---|---|
https://routeoptimization.googleapis.com/v1/projects/{project}:optimizeTours | https://api.unmap.dev/v1/projects/{project}:optimizeTours |
https://routeoptimization.googleapis.com/v1/projects/{project}/locations/{location}:optimizeTours | https://api.unmap.dev/v1/projects/{project}/locations/{location}:optimizeTours |
{project} and {location} can stay what they are: Unmap ignores them, and parent in the body,
because the API key identifies the account. The same handler also answers at Unmap's own path,
POST https://api.unmap.dev/optimize, which is the one to use in new code.
Only optimizeTours is implemented. batchOptimizeTours and the other methods answer 404.
Unmap serves the REST binding (JSON over HTTPS) only: a client library that talks gRPC will not
connect. Use its REST transport if it has one, or call the endpoint with a plain HTTP client.
Change the credential
Google authenticates this API with OAuth 2.0 access tokens from a Google Cloud account. Unmap uses
an API key from your dashboard, with no OAuth token exchange. Save the request as
request.json and set UNMAP_API_KEY to your key before running the Unmap example:
curl -X POST "https://routeoptimization.googleapis.com/v1/projects/my-project:optimizeTours" \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
--data @request.json# Same path, new host, an Unmap key where the access token was
curl -X POST "https://api.unmap.dev/v1/projects/my-project:optimizeTours" \
-H "Authorization: Bearer $UNMAP_API_KEY" \
-H "Content-Type: application/json" \
--data @request.json
# Or Unmap's own path, with the key in X-API-Key
curl -X POST "https://api.unmap.dev/optimize" \
-H "X-API-Key: $UNMAP_API_KEY" \
-H "Content-Type: application/json" \
--data @request.jsonUnmap also accepts X-Goog-Api-Key, X-API-Key and ?key=. If a client library manages OAuth
credentials automatically, configure its REST transport to send an Unmap key instead, or use a
plain HTTP client. Changing the host alone does not replace Google credentials.
See Authentication.
What carries over
- Field names and nesting, camelCase or snake_case, durations as
"300s", timestamps as RFC 3339 or{ seconds, nanos }, and 64-bit integers as strings. - The response:
routeswithvisits,transitions,metrics,routeCostsandroutePolyline;skippedShipmentswith Google's reason codes; andmetricswith the cost breakdown under the same keys. solvingMode: VALIDATE_ONLY, which answersvalidationErrorswithout solving.- Errors in Google's shape,
{ "error": { "code", "message", "status", "details" } }, with the same status names (INVALID_ARGUMENT,FAILED_PRECONDITION,RESOURCE_EXHAUSTEDand so on). Unmap adds its owncodestring besideerror.
What fails loudly
Unmap refuses what it cannot do. A plan that silently dropped a time window or a capacity would look fine and be wrong, so every unsupported constraint is an error you see on the first request:
- Fields not supported yet are a
400withFIELD_NOT_SUPPORTED_YETwhen set to anything but their default: quadratic soft duration limits,loadDemandson a visit, shipment types and precedence rules, injected solutions,maxActiveVehicles,Vehicle.ignoreand more. Values not supported yet areVALUE_NOT_SUPPORTED_YET: more than one pickup or delivery alternative per shipment, a second vehicle start or end time window,travelMode: WALKING, and theDETECT_SOME_INFEASIBLE_SHIPMENTSandTRANSFORM_AND_RETURN_REQUESTsolving modes. Like quadratic soft duration limits,routeDistanceLimit.costPerKilometerBelowSoftMaxis refused, but for good and withINVALID_VALUE, because GMPRO does not support it either. Field support has the full list, generated from the validator. - Place IDs (
arrivalWaypoint.placeId,startWaypoint.placeId,endWaypoint.placeId) arePLACE_ID_NOT_SUPPORTED. A place ID points into Google's database, and guessing a location for it would route to the wrong place. Geocode the address once with/geocode/searchand send coordinates. - Cloud Storage URIs (
gs://) have nowhere to go: no field ofoptimizeTourstakes one, and the batch methods that read them are not available (they answer404). The codeGCS_URI_NOT_SUPPORTEDis reserved for them; nothing returns it today. Send the request body inline. - Unknown fields, including typos, are
UNKNOWN_FIELDrather than skipped. - A mandatory shipment that cannot be served is a
400FAILED_PRECONDITIONthat names it, where Google can answer200with the shipment skipped and counted inskippedMandatoryShipmentCount. Give a shipment apenaltyCostif it may be skipped.
Run your real requests through VALIDATE_ONLY first. It reports field validation errors up to
maxValidationErrors and costs nothing. It does not test road reachability or fleet feasibility;
follow it with a solve. Authentication, body size and shipment or vehicle count limits still apply.
What is accepted and ignored
Unmap accepts several fields without applying them. A non-default value produces a warning in
the X-Unmap-Optimize-Warnings response header: considerRoadTraffic, parent, populateTransitionPolylines,
allowLargeDeadlineDespiteInterruptionRisk, and a waypoint's location.heading, sideOfRoad and
vehicleStopover. Review these warnings on each response. Ignored traffic and waypoint settings
can affect whether a plan suits your operation. The response body follows Google's format.
Routes and costs will differ
For the supported cost fields, Unmap uses fixedCost once per used vehicle, costPerHour over each route's
duration, costPerTraveledHour over its driving time, costPerKilometer over its distance, and
penaltyCost for each skipped optional shipment, excluding ignored shipments. These costs appear
under the same keys in metrics.costs. What goes
into it is not the same:
- Travel times come from a different road network. Unmap computes driving times from
OpenStreetMap data on its own Canada road graph, at free-flow speeds with no traffic
(
considerRoadTrafficis ignored). The same stops get different travel times than on Google, so routes, arrival times andtotalCostdiffer too. - The solver is different. Even with identical travel times (your own
durationDistanceMatrices), two solvers given a few seconds each can return different plans of similar cost. - Road coverage is Canada. For stops elsewhere, send your own matrices or use
useGeodesicDistances.
So do not judge a migration by comparing totalCost to the last Google answer. Check that the
plans are feasible and that their cost is reasonable for your operation, then compare on your own
travel data.
Limits and billing
Per-plan limits apply to shipments, vehicles, locations, solve time and solves at once: Hobby
allows 25 shipments, Growth 2,000. A timeout longer than the plan's is clamped, not refused.
Billing is one call per shipment actually served, and re-solving the same shipments within 24
hours is free. The Optimize API page has the numbers.
Checklist
- Use
https://api.unmap.devas the host, keeping a supported Google path or using/optimize. - Replace the OAuth token with an Unmap API key.
- Send a real request with
solvingMode: VALIDATE_ONLYand fix what it reports. - Replace place IDs with coordinates from
/geocode/search. - Inspect
X-Unmap-Optimize-Warningson every response for ignored fields and travel warnings. - Check the plan's limits against your largest request.
- Run a solve and verify its visit times, loads, skipped shipments and costs.