Bobbie Smulders Freelance Software Developer

Using the TomTom Route Planner API

Route planned in TomTom

Update June 2016: TomTom has published official documentation: TomTom Developer Portal

A while back, I wrote about using the TomTom Live Traffic API. But what about the route planner API? Fortunately, it uses the same type of request and response. So how does the API work?

Request URI

http://api.internal.tomtom.com/lbs/services/route/3
/52.36378,4.8822:52.37244,4.894101
/Quickest/json?key=dvbfcb88hkrje9ur2fs84uxn&language=en
&projection=EPSG4326&avoidTraffic=true&includeTraffic=true
&day=today&time=now&iqRoutes=2&trafficModelId=1424944744824&map=basic

Just like the previous examination, let’s dig a little deeper:

http://api.internal.tomtom.com
/lbs/services                   // Location based services
/route                          // Route planner
/3                              // Unknown
/52.36378,4.8822                // Coordinates of departure
:52.37244,4.894101              // Coordinates of destination
/Quickest                       // Type of route: Quickest, Shortest, AvoidMotorway, Walk, Bicycle, SpeedLimited or Green
/json                           // Type of output: json or xml
?key=dvbfcb88hkrje9ur2fs84uxn   // Might be the API key
&language=en                    // Language of descriptions: nl/Dutch, en/English
&projection=EPSG4326            // Type of coordinate system
&avoidTraffic=true              // Use traffic information to minimize delays, can be true or false
&includeTraffic=true            // Include traffic on the map, has no result on the returned result
&day=today                      // Day of departure: today, tomorrow, monday ... sunday
&time=now                       // Time of departure: now, anytime or 0...1439 (amount of minutes since the start of the day, 12:00PM = 12*60 = 720)
&iqRoutes=2                     // Unknown: 0, 1 or 2
&trafficModelId=1424944744824   // Timestamp of request
&map=basic                      // Unknown

JSON response
Using this request the following data is returned:

{"route":{"@version":"0.78.6","summary":{"routeKey":"q:543483.9917075406,6866170.891534261:544808.8471165473,6867749.63032282:S:du:t:5:59:t:1352505544993:9:f:b:t","iqType":"S","bbox":{"bottomLeft":{"latitude":52.35804,"longitude":4.88002},"topRight":{"latitude":52.37243,"longitude":4.89604}},"trafficModelId":"1352505544993","startTimeZone":"Europe\/Amsterdam","endTimeZone":"Europe\/Amsterdam","totalDelaySeconds":0,"totalDistanceMeters":3069,"totalTimeSeconds":607,"departureOverview":{"day":"today","time":"00:59","message":"Leave now from {0}"},"arrivalOverview":{"day":"today","time":"01:09","message":"Arrive today at {0}"},"routeURI":"@52.363780975341804,4.882199764251709:@52.37244033813476,4.894101142883302"},"instructions":{"instruction":[{"@isDepartureAction":true,"distanceMeters":0,"iconPath":"start.png","bbox":{"bottomLeft":{"latitude":52.36378,"longitude":4.8822},"topRight":{"latitude":52.36378,"longitude":4.8822}},"point":{"latitude":52.36378,"longitude":4.8822},"roadName":"Leidseplein - Lijnbaansgracht - Marnixstraat, Amsterdam","roadNumber":"","text":"Leave from","travelTimeSeconds":0},{"distanceMeters":157,"iconPath":"turnleft.png","bbox":{"bottomLeft":{"latitude":52.36291,"longitude":4.88023},"topRight":{"latitude":52.36291,"longitude":4.88023}},"point":{"latitude":52.36291,"longitude":4.88023},"roadName":"Stadhouderskade","roadNumber":"S100","text":"Turn left onto","travelTimeSeconds":33},{"distanceMeters":1117,"iconPath":"turnleft.png","bbox":{"bottomLeft":{"latitude":52.35804,"longitude":4.89083},"topRight":{"latitude":52.35804,"longitude":4.89083}},"point":{"latitude":52.35804,"longitude":4.89083},"roadName":"Ferdinand Bolstraat","roadNumber":"","text":"Turn left onto","travelTimeSeconds":168},{"distanceMeters":1213,"iconPath":"ra_cross.png","bbox":{"bottomLeft":{"latitude":52.35888,"longitude":4.89107},"topRight":{"latitude":52.35888,"longitude":4.89107}},"point":{"latitude":52.35888,"longitude":4.89107},"roadName":"Nieuwe Vijzelstraat","roadNumber":"","text":"At the roundabout, take the second exit onto","travelTimeSeconds":32},{"distanceMeters":1321,"iconPath":"bearright.png","bbox":{"bottomLeft":{"latitude":52.35964,"longitude":4.89115},"topRight":{"latitude":52.35964,"longitude":4.89115}},"point":{"latitude":52.35964,"longitude":4.89115},"roadName":"Nieuwe Vijzelstraat","roadNumber":"","text":"Exit right at","travelTimeSeconds":23},{"distanceMeters":2453,"iconPath":"turnright.png","bbox":{"bottomLeft":{"latitude":52.36933,"longitude":4.89216},"topRight":{"latitude":52.36933,"longitude":4.89216}},"point":{"latitude":52.36933,"longitude":4.89216},"roadName":"Langebrugsteeg","roadNumber":"","text":"Turn right onto","travelTimeSeconds":184},{"distanceMeters":2617,"iconPath":"turnleft.png","bbox":{"bottomLeft":{"latitude":52.36931,"longitude":4.89448},"topRight":{"latitude":52.36931,"longitude":4.89448}},"point":{"latitude":52.36931,"longitude":4.89448},"roadName":"Oudezijds Voorburgwal","roadNumber":"","text":"Turn left onto","travelTimeSeconds":46},{"distanceMeters":2921,"iconPath":"turnleft.png","bbox":{"bottomLeft":{"latitude":52.3718,"longitude":4.89604},"topRight":{"latitude":52.3718,"longitude":4.89604}},"point":{"latitude":52.3718,"longitude":4.89604},"roadName":"Damstraat","roadNumber":"","text":"Turn left onto","travelTimeSeconds":73},{"@isDestinationAction":true,"@isDestination":true,"distanceMeters":3069,"iconPath":"finish.png","bbox":{"bottomLeft":{"latitude":52.37243,"longitude":4.8941},"topRight":{"latitude":52.37243,"longitude":4.8941}},"point":{"latitude":52.37243,"longitude":4.8941},"roadName":"Damstraat, Amsterdam","roadNumber":"","text":"Arrive at","travelTimeSeconds":48}]}}}</pre>

