Autocomplete and Suggestions with the Search API
Tags: mapping, autocomplete, devops, api
Published: 2020-11-18 05:26:31

####Autocomplete and Suggestion With The Seacrch API 

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/0gvu1e0qv84oznaazryc.png)

We previously discussed the TomTom Search API a bit with our previous article, [Understanding Fuzzy Search](https://developer.tomtom.com/blog/decoded/understanding-fuzzy-search).

Today we are going to dive a little bit deeper and discuss our [Search Autocomplete API](https://developer.tomtom.com/search-api/search-api-documentation/autocomplete), 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:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/8yci96hbmc2tn7a34gux.png)

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: 

![Screen Shot 2020-11-17 at 8.53.36 PM](https://dev-to-uploads.s3.amazonaws.com/i/cd8xovjrbt2vulafba3w.png)
 
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: 

![Screen Shot 2020-11-17 at 9.04.07 PM](https://dev-to-uploads.s3.amazonaws.com/i/r3u8vxyi9zc25a0jrvw3.png) 

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](https://developer.tomtom.com/search-api/search-api-documentation/autocomplete) 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.*

*This article originally appeared on https://developer.tomtom.com/blog. The original author is [Magdalena Korczynska](https://developer.tomtom.com/blog/author/magdalena-korczynska)*.