Get Started
Hands-on with Optic

Hands-on with Optic

Get started by exploring Optic through an interactive demo. In this demo, you will:

  • Lint an OpenAPI spec
  • Diff an OpenAPI spec against a previous version
  • Check for breaking changes between two OpenAPI specs
  • Verify that an OpenAPI spec is accurate

Start by cloning the demo repo:

git clone

and installing Optic:

npm install -g @useoptic/optic

Viewing our spec

In the cloned demo repo, you will find an OpenAPI spec (openapi.yml) that describes an online bookstore and has a couple of endpoints for adding, getting, and updating books and authors.

Optic hosts your OpenAPI spec and keeps track of the history of your specification. You can view your API documentation and see how it has changed over time. To do this, you'll need to upload your OpenAPI spec to Optic.

First, log in to Optic:

optic login

Next, add your OpenAPI spec to Optic

optic api add openapi.yml --history-depth=0

--history-depth=0 will add all the history of this API to Optic, so you can see exactly how your API has changed over time, and see when breaking changes were introduced.

You should see that Optic has uploaded openapi.yml and is now being tracked.

Adding API ~/bookstore-example/openapi.yml
Optic Bookstore Demo Spec is now being tracked.

Click and follow the link in the output to be able to see your API and all of its history.


You will also notice that an x-optic-url has been added to your OpenAPI spec. This is how Optic keeps track of spec files in different places. Commit this change.

git add .
git commit -m "Add x-optic-url"

Linting an OpenAPI spec

This repo has 3 branches. Check out the first one which adds a GET /authors endpoint. Start by switching to the branch add-author-list-endpoint.

git checkout add-author-list-endpoint

Now lint the OpenAPI spec with optic lint:

optic lint openapi.yml
invalid openapi: paths > /author > get > responses > 200 must NOT have additional properties
112 | responses:
113 |   200:
114 |     description: Successfully fetched authors
115 |     application/json:
116 |       schema:
117 |         type: object
118 |         properties:

Oops - it looks like something is wrong with this OpenAPI spec. There is a missing content key where application/json should be.

Let's fix that:

112 | responses:
113 |   200:
114 |     description: Successfully fetched authors
+   |     content:
115 |       application/json:
116 |         schema:
117 |           type: object
118 |           properties:

Now rerun lint to confirm that the spec is fixed:

optic lint openapi.yml

Diffing API specs

Next, check out the add-type-to-book-request branch, which adds a type to the Books request:

git checkout add-type-to-book-request

Now, try running diff against main, and checking it against the API's standards:

optic diff openapi.yml --base main --check

The rules are configured in the optic.yml file in the repo. Learn more about how to configure your own API standards.

   FAIL  POST /books
    added rule [error]: prevent changing request property to required
      x cannot add a required request property 'type' to an existing operation. This is a breaking change.
      at paths > /books > post > requestBody > content > application/json > schema > properties > type (~/bookstore-example/openapi.yml:208:5096)

It looks like Optic has detected a breaking change here! Adding a new request body property that is required will break existing calls that don't include this request property. Make sure to fix this by setting a default value to type if it's not already set.


Optic also looks for a number of other common breaking changes, so you can rest easy and know you aren't accidentally adding breaking changes. You can see more about what breaking changes we detect in our GitHub repo (opens in a new tab)


Try adding the --web flag to this command - Optic will render the results in a web browser so you can see exactly what changed.

Now check out the last branch, add-dob-to-author, where the date of birth of authors is being added.

git checkout add-dob-to-author

Try running diff against main again, and checking it against the API standards.

optic diff openapi.yml --base main --check
   FAIL  PATCH /author/{author_id}
    added rule [error]: request property naming check
      x dateOfBirth is not snake_case
      at paths > /author/{author_id} > patch > requestBody > content > application/json > schema > properties > dateOfBirth (~/bookstore-example/openapi.yml:151:3939)

It looks like dateOfBirth isn't consistent with the naming rules for the API, because the standards are configured to require snake_case properties.


