Enabling Integration, Collaboration, and Innovation with the Strava API

This is the fifth post in Strava’s Intern Blog Series, where we give interns the opportunity to talk about the projects that they’ve been working on.

I remember finding out about Strava in high school while I was working as a salesman at Mike’s Bikes in Berkeley. I had just started doing some local crits and I wanted to know how the pros trained. I looked at their Strava profiles and thought the data must have been fake. Thirty hours of riding in one week? Eighteen miles per hour average? And then there were segments. I was hooked.

This summer I am working on the Strava API. My experience is probably a little different than most Strava engineering interns because I am on the Business Development Team, not a vertical team (cross-functional teams organized around features). My manager Mateo has one of the coolest jobs at Strava; he is Strava’s Head of Integration, which means he gets sent every cool new device before it is released. He knows the industry, devices, and our developer community better than anyone. My technical mentor Pan is one of Strava’s most senior Ruby engineers and his Blog About Code pops up in about half of my Google searches; I am lucky to have Pan review my code and provide technical feedback everyday. The Strava API Team is small but mighty, which means that I have ownership over a lot of different projects.

For me, working on the Strava API has meant:

  • Enhancing the Application model and requiring app icons to improve the Strava API Directory and drive app adoption
  • Increasing the value of the API by creating new endpoints
  • Improving API scalability and maintainability with new and updated admin tools to enable app permissions and track activities uploaded by the API
  • Collaborating with partners and device manufacturers to enable new integrations and business opportunities
  • Becoming the point-of-contact for external developers

So where did I start five weeks ago?

Enhancing the Application Model

My first task this summer was to enhance our Ruby on Rails StravaOAuth::Application model, the model which Strava uses to represent an application that consumes our API. Previously, app owners were not required to upload app icons; this made it difficult for athletes to identify external apps and resulted in a lot of engineering overhead to ensure that the Strava API Directory was populated with apps that had icons. It was also responsible for at least one sad screenshot of an app authorization without an icon in an article written about Strava’s new Premium Perks feature:

App authorization with no icon

I built a new webpage for app owners to upload an app icon and updated our application controller logic so that app owners are redirected to this new page whenever they try to view or edit their app settings but have not uploaded an icon, after they delete an icon, and immediately after app creation. Now, no overhead is required to ensure that our beautiful Strava API Directory continues to looks its best:

The Strava API Directory

In addition to updating application picture logic, I also added client and server-side validations to ensure that people are not uploading malicious content to our servers and that app names comply with our Brand Guidelines (for instance, you are not allowed to have “Strava” in your app name!).

API Audit

I also conducted an audit of all of Strava’s API endpoints. Have you ever run rake route on an eight-year-old production Rails app? Here’s what it looks like:

API routes from our Rails app

The list goes on. As of July 19, 2017, there were 280 API endpoints and I looked at every single one of them. An audit may sound mundane, but that was not my experience. I took it as an opportunity to learn about the ins and outs of the Strava API and to observe how code, technologies, and ideologies have changed at Strava through the years. I found duplicate endpoints, endpoints that were hardcoded for old partners, inappropriate HTTP GET requests, and several undocumented endpoints with really cool functionality.

One actionable takeaway from my audit was to establish a standard for app permissions and access tokens, designating which apps have access to newly minted features, and which apps have the ability to view private data or write to Strava. Strava has app permissions and access tokens, and even internally the difference between the two is often confused:

  • Access tokens determine if an app has access to private data or can write to Strava. When you want to authorize an app to have access to your Strava account, the app redirects you to the Strava App Authorization Page, where, depending on the type of access token that app is requesting, you are alerted about which pieces of data that app will be able to receive.
  • App permissions are assigned by Strava on a per-app basis to give those apps access to bleeding-edge features, like webhook events and Strava Beacon.

Without guidelines, it is tough for web engineers who contribute to the API on a per-feature basis to notice inconsistencies in our implementation of app permissions and access tokens across our enormous Rails application. Moving forward, Strava now has a solid set of standards for adding new API endpoints. As a low-level best practice, any route with an HTTP verb other than GET should probably require a write access token.

Integrating with Partners and External Developers

Most of the features I have been working on with our partners have not been released yet, so I will have to leave specifics to the reader’s imagination. However, I will say that creating new API functionality and then getting to test it out on devices that have not yet been released is awesome. I get to go to meetings with our top-tier partners everyday and see Strava’s future. It is still hard for me to believe that I am able to make a meaningful contribution to the software that all of my friends and fellow cyclists will be using in six months.

Another aspect of my job is responding to questions and requests from the developer community. I bump rate limits, enable app permissions, and find out about all of the cool things people are doing with Strava data. Developers are appreciative that Strava has a public API and that we respond quickly to their requests, but working with the public is a double-edged sword.

Recently we had to make a last-minute change to our authorization flow because the detailed Athlete representations that we returned on successful token exchange were so large that they were crashing authorizations for one of our partners. A product was scheduled to be released the next day, so we made the call to switch the detailed Athlete representation to a smaller summary representation. Of course, the summary representation contains fewer data fields than the detailed representation, and with no notice given, we broke a few external apps.

The feedback we received from the developer community was that the change was unfair and unprofessional since it was not backward compatible and we had not given prior notice. We did not expect that there would be many apps with authorization flows that relied on data that was uniquely available to the detailed Athlete representation, but even developers who were not directly affected by the update wrote in to voice their disagreement with our decision on principle.

I learned a lot from changing the authorization flow. To prevent a botched product release from our partner that did not cause other apps to break, we instead could have added an optional parameter for that partner to receive a summary Athlete representation instead of the default detailed representation. At a higher level, I learned that it is important to give ample notice to our developer community across multiple channels before making changes that could affect their apps. I also learned that Strava’s reputation holds substantial weight with those developers, and it makes me proud to provide the best Strava API experience possible.

What I am Working on Now: Webhooks

Right now, I am working on adding a new webhook event type for activity updates. The major advantage of webhooks is that we are able to send data to apps instead of having them programmatically poll for updates; this means fewer API calls to Strava and real-time updates for API apps. The Strava API currently supports webhooks for activity creation events, but not for other event types. We want app owners to be able to know when athletes change an activity title, upload photos, etc., and that will all be possible with our new webhooks system.

I would like to thank my technical mentors Mateo, Pan, and Micah for their tireless support and commitment to help me become a better engineer. I would also like to thank David, Balazs, Kate, Pete, and Davy for showing me the ropes of business development and for making me feel like I was an important part of the team from day one.