Get Started - HERE developer portal

This section outlines how to get started quickly using the HERE Tour Planning API on the HERE developer portal.

  1. Get a HERE Account
  2. Register your App
  3. Get an API Key
  4. Send a Request

Note

This section provides information on the minimum setup required to begin quickly using the HERE Tour Planning API. For more detailed information on HERE account setup, app registration, and authentication, see the Identity & Access Management Developer Guide.

Get a HERE Account

If you are an individual developer who has signed up for one of the plans listed on our Developer plans page on developer.here.com., you received a HERE account ID when you signed up. You can use your HERE account to log in to developer.here.com. to create applications. Applications (uniquely identified by an app ID) enable development with HERE products and services.

Register your App

To register your app, follow these steps:

  1. Sign in to developer.here.com..
  2. Click your name, select Projects, and then choose your project from the list. Your project details and available application credentials are then displayed.
  3. Select JavaScript or REST and click Generate App. When your application is created, its app ID is displayed.

Get an API key

To get an API key, follow these steps:

  1. Sign in to developer.here.com..
  2. Click your name, select Projects, and then choose your project from the list. Your project details and available application credentials are then displayed.
  3. Click Create API key to generate a maximum of two API keys for your application. The API key is created and displayed.

Send a Request

The HERE Tour Planning API supports two types of requests, synchronous and asynchronous. All features are available for both synchronous and asynchronous requests, however synchronous requests have stricter limitations on jobs and fleet sizes.

Note

Certain features make solving a vehicle routing problem more challenging, therefore the algorithm needs more time to find a "good" solution. Such features can include, the amount of jobs and vehicle types, multi-jobs, pickup and delviery jobs, restrictive time windows, insufficient total vehicle capacity in comparison to the total job demand, and so on. HERE recommends using asynchronous requests with a higher polling interval in these cases.

Complexity of the problem vs. time required to solve it

Certain features make solving a vehicle routing problem more challenging, so that the algorithm needs more time to find a "good" solution. Such features are:

  • The amount of jobs and vehicle types: the bigger amount means more complex problem
  • Multi jobs
  • Pickup and delivery jobs
  • Restrictive time windows
  • Insufficient total vehicle capacity in comparison to total job demand

Consider using asynchronous request with higher polling interval in such cases.

Synchronous Request

Using the synchronous request involves sending a request to the server and waiting for the response. The synchronous request has a limit of 250 jobs and 35 vehicle types. For larger problems, you can use an asynchronous request.

Create a problem definition and send a solution calculation request to the corresponding endpoint. If the request is valid, the service will start calculating and will return a solution once the calculation is completed. The following is an example of such a request:

POST `https://tourplanning.hereapi.com/v3/problems`
Authorization: Bearer <TOKEN>
Content-Type: application/json

Body:

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

Example of a response with a calculated solution:

{
  "statistic": {
    "cost": 54.459916,
    "distance": 35277,
    "duration": 5286,
    "times": {
      "driving": 5106,
      "serving": 180,
      "waiting": 0,
      "break": 0
    }
  },
  "tours": [
    {
      "vehicleId": "myVehicle_1",
      "typeId": "myVehicle",
      "stops": [
        {
          "location": {"lat": 52.52568, "lng": 13.45345},
          "time": {
            "arrival": "2020-07-04T09:19:01Z",
            "departure": "2020-07-04T09:19:01Z"
          },
          "load": [1],
          "activities": [
            {
              "jobId": "departure",
              "type": "departure"
            }
          ]
        },
        {
          "location": {"lat": 52.46642, "lng": 13.28124},
          "time": {
            "arrival": "2020-07-04T10:00:00Z",
            "departure": "2020-07-04T10:03:00Z"
          },
          "load": [0],
          "activities": [
            {
              "jobId": "myJob",
              "type": "delivery"
            }
          ]
        },
        {
          "location": {"lat": 52.52568, "lng": 13.45345},
          "time": {
            "arrival": "2020-07-04T10:47:07Z",
            "departure": "2020-07-04T10:47:07Z"
          },
          "load": [0],
          "activities": [
            {
              "jobId": "arrival",
              "type": "arrival"
            }
          ]
        }
      ],
      "statistic": {
        "cost": 54.459916,
        "distance": 35277,
        "duration": 5286,
        "times": {
          "driving": 5106,
          "serving": 180,
          "waiting": 0,
          "break": 0
        }
      }
    }
  ]
}

For a detailed explanation, see Solution.

