Sorry, you need to enable JavaScript to visit this website.

Autocomplete and Suggestions with the Search API

TomTom’s Search API with Autocomplete enables you to provide more meaningful results to your application’s users.

 Autocomplete and Suggestion with the Search API 

search1

We previously discussed the TomTom Search API a bit with our previous article, Understanding Fuzzy Search.

Today we are going to dive a little bit deeper and discuss our Search Autocomplete API, a feature that allows you provide more meaningful results to your users without the need to track them.*

The autocomplete endpoint complements the ‘type ahead’ parameter in the Fuzzy search by providing related categories that the user might be looking for. Let’s review the explanation of this parameter from the documentation:

And when the search enters in Predictive Mode it provides also more matching results.

First, the Technical aspects of the API 

The documentation for this endpoint can be found in the developer portal: https://developer.tomtom.com/search-api/search-api-documentation/autocomplete  

This REST API Call uses HTTPS-GET and has minimum parameters: 

Required Parameters
Parameter Description

baseURL
string

The base URL for calling the API. 
Value: api.tomtom.com 

versionNumber
string

The service version. 
Value: The current value is 2

ext
string

An API Key valid for the requested service. 
Value: Your valid TomTom API Key

language
string

Language in which autocomplete results should be returned. 
Value: One of the TomTom supported IETF language tags. 

Let’s say we start looking for wine stores.  So, I start typing “wine”, and at the 4th character we decide to provide some suggestions. Since I am in Madrid, a sample call will look like this: 

https://api.tomtom.com/search/2/autocomplete/wine.json?key=<Your_API_Key>&language=en-GB&lat=40.41687&lon=3.70356 

Adding my private API key with the call, I get these results:

{
  "context": {
    "inputQuery": "wine",
    "geoBias": {
      "position": {
        "lat": 40.41687,
        "lon": 3.70356
      }
    }
  },
  "results": [
    {
      "segments": [
        {
          "type": "category",
          "value": "Wine & Spirits",
          "matches": {
            "inputQuery": [
              {
                "offset": 0,
                "length": 4
              }
            ]
          },
          "id": "9361025",
          "matchedAlternativeName": "Wine"
        }
      ]
    },
{
      "segments": [
        {
          "type": "category",
          "value": "Wine Bar",
          "matches": {
            "inputQuery": [
              {
                "offset": 0,
                "length": 4
              }
            ]
          },
          "id": "9379007",
          "matchedAlternativeName": "Wine"
        }
      ]
    },
    {
      "segments": [
        {
          "type": "category",
          "value": "Winery",
          "matches": {
            "inputQuery": [
              {
                "offset": 0,
                "length": 4
              }
            ]
          },
          "id": "7349",
          "matchedAlternativeName": "Wine"
        }
      ]
    }
  ]
}

Let’s examine the results: 

  1. I see 3 sections. 
  2. All of them are of the type “category”. 

According to the documentation, we can get 3 different types of results: Brands, Categories and Plaintext. 

For example, if we search for the term “jim” - assuming this refers to several brands, we can observe:

https://api.tomtom.com/search/2/autocomplete/jim.json?key=<API KEY>&language=en-GB&limit=10 
{
  "context": {
    "inputQuery": "jim"
  },
  "results": [
    {
      "segments": [
        {
          "type": "brand",
          "value": "Jim Thompson",
          "matches": {
            "inputQuery": [
              {
                "offset": 0,
                "length": 3
              }
            ]
          }
        }
      ]
    },
    {
      "segments": [
        {
          "type": "brand",
          "value": "Jimmy's Pizza",
          "matches": {
            "inputQuery": [
              {
                "offset": 0,
                "length": 3
              }
            ]
          }
        }
      ]
    },
    {
      "segments": [
        {
          "type": "brand",
          "value": "Jimmy John's",
          "matches": {
            "inputQuery": [
              {
                "offset": 0,
                "length": 3
              }
            ]
          }
        }
      ]
    },
{
      "segments": [
        {
          "type": "brand",
          "value": "Jimmy Chung's",
          "matches": {
            "inputQuery": [
              {
                "offset": 0,
                "length": 3
              }
            ]
          }
        }
      ]
    },
    {
      "segments": [
        {
          "type": "brand",
          "value": "Jimmy Choo",
          "matches": {
            "inputQuery": [
              {
                "offset": 0,
                "length": 3
              }
            ]
          }
        }
      ]
    }
  ]
}

