Updating APIs can be a tricky business. Whenever you modify an API, even if it’s a minuscule change to the code, you run the risk of breaking some existing functionality in an unintended way. So even if you’re fixing a minor bug, you want to make sure other working components in the API are left unharmed. Otherwise, you can cause issues in your customer’s integrations—and when that happens, you hear about it.
When introducing breaking changes to an API, you want your customers to keep the version they already have and update when they are ready—so they can test the changes in their own systems before releasing any changes downstream to their users. This is why making sure your API versioning doesn’t break is so critical. We have two systems in place for that: point-in-time API versioning coupled with API monitoring from Runscope. Monitoring our APIs with regression tests is critical to making sure that our API versioning processes are effective and deliver value to us and the end-user.
We consider ourselves an API-first company, which means that our product and the way we interface with customers is entirely by APIs. There’s an expectation that APIs will be online 24/7. If a customer uses Clearbit for a product integration and our APIs go down or something breaks, then that can trickle down and cause issues in the customer’s system—and that’s not good for anyone’s business. So, more important than the way that we version and improve on our APIs is the way that we ensure that they’re performing optimally, and at all times. For that, Runscope is a vital component to our business.
Three Versions of API Versioning
Basically, you have three ways to version an API:
The first (and most common) is to include the version in the request URL — for example, v1, v2, and so on — and route different API versions to different endpoints. This works well for occasional updates, but quickly gets unruly if you have a lot of API changes.
The second approach, which I’ve seen GitHub successfully using, is to send the version in the header of the request. This approach (similar to url versioning) is probably best for APIs that only introduce breaking changes once in a great while.
The third approach, which I’m not sure if Stripe invented, but they certainly made it popular, is what we call point-in-time versioning. How it works is, the first time a user makes a request to the API, that point-in-time (timestamp) gets saved alongside the account data and becomes their version until they choose to manually bump it to the current version.
With this approach, when a user calls an API for the first time, they don’t have to worry about versioning. They make their first API request, and we record the version they are using automatically. Now, every time a user calls an API, that API version is locked.
Point-in-Time Versioning: Not a Numbers Game Anymore
The point-in-time method is slightly more complex, but it has advantages. For instance, at Clearbit, it allows us to make adjustments within our codebase without having to create create new endpoints within our system. It also allows us to easily see which API versions our customers are using. Since we’re anticipating quite a few changes to our APIs in the future as we improve them, this approach works well for us.
This approach also allows us to do some interesting things in our API Docs and Dashboard (below). We can look at the current version and compare that to the customer’s time-stamp. Based on that comparison, we can let the customer know they are not on the current version and, because we keep a detailed change log, spell out exactly what changes were made since their point-in-time version.