If a request is not valid, then the corresponding error is returned:

{
  "title": "BAD_REQUEST",
  "status": 400,
  "code": "E613420",
  "cause": "Vehicle's arrival time is earlier than its departure time",
  "action": "Correct arrival time of 'vehicle' to be earlier than its departure",
  "correlationId": "<globally unique id>"
}

Asynchronous Request

The asynchronous request to receive a solution for a problem consists of several steps:

Note

Asynchronous request flows have a limit of 3000 jobs and 150 vehicle types.

Request a Solution for the Problem

Create a problem definition and send a solution calculation request to the corresponding endpoint:

POST `https://tourplanning.hereapi.com/v3/problems/async`
Authorization: Bearer <TOKEN>
Content-Type: application/json

Body:

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

The service will return the following response body:

{
    "statusId": "<globally unique id>",
    "href": "https://tourplanning.hereapi.com/v3/status/<same as in statusId>"
}

The elements in the response are:

  • statusId — A unique identifier of the status which is used for tracking the solution calculation status and for downloading the solution result.
  • href — The URL for polling the status.

Check the Status of the Solution

To get the status of a solution calculation for a given problem ID, use the href obtained when submitting the request:

> GET `https://tourplanning.hereapi.com/v3/status/<statusId>`
> Authorization: Bearer <token>
---
< HTTP/1.1 200 OK
< Content-Type: application/json

Body:

{
    "status": "pending"
}

If you get status pending or inProgress, then you should keep polling until the calculation is finished and a status of success, timeout, or failure is returned.

A response with success returns a resource link to download the calculated solution:

{
    "status": "success",
    "resource": {
      "resourceId": "<globally unique id>",
      "href": "https://tourplanning.hereapi.com/v3/problems/<same as resourceId>/solution"
    }
}

A response with failure returns an error object:

{
    "status": "failure",
    "error": {
      "message": "There was an error solving the problem"
    }
}

You can use the statusId to get error details via the solution endpoint as described in the following section.

Download the Solution

If the status of a solution calculation is success, the calculated solution is available using the ID provided in the resourceId element which is effectively a problemId:

> GET `https://tourplanning.hereapi.com/v3/problems/<problemId>/solution`
> Content-Type: application/json

Response body:

{
  "statistic": {
    "cost": 54.459916,
    "distance": 35277,
    "duration": 5286,
    "times": {
      "driving": 5106,
      "serving": 180,
      "waiting": 0,
      "break": 0
    }
  },
  "tours": [
    {
      "vehicleId": "myVehicle_1",
      "typeId": "myVehicle",
      "stops": [
        {
          "location": {"lat": 52.52568, "lng": 13.45345},
          "time": {
            "arrival": "2020-07-04T09:19:01Z",
            "departure": "2020-07-04T09:19:01Z"
          },
          "load": [1],
          "activities": [
            {
              "jobId": "departure",
              "type": "departure"
            }
          ]
        },
        {
          "location": {"lat": 52.46642, "lng": 13.28124},
          "time": {
            "arrival": "2020-07-04T10:00:00Z",
            "departure": "2020-07-04T10:03:00Z"
          },
          "load": [0],
          "activities": [
            {
              "jobId": "myJob",
              "type": "delivery"
            }
          ]
        },
        {
          "location": {"lat": 52.52568, "lng": 13.45345},
          "time": {
            "arrival": "2020-07-04T10:47:07Z",
            "departure": "2020-07-04T10:47:07Z"
          },
          "load": [0],
          "activities": [
            {
              "jobId": "arrival",
              "type": "arrival"
            }
          ]
        }
      ],
      "statistic": {
        "cost": 54.459916,
        "distance": 35277,
        "duration": 5286,
        "times": {
          "driving": 5106,
          "serving": 180,
          "waiting": 0,
          "break": 0
        }
      }
    }
  ]
}

For a detailed explanation, see Solution.

If an error occurs during the problem solving, the error response is returned:

{
    "title": "Unprocessable entity",
    "status": 422,
    "code": "E613000",
    "cause": "E613420, 'Vehicle's arrival time is earlier than its departure time' 'Correct arrival time of 'vehicle' to be earlier than its departure'",
    "action": "",
    "correlationId": "REQ-497fdde4-048d-4db5-9d6e-8e44a952dede"
}

Note

Requesting a solution of an unfinished calculation will result in the HTTP status code 404 Not Found.

results matching ""

    No results matching ""