21 comments

[ 3.4 ms ] story [ 80.0 ms ] thread
Author here. What a great surprise to see my article here. Any comments and suggestions are highly appreciated (since my page has no comment function yet).

Side note: I’m not using google analytics or anything privacy concerning on the page. I host my own instance of Ackee. That’s where I found HN as the top referrer.

Nice one. But I was a little confused: this is 'only' about Circ? Did you consider to investigate the other companies as well? Seems there are at least four more ;-) To really say something about 'scooters in Lisbon' and 'compare with other cities' more data is needed.

One could think the hardest part of starting a new scooter company these days is finding a differentiating color...

From the article:

Note: I was also trying to retrieve similar information for Lime scooters. However, the Lime API does not return a unique Scooter ID. For every request the returned scooter IDs are randomized (and internally they map them to their real IDs), which makes it impossible to track individual scooters.

One could also try the data of car sharers with floating fleets ("leave the car legally parked anywhere within their business area") like car2go.

Incidentally, in comparison with car sharing, I hate these scooters. With cars you have to park them legally or the you (the last renter) will have to pay the potential parking ticket. With scooters, people can easily lift and move them, so the last renter has plausible deniability if they parked idiotically. End result? They're all parked fucking idiotically.

> the Lime API does not return a unique Scooter ID. For every request the returned scooter IDs are randomized

How did you figure this out?

I’ve been playing with this scooter data for a while (Lime included) and I’ve always been able to correctly map scooter ID uniquely to a scooter at a location. Multiple requests will return the same scooter in the same location and I’ve always believed the same ID in a different place later meant the scooter actually moved.

When I was trying to retrieve the same data from Lime API as I did for Circ, I retrieved only unique scooter ids. Even after recording 24h. First I was puzzled, but then I realized that many different scooter ids are at exactly the same GPS coordinates (also same battery level, etc). That's how I reached my conclusion.

But I might be wrong about this. I'll give it a second try for confirmation.

It’s possible that Lime operates differently in Portugal than US, too.

Also, I had a look at your repository and it’s fantastic. Great work on this.

Great use of mitmproxy and data! Nice article!

Did you choose Lisbon for any particular reason?

I'm from Lisbon.

Lisbon is my 'home' since ~8 years. Since I know the place well I started there. But as suggested I would like to collect similar data for several (European) cities and compare the results. For example Lisbon has a very high tourists/locals ratio which can be a reason for the huge number of trips shorter than 1km.
Soooo...

> 1793 scooters

> 34671 scooter trips recorded

> 63322 km of scooter movement

over 111 days, at 1 EUR to unlock + 0,25 EUR/minute = 34671 EUR in unlock fees. Assuming each scooter covers an average of 15km/h, that's 254k minutes or 63k EUR in revenue.

Assuming each scooter costs 400 EUR, that's 717200 EUR for the scooters.

So about 14% return in ~4 (summer) months, excluding any promos, transaction costs or maintenance/juicing fees.

> excluding any promos, transaction costs or maintenance/juicing fees

Plus overhead of customer service and engineers to actually build/maintain the service and of course data plans to keep the scooters connected. These are almost certainly more than the 14% gross margin. Long-term profitability of these companies remains questionable at current activation/per-minute fee levels.

Maybe, but I kinda assume that the same fleet is rolled out across hundreds if not thousands of cities. It gets divided by a lot.

At least We can establish an upper ceiling on return.

An important cost factor is the 'juicer': the person that picks up, charges and returns the scooter to the street. They make a few euros per scooter per night. See for example https://www.ridester.com/lime-charger/

I remember reading somewhere a number of Euro 6,50 for a guy working somewhere in Europe. But cannot find that anymore.

I also wonder what the lifespan is. I regularly see damaged scooters and I think most are not well treated.

But in general I guess they potentially can make good money because otherwise there would not be so many.

How does mitmproxy work? Does it run on the phone or how can you read the https urls?
The normal chain is app > server.

Mitmproxy acts as a middleman. Typically you’ll run it on another device on the same network. app > proxy > server

Which means every time the app makes a GET request (for example) the proxy can log the url/ip as well as the parameters passed to the server.

Then, to get the data yourself, you use a web client like Curl (or Requests in Python) and send the same headers/auth/parameters as the app did. But now instead of returning it to the app, it’s in a format you can store/manipulate.

I understand that. My question is since this is https - encrypted http - how do you decrypt the traffic? Is there something running on the phone too? Otherwise you would need the server's private key, right?
I also once rented two for my girlfriend and me, to go on a trip for half an hour. Considering the distance and the costs for the two of us, an Uber would have been much cheaper (and faster). So that was my first and last experience.
Using certificate pinning would make using mitmproxy impossible. It would require someone to decompile the app and attempt to remove the pinning.