There are several brands represented here based on our input; if we keep typing and we make a following query with “jimm”, we see: 

{
  "context": {
    "inputQuery": "jimm"
  },
  "results": [
    {
      "segments": [
        {
          "type": "brand",
          "value": "Jimmy's Pizza",
          "matches": {
            "inputQuery": [
              {
                "offset": 0,
                "length": 4
              }
            ]
          }
        }
      ]
    },
    {
      "segments": [
        {
          "type": "brand",
          "value": "Jimmy John's",
          "matches": {
            "inputQuery": [
              {
                "offset": 0,
                "length": 4
              }
            ]
          }
        }
      ]
    },
    {
      "segments": [
        {
          "type": "brand",
          "value": "Jimmy Chung's",
          "matches": {
            "inputQuery": [
              {
                "offset": 0,
                "length": 4
              }
            ]
          }
        }
      ]
    },
{
      "segments": [
        {
          "type": "brand",
          "value": "Jimmy Choo",
          "matches": {
            "inputQuery": [
              {
                "offset": 0,
                "length": 4
              }
            ]
          }
        }
      ]
    },
    {
      "segments": [
        {
          "type": "brand",
          "value": "Jimmy's Killer Prawns",
          "matches": {
            "inputQuery": [
              {
                "offset": 0,
                "length": 4
              }
            ]
          }
        }
      ]
    }
  ]
}

Now the brand “Jim Thompson” is gone from the list after tacking on more of the letter “m”, and we have a new “Jimmy’s Killer Prawns” brand name. 

Returning to our original query (wine), as specified in the documentation, I get only 5 results by default. I think I am going to need more than that for my users, so maybe I'll try 10 next time. 

Getting back to my first attempt, I already added some optional parameters (Lat and Long of most central place in Madrid: La Puerta del Sol). Next, we will go through some optional parameters. 

Optional parameters 

Let’s take a look at the optional parameters: 

Optional Parameters
Parameter Description

[limit]

Maximum number of autocomplete results that will be returned. Default value: 5 Max value: 10 

[lat]

Latitude, e.g., lat=37.337. It must be used in conjunction with the lon parameter. Results should be biased to the position defined by the lat, lon parameters.   

[lon]

Longitude, e.g., lon=-121.89. It must be used in conjunction with the lat parameter. Results should be biased to the position defined by the lat, lon parameters.

[raidus]

A radius in meters. It must be used in conjunction with lat, lon parameters. 

[countrySet]

A comma-separated string of country codes (e.g., FR,ES). This will limit the autocomplete results to the specified countries. 

[resultSet]

Restricts the result space based on their segment types 

So, let’s see what we get if we exchange the location area for the country (ES=Spain) and add a limit of 10 results. 

My new URL looks like: 

https://api.tomtom.com/search/2/autocomplete/wine.json?key=<API_KEY>&language=en-GB&countrySet=ES&limit=10 

And this time I get the following result: 

{
  "context": {
    "inputQuery": "wine"
  },
  "results": [
    {
      "segments": [
        {
          "type": "category",
          "value": "Wine Bar",
          "matches": {
            "inputQuery": [
              {
                "offset": 0,
                "length": 4
              }
            ]
          },
          "id": "9379007",
          "matchedAlternativeName": "Wine"
        }
      ]
    },
    {
      "segments": [
        {
          "type": "category",
          "value": "Wine & Spirits",
          "matches": {
            "inputQuery": [
              {
                "offset": 0,
                "length": 4
              }
            ]
          },
          "id": "9361025",
          "matchedAlternativeName": "Wine"
        }
      ]
    },
{
      "segments": [
        {
          "type": "category",
          "value": "Winery",
          "matches": {
            "inputQuery": [
              {
                "offset": 0,
                "length": 4
              }
            ]
          },
          "id": "7349",
          "matchedAlternativeName": "Wine"
        }
      ]
    }
  ]
}