The data uses a very simple JSON scheme, which is laid out as follows:

{
  "route": {
    "@version": "",			// The version of the route planner
    "summary": {
      "routeKey": "",			// Summary of the request parameters
      "iqType": "",			// Unknown, can be changed with the "iqRoutes" parameter (0,1,2 map to N,E,S)
      "bbox": {				// The coordinates of the viewport that contains the route	
        "bottomLeft": {
          "latitude":0.0,
          "longitude"0.0:
        },
        "topRight": {
          "latitude": 0.0,
          "longitude": 0.0
        }
      },
      "trafficModelId": "",		// Current time as Unix timestamp
      "startTimeZone": "",		// Timezone of the departure
      "endTimeZone": "",		// Timezone of the destination
      "totalDelaySeconds": 0,		// Delay caused by traffic
      "totalDistanceMeters": 0,		// Distance of the route in meters
      "totalTimeSeconds": 0,		// Total time the route takes
      "departureOverview": {
        "day": "",			// The day of the departure
        "time": "",			// The time of the departure
        "message": ""			// Readable message of both
      },
      "arrivalOverview": {
        "day": "",			// The day of the arrival
        "time": "",			// The time of the arrival
        "message": ""			// Readable message of both
      },
      "routeURI": ""			// The departure and destination coordinates
    },
    "instructions": {
      "instruction": [
        {
          "@isDepartureAction": ,	// Wether or not this is the departure instruction (true or false). Will not be displayed when it is false
          "@isDestinationAction":,	// Wether or not this is the destination instruction (true or false). Will not be displayed when it is false
          "@isDestination": ,		// Wether or not this is the destination (true or false). Will not be displayed when it is false
          "distanceMeters": 0,		// Distance of this parts of the route
          "iconPath": "",		// Icon for this instruction
          "bbox": {			// The coordinates of the viewport that contains the instruction
            "bottomLeft": {
              "latitude": 0.0,
              "longitude": 0.0
            },
            "topRight": {
              "latitude": 0.0,
              "longitude": 0.0
            }
          },
          "point": {			// Specific coordinates of this direction
            "latitude": 0.0,
            "longitude": 0.0
          },
          "roadName": "",		// Name of the road
          "roadNumber": "",		// Number of the road
          "text": "",			// Instruction text
          "travelTimeSeconds": 0	// Time it takes to travel during this instruction
        },
      ]
    }
  }
}

This JSON format is a lot more straight-forward than the Live Traffic API. The document starts with a summary of the route, and continues with an array of instructions. Each instruction has a clear set of parameters to store the data. All coordinates use the wide-spread WGS84 projection. It should be pretty easy to implement the API.

If you have any questions, don’t hesitate to use the comments section.

Disclaimer: This is not an official API, I am not a TomTom representative and I am not responsible for any mess you create. Use the API responsibly.