Skip to main content

HERE Tour Planning

Tour Planning is a solver, not a router. You hand it a problem — jobs, vehicles, constraints — and it returns a sequence. This is the API behind both /here-tour-planning/ and /route-optimization/ on placematic.com. They describe one HERE product. There is one guide.

What problem this guide solves

You have 200 stops, 12 vehicles, delivery time windows, vehicle capacities, driver shifts, and two refrigerated trucks that must handle the frozen goods. You need to know which vehicle visits which stop, in what order. This is the Vehicle Routing Problem. It is NP-hard. You are not going to solve it with a loop and a nearest-neighbour heuristic, and every hour you spend trying is an hour you could have spent shipping.

When to use Tour Planning

HERE’s solver handles these VRP variants:
  • Capacitated VRP — vehicle capacity constrains what can be loaded
  • VRP with time windows — stops accept service only within defined intervals
  • Multi-depot VRP — vehicles start from different locations
  • Heterogeneous fleet VRP — mixed vehicle types with different costs, capacities, and capabilities
  • Pickup and delivery VRP — collect at A, deliver at B, in one tour
  • VRP with priorities — high-priority jobs are protected from being dropped when capacity binds
  • VRP with reloads — a vehicle returns to a depot mid-tour to reload
If your problem is on that list, use Tour Planning.

When NOT to use it

Tour Planning is not a routing API. It returns a sequence and an itinerary. If you need turn-by-turn geometry for a single leg, that is Routing.
  • Point-to-point navigation. Use Routing.
  • A table of travel times. Use Matrix Routing. Tour Planning consumes that kind of cost internally; do not ask it for the table.
  • Real-time dispatch on every event. Solving takes seconds to minutes. It is not a per-request operation in a hot path.
  • Two or three stops. A solver is overhead. Sort them.
  • Problems where you need to see and tune the objective function. Tour Planning exposes cost weights, not a general-purpose optimizer. If you need custom objectives beyond distance, time, and fixed cost, you may want your own solver fed by Matrix Routing.

Structure of a problem

Two halves. Get this mental model right and the rest follows. plan — the jobs. Each job has an id, tasks (deliveries, pickups), places with locations, service duration, time windows, and demand. fleet — the vehicles. types defines vehicle classes with costs, capacity, shifts, and limits. profiles defines routing behaviour — transport type, departure time, traffic handling.
fleet.types[].profile is a string reference into fleet.profiles[].name. It is not a transport mode. Writing "profile": "truck" when no profile is named truck is a common and confusing failure. Name the profile, then reference it.

Submitting a problem

curl --location 'https://tourplanning.hereapi.com/v3/problems' \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer <TOKEN>' \
  --data '{
    "plan": {
      "jobs": [{
        "id": "myJob",
        "tasks": {
          "deliveries": [{
            "places": [{
              "location": {"lat": 52.46642, "lng": 13.28124},
              "times": [["2020-07-04T10:00:00.000Z","2020-07-04T12:00:00.000Z"]],
              "duration": 180
            }],
            "demand": [1]
          }]
        }
      }]
    },
    "fleet": {
      "types": [{
        "id": "myVehicleType",
        "profile": "normal_car",
        "costs": {"distance": 0.0002, "time": 0.005, "fixed": 22},
        "shifts": [{
          "start": {"time": "2020-07-04T09:00:00Z", "location": {"lat": 52.52568, "lng": 13.45345}},
          "end":   {"time": "2020-07-04T18:00:00Z", "location": {"lat": 52.52568, "lng": 13.45345}}
        }],
        "limits": {"maxDistance": 300000, "shiftTime": 28800},
        "capacity": [10],
        "amount": 1
      }],
      "profiles": [{"name": "normal_car", "type": "car", "departureTime": "2020-07-04T09:15:00Z"}]
    },
    "configuration": {
      "termination": {"maxTime": 2, "stagnationTime": 1}
    }
  }'
curl --location 'https://tourplanning.hereapi.com/v3/problems/async' \
  --header 'Content-Type: application/json' \
  --header 'Authorization: Bearer <TOKEN>' \
  --data '{ ...same body as sync... }'

# Returns:
# { "statusId": "<id>", "href": "https://tourplanning.hereapi.com/v3/status/<statusId>" }
API key authentication works too: drop the Authorization header and append ?apikey=<YOUR_HERE_API_KEY> to the URL. This applies to all Tour Planning endpoints. See Authentication.

The async lifecycle

For anything of real size, use /v3/problems/async.
  1. POST the problem → receive statusId and href
  2. GET the href — poll while status is pending or inProgress
  3. On success, the response contains resource.href pointing to the solution
  4. GET the solution at /v3/problems/{problemId}/solution
Terminal statuses are success, timeout, and failure. A timeout is not a bug — see below.
Use the href HERE returns. Do not construct status or solution URLs yourself.

Key concepts