And… it is exactly the same as before!  At least I see consistency. (These categories are in the DataBase for Spain.) With these 3 categories, I can present them to the user and if any of those are selected, we can take the “id” provided in the Segment and perform a normal POI category search. In this case I see that the category “Wine & Spirits" is the closest to what I want. 

I’ll make a quick category search and see what I get. 

We’ll use the POI search documentation here: https://developer.tomtom.com/search-api/search-api-documentation-search/category-search 

This time we are going to use the [lat, lon] for “Puerta del Sol” as a Bias guideline. 

https:// https://api.tomtom.com/search/2/categorySearch/.json?key=<API_KEY>&lat=40.41687&lon=-3.70356&categorySet=9361025 

Before we check the results, let’s examine this URL closely: 

  1. I didn’t pass any text in the query: I want all possible POIs in this category and close to this location. 
  2. The Category is added in the optional parameter “categorySet” 

Now this REST API Call gave some interesting results, and since it returns a minimum of 10, is good enough to present to the user. 

Let’s see the first item in the results: 

{
  "type": "POI",
  "id": "ES/POI/p0/1486801",
  "score": 1.21439,
  "dist": 295.90900560698543,
  "info": "search:ta:724009006287107-ES",
  "poi": {
    "name": "David Borda Juan Oscar",
    "categorySet": [
      {
        "id": 9361025
      }
    ],
    "categories": [
      "food drinks: wine spirits",
      "shop"
    ],
    "classifications": [
      {
        "code": "SHOP",
        "names": [
          {
            "nameLocale": "en-US",
            "name": "food drinks: wine spirits"
          },
          {
            "nameLocale": "en-US",
            "name": "shop"
          }
        ]
      }
    ]
  },
  "address": {
    "streetNumber": "9",
    "streetName": "Calle del Príncipe",
    "municipalitySubdivision": "Madrid",
    "municipality": "Madrid",
    "countrySecondarySubdivision": "Madrid",
    "countrySubdivision": "Comunidad de Madrid",
    "postalCode": "28012",
    "countryCode": "ES",
    "country": "España",
    "countryCodeISO3": "ESP",
    "freeformAddress": "Calle del Príncipe 9, 28012 Madrid",
    "localName": "Madrid"
  },
  "position": {
    "lat": 40.41593,
    "lon": -3.70029
  },
  "viewport": {
    "topLeftPoint": {
      "lat": 40.41683,
      "lon": -3.70147
    },
    "btmRightPoint": {
      "lat": 40.41503,
      "lon": -3.69911
    }
  },
  "entryPoints": [
    {
      "type": "main",
      "position": {
        "lat": 40.41593,
        "lon": -3.70035
      }
    }
  ]
}

As you can see there is a wealth of information related to this POI (Point of Interest), but point your attention to the the field named “categories”. This is an array of assigned categories that this Place relates to. If I can present this to the user, he or she can refine the autocomplete search to be improved in the future.

End notes 

The Autocomplete feature in the TomTom Search is an extremely valuable addition to the rest of our APIs. We saw in this small example how easy it can be to provide continuous search results to your application, so that the user can narrow their focus and get more specific results.  

Check out the many possibilities in our developer portal: developer.tomtom.com and don’t forget to add questions and comments in our forum: devforum.tomtom.com. 

Happy mapping… and searching! 


*Note: Privacy protection is paramount for TomTom, and all APIs available in the developer portal (developer.tomtom.com) keep this policy so your users can be reassured that all data collected is only to make our APIs better (and with your consent), and only out of necessity to perform the actions you require in your application.  

First published: 
Friday, December 6, 2019 - 22:49
Last edited: 
Friday, December 20, 2019 - 13:49