Where's my Voi scooter: [1] Starting my journey


4 min read

Somebody used the Voi scooter parked in front of my place, I want to know where it is now.


I got into using Voi scooter recently. It is a scooter hiring service where you can use scooters parked on the street. To use the same scooter and go out again the next day, I usually park my scooter outside my place. However, it keeps being taken by someone else. While it is allowed, I find it annoying to have to find a scooter elsewhere. Therefore I decided to make a program to find where did the scooter go.

How I researched this topic

Finding an API (Application Programming Interface)

Voi scooters' locations are public. Every single scooter's location is shown on the map when you open the Voi app. Hence I decided to find out if there is an API for that so I don't have to fetch the data manually. I googled "Voi API", and it took me to a documentation site for Voi where I found a webpage Mass light that contains information about an MDS and GBFS V1,2 API.

I decided to stop and see if anyone has done anything similar before, so I don't reinvent the wheel (although that would still be a learning journey). Luckily, I found an article where Héctor Martos shared how he tracked a Voi scooter's journey. He found the API by using a proxy and the Voi app, then repeatedly fetched data from it. Unfortunately, he didn't include what the API is and how to use it.

I also did some further research but found no other useful information, therefore this is all I had.

Going back to Voi documentation

Going back to Mass Light. I need to authenticate myself with a bearer token in order to query their MDS data. But I didn't know how to get one, I didn't even know what MDS is, it turns out MDS is Mobility Data Specification, by Open Mobility Foundation. It hopes to use location data of vehicles to help make better decisions. I searched their website and there is no information on how to access the data. So I went back to Mass Light, I saw this code snippet to get an access token:

$ curl -X POST -u user:password
  -d grant_type=client_credentials
  -H "Content-Type:application/x-www-form-urlencoded"

So I tried it. It didn't work because I need a username and password, which I don't have. So I figured this API is not for normal users. It would have been helpful if they stated this from the start.

Found a Github page on using the Voi API

I went back to find related information, and that is when I stumbled upon this Github page, where Constantin left a tutorial on how to query the Voi API.

So I made a python script following the instruction:

import requests
url = "http://api.voiapp.io/v1/auth/verify/phone"
# fake country code and phone number
obj = {"country_code": "AB",
       "phone_number": "0123123123"}
re = requests.post(url, json=obj)

However, I got an <Response [405]>, and it is until later that I found out I had to use https instead of http, another thing that I learned is that the country code for the UK is GB.

After fixing that, I was able to get a response and an SMS verification code, I then followed the steps on the page and successfully verified myself. I did skip the Get first authToken step, I think because I already registered with Voi with my phone number. I know because later when I tried to use the Voi App, I had to authenticate again, so I will need another number to continue this project if I still want to ride Voi with my phone number.

Finding out the zones code

Voi scooters serve 76 cites. It would be impossible that they tell you where every single scooter is, therefore I have to first get the zones code for my city before I can start asking the API where the scooters are.

url = "https://api.voiapp.io/v1/zones"
re = requests.get(url, headers={"x-access-token": accessToken})

This gave me a huge JSON (JavaScript Object Notation) object, but with the power of control+f, I quickly found the zones code for my city and can start querying the location of scooters.

Making my first vehicle location request

I then made my first request

url = f"https://api.voiapp.io/v2/rides/vehicles?zone_id={my_zone_id}"
re = requests.get(url, headers={"x-access-token": accessToken})

It again gave me a huge JSON object, with the format being:


Here we can see each scooter has an ID, and location in terms of longitude and latitude. The scooters here seem to be the ones parked.

What I plan to do in the future

With these data, I plan to find a way to repeatedly query and record the vehicle location data so that I can further analyse them over time.

I also plan to see if it is possible to track the live location data of the scooters, as done in Héctor Martos's article.