Today we say farewell to a legend in the API documentation space: Apiary.io is shutting its doors.
Apiary.io is a hosted API documentation solution a lot like Bump.sh. It was founded in 2011, bringing modern looking “Stripe-like” three column API documentation to teams which would otherwise have been documenting their API with a CMS or wiki. Seeing as OpenAPI didn’t exist then they created their own description format: API Blueprint. Swagger, the precursor to OpenAPI, was around in a very early JSON form, but API Blueprint was based on Markdown. This made it very easy to write, but was a lot harder for tooling to work with. Eventually OpenAPI won the format wars and Apiary added support for OpenAPI v2.0 and eventually added experimental v3.0 support, alongside API Blueprint.
Apiary was well respected for offering a solid SaaS product, and was well known for their open-source projects: Dredd and Gavel. These tools offered powerful testing functionality which helped teams ensure their API implementation matched the API description, which was foundational to bringing the API Design-first workflow to REST APIs. This API description-based testing would help point out discrepancies in a test suite instead of having complaints from users. These tools have both sadly been archived and will see no further development.
Why is Apiary shutting down?
As is so often the case in API industry, they have been assimilated by a giant corporation. Oracle bought Apiary back in 2017, and have been migrating users over to their “Oracle Cloud” offering for years. Paid Apiary plans had been deprecated since 2018, and now finally users are seeing banners on their dashboards telling them Apiary is finally turning off the lights September 9th 2025.
Do you really want to use Oracle Cloud?
Oracle Cloud is a large offering similar to Amazon Web Services: there’s a whole lot of stuff to sift through to get to the bit that you want, and all you wanted was API documentation. This shouldn’t be hard, and Apiary always focused on simplicity, but now it’s incredibly confusing to figure out where you’re meant to go or what you’re meant to do. It’s impossible to even find out how much it might cost, and you know what they say: if you have to ask, you can’t afford it.
Instead of messing with Oracle Cloud, Bump.sh is the perfect new home for API documentation.
- Bump.sh supports any Git workflows, no awkward syncing or conflicts.
- Bump.sh support OpenAPI v3.1, Oracle Cloud only supports OpenAPI v3.0.
- Bump.sh supports AsyncAPI, Overlays, and Webhooks, meaning you can describe more of your architecture on the same platform.
- Bump.sh integrates with powerful open-source solutions like Microcks for mocking and testing.
- Bump.sh is a small and friendly team, not a faceless corporation.
Migrating to Bump.sh
To get started with the migration, you have two options. We’ve prepared a conversion tool from API Blueprint to OpenAPI 3.1 to make the process quick and easy. You can also choose to go with a manual conversion. To make the process simple and fast, we’ve combined a set of existing tools that, when used together, deliver a particularly effective result.
Step 1: Convert Blueprint to OpenAPI
Option A: Use our conversion tool
We’re proud to publish a tool that automatically converts Blueprint definitions to OpenAPI 3.1. Discover more about it in the Github Readme.
Clone this repository, and replace original.apib
with your API Blueprint
downloaded from Apiary or wherever it happens to live.
git clone [email protected]:bump-sh-examples/apiblueprint2openapi.git
cd apiblueprint2openapi
cp ~/src/my-project/example-api/latest.apib ./original.apib
With this in place, run NPM installer as all the best/latest/current tooling for this happens to be JavaScript based.
npm install
npm run convert
The conversion script should create a few files in generated/
, with output
from two different conversion scripts so you can see which you prefer.
apib2openapi.yaml
- Using NPM moduleapib2openapi
to produce OpenAPI v3.0.apib2openapi.31.yaml
- Upgradedapib2openapi
output withopenapi-format
to produce OpenAPI v3.1 and generally tidied up.apispecconverter.yaml
- Using NPM moduleapib2openapi
to produce OpenAPI v3.0.apispecconverter.31.yaml
- Upgradedapib2openapi
output withopenapi-format
to produce OpenAPI v3.1 and generally tidied up.0.
This is probably a lot to think about so to keep it simple, you probably want to
use generated/apispecconverter.31.yaml
.
cp generated/apispecconverter.31.yaml ~/src/my-project/example-api/openapi.yaml
Want to see how they look with zero effort involved?
$ npm exec bump preview generated/apispecconverter.31.yaml
> Your preview is visible at: https://bump.sh/preview/9b563ce6-e1a5-4da6-8f5d-d51ae0b26c1d (Expires at 2025-06-27T17:49:34+02:00)
> * Let's render a preview on Bump.sh... done
Option B: Manual conversion
If you prefer a step-by-step approach, our guide below will walk you through the process—essentially mirroring what our conversion tool does.
1. Export API description from Apiary.io
If you are using Apiary.io, you will need to export your API description before the shutdown.
Seeing as Apiary.io supports API Blueprint and OpenAPI, you can export your API description in either format. Those of you with OpenAPI already will have an easier time, but if you are using API Blueprint, you will need to convert it to OpenAPI.
Download the API descriptions in whichever format to your local machine, or if you are using GitHub sync, you can just clone your repository and it’ll be in there.
2. Convert API Blueprint to OpenAPI
There are a few tools around for converting API Blueprint to OpenAPI. All the tools vary in quality and many are unmaintained as the API Blueprint ecosystem wandered off once Oracle bought it. Of all the tools which promise to convert API Blueprint to OpenAPI, the best results we found were using LucyBot’s api-spec-converter which can be installed via NPM.
npm install -g api-spec-converter
Then run the conversion with this command:
api-spec-converter \
--from api_blueprint --to openapi_3 -s yaml \
your-original-api-blueprint.apib > openapi.legacy.yaml
Did that work? If so, you now have an OpenAPI v3.0 document called openapi.legacy.yaml
. If not, you may need to try a different tool, like apib2openapi, or contact Bump.sh for help.
3. Upgrade OpenAPI to v3.1
Getting to OpenAPI v3.0 is a good start, but OpenAPI v3.1 is the latest and greatest, so why stop there?
A great tool to pull in next is OpenAPI Format, which will not just upgrade to OpenAPI v3.1, but can also be used to format the OpenAPI document, improving readability and fixing mistakes.
npm install -g openapi-format
The command to convert your OpenAPI v3.0 document to a much tidier v3.1 is as follows:
openapi-format openapi.legacy.yaml -o openapi.yaml --convertTo '3.1'
This will output a new OpenAPI document called openapi.yaml
which is formatted nicely and upgraded to the latest version.
Step 2: Validate OpenAPI with vacuum
Before we go any further, lets make sure this OpenAPI is valid. A great tool for this is vacuum, which will check your OpenAPI document for errors and inconsistencies, making sure we have a stable foundation to work from.
brew install daveshanley/vacuum/vacuum
vacuum lint --errors --details openapi.yaml
When I ran this command, vacuum was returning errors about operationId
being invalid. The conversion tool was creating operationId’s based off a title (e.g.: operationId: Get booking
) instead of something like operationId: get-booking
. You could delete all the operationId
lines, but they are handy for keeping URLs clear in documentation amongst other things. Seeing as we already have OpenAPI Format handy, let’s use that to fix this the problem.
Create a config files somewhere, like config.openapi-format.json
, and add the following content to it:
{
"sort": true,
"casingSet": {
"operationId": "kebab-case"
},
"generateSet": {
"operationIdTemplate": "<method>-<path>",
"overwriteExisting": true
}
}
That config file will tell OpenAPI Format to sort the document, convert operationId
to kebab-case, and generate it using the <method>-<path>
template, which will result in operationId: get-bookings
for the /bookings
endpoint.
openapi-format openapi.legacy.yaml -o openapi.modern.yaml --convertTo '3.1' --configFile config.openapi-format.json
That’s it! You now have a modern OpenAPI v3.1 document that is ready to be used in Bump.sh.
There is loads more you can do with OpenAPI Format, so take a look at the OpenAPI Format config options if you’d like to tweak it further.
Step 3: Upload to Bump.sh
npm install -g bump-cli
bump preview openapi.modern.yaml
This will upload your OpenAPI document to Bump.sh and generate a preview link. You can then view the preview in your browser to see how it looks.
Your preview is visible at: https://bump.sh/preview/9b563ce6-e1a5-4da6-8f5d-d51ae0b26c1d (Expires at 2025-06-27T17:49:34+02:00)
* Let's render a preview on Bump.sh... done
Step 4: Iteratively improve OpenAPI
The conversion process is not always perfect, but a larger problem is that API Blueprint didn’t have a lot of the features that OpenAPI has, so you may find that your OpenAPI document is missing some information.
For example, API Blueprint didn’t have a way to describe authentication. That felt like a huge admission at the time, and folks were working on it with API Blueprint RFC 002: Authentication, but seeing as that never got done you’ll likely have to add this all in manually.
OpenAPI v3.1 can describe all sorts of authentication and authorization via Security Schemes, so with a little bit of work you can add this in to your OpenAPI document.
Step 5: Contract testing with OpenAPI
Contract testing is usually a very boring and tedious process, but it is a very important one. It helps ensure that your API implementation matches the API description, and that any changes made to the API do not break existing functionality.
The way it is normally implemented, a bunch of people who just spent ages writing that a response should return various fields and types, then they have to write a bunch of tests to check that the API implementation matches the API description. This is a lot of work, and it is very easy to forget to write tests for every single endpoint, or to forget to update the tests when the API changes.
Instead, you can use the OpenAPI document as a source of truth for your API, and makes it nice and easy to compare the implementation to the API description. This is mainly done either using a contract testing tool like Microcks, or baking the contract testing into any existing test suite, like RSpec in Ruby, or Pest in PHP.
- Contract testing with Rails and RSpec with openapi_contract
- Contract testing with Laravel PHP and Pest with Spectator
For example, if you are using RSpec in Ruby, you can use the openapi_contract
gem to validate your API responses against the OpenAPI document. This will ensure that your API implementation matches the API description, and that any changes made to the API do not break existing functionality.
When I added the OpenAPI document to an Rails app, openapi_contract
offered a single assertion that could be slid into an existing RSpec test, to validate the API response against the OpenAPI document:
# spec/requests/widgets_spec.rb
require "rails_helper"
RSpec.describe 'Widgets Requests', type: :request do
describe "GET /widgets" do
it 'responds with 200' do
create_list(:widget, 3)
get '/widgets'
expect(response).to have_http_status(:ok)
expect(response).to match_openapi_doc(OPENAPI_DOC)
end
This match_openapi_doc
assertion will validate the response for that request to GET /widgets
, comparing what is actually returned with what was described in OpenAPI. If any part of the response does not match the API description (any property data is missing when required, wrong data types, unexpected properties have appeared, etc), it will fail the test.
I thought I was gonna be just fine adding this to an API, but it immediately failed with the following error:
1) Widgets Requests GET /widgets responds with 200
Failure/Error: expect(response).to match_openapi_doc(OPENAPI_DOC)
* 1 at `/0/id` is not a string
* 2 at `/1/id` is not a string
* 3 at `/2/id` is not a string
# ./spec/requests/widgets_spec.rb:15:in 'block (3 levels) in <top (required)>'
Oops! It turns out that the OpenAPI document was expecting the id
field to be a string, but the API implementation was returning an integer. This was not a mistake with the conversion, or with my OpenAPI, but it turns out my API was not doing different to what I thought it was doing. What everyone was told it was doing…!
Contract testing using the OpenAPI document is a such a great way to avoid mismatches between an API implementation and its documentation, whether using dedicated OpenAPI contract testing tools like Microcks, or integrating it into your existing test suite. Both methods help ensure that your API remains consistent and reliable, while also making it easier to catch issues early in the development process.
Traditional “code first” approaches pretend they solve this mismatch by keeping the OpenAPI description close to the code as annotations, but confusing proximity with accuracy often leads to mismatches creeping in with the false notion that developers will always keep things up to date just because it’s nearby. This is not the case, and the OpenAPI document should be treated as the source of truth for your API.
Whatever language/framework you’re using there is probably an option. Check OpenAPI.Tools to see if there is something that can do it.
Conclusion
Apiary.io has been a great tool for API documentation, but with its shutdown, it’s time to move on. Bump.sh is a modern alternative that supports OpenAPI v3.1, AsyncAPI, and more, making it a great choice for API documentation.
If you’re looking for a new home for your API documentation, Bump.sh is the perfect solution. With its powerful features, easy-to-use interface, and friendly team, Bump.sh is the ideal choice for API documentation.
If you have any questions or need help with the migration, feel free to contact us. We’re here to help you make the transition as smooth as possible.