configuration.termination controls solve quality. maxTime caps wall-clock seconds. stagnationTime stops when the solution stops improving. These are the two most important parameters in the request, and both are routinely left at example values. A two-second maxTime on a 200-stop problem produces a legal solution that a dispatcher will look at and reject. Increase it. Measure the marginal improvement. Find your knee. timeout status means the solver did not converge within maxTime. It is a tuning signal, not an error. Raise maxTime or reduce problem size. Jobs can be dropped. If capacity, shift time, or time windows make full service impossible, the solver returns unassigned jobs with reasons. Your integration must handle a solution that does not serve every stop. A dispatcher UI that silently omits them is worse than useless. Priorities protect jobs from being dropped. High-priority jobs are preferentially retained when constraints bind. Costs shape the objective. distance, time, and fixed per vehicle type. Setting fixed high discourages using an extra vehicle; setting it to zero encourages spreading load. This is where you encode business policy, and most teams never touch it. Truck profiles are supported. type: "truck" with vehicle parameters, same physical constraints as Truck Routing. Optimizing a truck fleet on car profiles produces sequences that are infeasible in exactly the way a car route is infeasible for a truck. Traffic handling is a profile property. Live or historic traffic materially changes ETAs and therefore the optimal sequence. A 9am tour and a 2pm tour are different problems.

Production architecture

Solve is a job, not a request. Submit async, persist statusId, poll on a worker, return control to the caller immediately. Blocking a dispatcher’s HTTP request on a 90-second solve reproduces every problem async exists to prevent. Persist statusId before you poll. Process restarts. Resubmitting a solved problem bills again and returns a different sequence, which confuses everyone. Solve on a schedule, not on every change. Nightly, or on dispatch-window close. Re-solving on every order that arrives produces route churn drivers cannot follow. Model unassigned jobs as a first-class outcome. Surface them. Explain why. Let a human decide. Store the solution, not just the sequence. When a driver deviates, you need to know what the plan was. Replanning mid-day is a new problem. Vehicle current location becomes the shift start. Completed jobs are removed. This is a fresh submission, not an incremental update. Truck parameters belong on the vehicle record, not in the request builder. Same argument as Truck Routing.

Cost and usage considerations

Tour Planning is included in the HERE Base Plan. This is worth knowing before anyone builds an approximation to avoid a licensing conversation that does not exist.
Confirm your entitlement anyway — Base Plan inclusion and your contract’s inclusion are separate facts. See Getting a HERE API Key. Where teams overspend, and it is rarely on Tour Planning itself:
  • Approximating tour planning with N routing calls. Slower, more expensive, and the routes are worse. This is the single largest waste in fleet software.
  • Re-solving unchanged problems. Hash the problem. If nothing changed, reuse the solution.
  • Solving per-vehicle instead of per-fleet. The whole point is fleet-wide balancing.
  • maxTime set so high that solves cost more compute than the improvement is worth. Measure the knee.
See HERE Pricing Explained.

Common mistakes

Building an optimizer out of the Routing API. The reason this page exists. Setting profile to a transport mode instead of a profile name. It is a reference into fleet.profiles. Leaving maxTime: 2 from the documentation example. Legal solution, unusable routes. Treating timeout as a failure. It means “raise maxTime.” Ignoring unassigned jobs. The solver told you it could not serve them. Read the response. Blocking an HTTP request on a synchronous solve. Use /async. Constructing the status or solution URL. Use the returned href. Optimizing a truck fleet on car profiles. Infeasible sequences, confidently returned. Leaving costs at example values. fixed is how you tell the solver whether adding a vehicle is cheap or expensive. That is a business decision, not a default. Re-solving on every inbound order. Route churn. Drivers stop trusting the app.

Best practices

  • Use /v3/problems/async for anything beyond a toy
  • Persist statusId before polling; poll on a worker
  • Tune maxTime and stagnationTime against your own problem size; find the knee empirically
  • Set costs to reflect real vehicle economics
  • Handle and surface unassigned jobs explicitly
  • Name profiles clearly and reference them correctly
  • Use truck profiles and vehicle constraints for truck fleets
  • Hash the problem; skip re-solves that would produce the same answer
  • Solve on a schedule; treat mid-day replanning as a new problem

API reference

Complete problem and solution schemas, constraint definitions, and objective configuration are maintained by HERE. We do not duplicate them.

Matrix Routing

The cost table underneath any optimization — including your own solver.

Truck Routing

Vehicle constraints, which Tour Planning profiles also accept.

Routing

Turn-by-turn geometry for the legs Tour Planning sequences.

Choosing the Right HERE APIs

Routing, matrix, and solver — the distinction that costs the most to get wrong.
Also: EV Routing · Authentication · HERE Tour Planning
Need production HERE API keys or implementation support? Placematic is an official HERE Technologies reseller and implementation partner helping companies choose the right HERE APIs, estimate usage, migrate from Google Maps and build production-ready geospatial solutions. Talk to us.