Optic isn't just an OpenAPI linter - Optic can be configured to run forwards only governance (i.e. only newly added endpoints will be affected by rules). This is useful when you have an existing API and want to incrementally standardize or roll out new rules. Read more in the forwards only checks guide.

Running in CI

Optic can be configured to run in CI so you don't need to worry about manually checking every change.

Here are some pull requests where Optic has been set up in CI with the examples from above:

Optic comments on pull requests with a preview of the API and a visual diff and can be configured to fail CI so that you can control how your API changes over time.

If you want to set up CI, follow the GitHub or GitLab guides.

Verifying your OpenAPI spec

Finally, it's time to verify that the API implementation matches the OpenAPI spec.

Switch back to the main branch:

git checkout main

If you haven't added openapi.yml to Optic yet, add it now.

optic login
optic api add openapi.yml --history-depth=0

For this tutorial, a server is running on Use this server to verify the implementation.


In this case, you're using a remote server, but you can route traffic anywhere whether that be a locally run server or your staging or production servers.

Start by making a request to the server to see what it responds with:


You should have gotten a list of books back from this endpoint. Now use Optic to capture traffic and use it to verify the implementation. To do this, you need to start Optic up to capture traffic:

optic capture openapi.yml --reverse-proxy

You should notice a message that says something like:

> Optic proxy is running at https://localhost:8000 - send traffic to this host. Traffic will be forwarded to and will be recorded

Any traffic sent to https://localhost:8000 will be forwarded to To get the list of books through the capture proxy, make a request to https://localhost:8000/books.


Optic runs a local reverse proxy server so that it can monitor requests and use that information to update or verify an OpenAPI spec.

Make a couple of other requests to capture some traffic you can use to verify the OpenAPI spec.

curl https://localhost:8000/books
curl -X POST https://localhost:8000/books --data '{"name": "Animal Farm", "author_id": "6nTxAFM5ck4Hob77hGQoL"}' --header 'Content-Type: application/json'
curl https://localhost:8000/books/123

Notice that Optic is capturing traffic as you make these requests:

» Optic proxy is running at https://localhost:8000 - send traffic to this host. Traffic will be forwarded to and will be recorded
 help  Press [ Enter ] to finish capturing requests
3 requests captured

You can also run Optic in system-proxy mode which will use the system proxy to capture traffic. This is useful for when you want to capture traffic in your web browser so you don't need to reroute requests to the Optic reverse proxy.

It looks like the OpenAPI spec is out of date with the API implementation.

  Diff   'name' is not documented
operation: post /books  
73 | application/json:
74 |   schema:
75 |     type: object
76 |     properties:  Undocumented 'name'
77 |       id:
78 |         type: string
79 |     required:
  Diff   'author_id' is not documented
operation: post /books  
73 | application/json:
74 |   schema:
75 |     type: object
76 |     properties:  Undocumented 'author_id'
77 |       id:
78 |         type: string
79 |     required:

The POST /books endpoint is returning two extra fields (name and author_id) - go ahead and use optic update to update the spec to match:

optic update openapi.yml --all

You should now see Optic has updated your OpenAPI spec. Confirm the updates by running optic verify:

optic verify openapi.yml

Great! You've confirmed the OpenAPI spec matches the API implementation. Go ahead and commit these changes:

git add .
git commit -m "Updated OpenAPI spec to match API response"

Finally, upload the spec to Optic Cloud.

optic verify openapi.yml --upload

Once you've uploaded this, you'll see in the spec in Optic that you've uploaded verification information to some of the endpoints.


Optic stores captured traffic in a temporary directory. If you want to clear out old traffic that you've collected, run the optic capture clear command.

What's next

In this tutorial you have:

  • Linted an OpenAPI spec
  • Diffed OpenAPI spec against a previous version
  • Run API checks against our OpenAPI spec
  • Verified the implementation of our OpenAPI spec

You've only scratched the surface of what Optic can do. Here's a list of things you might want to check out next: