You open a pull request, the docs build, and three days later staging rejects every request because the OpenAPI file has a dangling $ref pointing to a renamed path. The spec looked correct in the editor and rendered in Swagger UI, but it was not actually valid. A CLI validation step would have caught it before it shipped.
That is what a Swagger command-line workflow is for: catch broken specs before people or downstream systems do. In practice, “swagger cli” usually means @apidevtools/swagger-cli, an npm package with two useful commands:
-
validate: checks an OpenAPI or Swagger 2.0 document. -
bundle: turns a multi-file spec into one file.
This guide shows how to use swagger-cli, where it stops, and how to add live API testing with the Apidog CLI.
The workflow is:
- Validate and bundle the OpenAPI contract.
- Optionally lint it with a maintained tool like Redocly CLI.
- Run real API tests against the deployed service.
What “swagger cli” actually refers to
There is no single official swagger binary. The term usually points to one of these tools:
-
@apidevtools/swagger-cli: the package most developers mean. Its binary isswagger-cli. It validates OpenAPI / Swagger specs and bundles multi-file specs. -
swagger-codegen: a separate SmartBear project for generating client SDKs, server stubs, and docs from a spec. - Swagger UI and Swagger Editor: browser tools for rendering and editing specs, not CLIs. If you are still learning the format, start with this Swagger and OpenAPI primer.
This article focuses on command-line validation, bundling, linting, and API testing. For GUI-based design and testing platforms, see this Swagger alternatives roundup.
Install swagger-cli
Install the package globally:
npm install -g @apidevtools/swagger-cli
Confirm the binary is available:
swagger-cli --version
swagger-cli --help
You can also avoid a global install and run it with npx:
npx @apidevtools/swagger-cli validate openapi.yaml
That is useful in CI runners where you do not want persistent global packages.
One important note: @apidevtools/swagger-cli is deprecated. It still works and is still used in many pipelines, but new projects should consider Redocly CLI as the maintained successor. This article covers both.
Validate an OpenAPI spec with swagger-cli
Run:
swagger-cli validate openapi.yaml
If the spec is valid, the command exits with status code 0. If the spec is invalid, it prints an error and exits non-zero. That makes it easy to use in CI.
Example:
swagger-cli validate openapi.yaml
Typical issues this catches:
- Invalid YAML or JSON.
- Missing required OpenAPI fields.
- Broken
$refpointers. - Invalid document structure.
- Some OpenAPI specification rule violations.
You can disable either validation layer, although most projects should keep both enabled:
swagger-cli validate --no-schema openapi.yaml
swagger-cli validate --no-spec openapi.yaml
Use these only when you have a specific reason:
-
--no-schemaskips structural validation against the OpenAPI JSON Schema. -
--no-specskips OpenAPI specification rule checks.
For most pipelines, use the default:
swagger-cli validate openapi.yaml
Validation does not enforce style. A spec can pass validation while still having missing descriptions, inconsistent naming, weak examples, or unclear operation summaries. For team-specific rules, use a linter.
For a deeper comparison of validation options, see this guide on how to validate OpenAPI specs.
Bundle a multi-file OpenAPI spec
Many API specs are split across multiple files:
openapi.yaml
components/
schemas/
User.yaml
Error.yaml
parameters/
Pagination.yaml
That is easier to maintain, but many downstream tools expect a single file. Use bundle to create one distributable document:
swagger-cli bundle openapi.yaml -o dist/openapi.bundled.yaml -t yaml
Useful flags:
-
-o, --outfile <file>: write output to a file. -
-t, --type <json|yaml>: choose output format. Default isjson. -
-r, --dereference: inline every$ref. -
-f, --format <spaces>: control indentation. Default is2. -
-w, --wrap <column>: wrap long YAML strings.
A normal bundle keeps internal $ref pointers but pulls external files into one document:
swagger-cli bundle openapi.yaml -o dist/openapi.yaml -t yaml
A dereferenced bundle removes all $ref pointers by inlining referenced content:
swagger-cli bundle openapi.yaml -o dist/openapi.deref.yaml -t yaml --dereference
Use normal bundling for most distribution workflows. Use --dereference only when a specific consumer cannot resolve references.
A common build command is:
swagger-cli validate openapi.yaml && swagger-cli bundle openapi.yaml -o dist/openapi.json
The && ensures the bundle step only runs if validation succeeds.
Add swagger-cli to GitHub Actions
Validation is most useful when it runs automatically on every pull request.
Here is a minimal GitHub Actions workflow:
name: Validate OpenAPI spec
on:
pull_request:
paths:
- 'openapi.yaml'
- 'components/**'
jobs:
validate-spec:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- name: Validate spec
run: npx @apidevtools/swagger-cli validate openapi.yaml
Because swagger-cli validate exits non-zero on failure, the pull request check fails automatically.
If you also want to generate a bundled artifact:
name: Validate and bundle OpenAPI spec
on:
pull_request:
paths:
- 'openapi.yaml'
- 'components/**'
jobs:
openapi:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
- name: Validate spec
run: npx @apidevtools/swagger-cli validate openapi.yaml
- name: Bundle spec
run: npx @apidevtools/swagger-cli bundle openapi.yaml -o dist/openapi.yaml -t yaml
This gives you a fast contract gate before specs reach staging, docs, SDK generation, or consumers.
When validation is not enough
Validation answers:
Is this a legal OpenAPI document?
Linting answers:
Is this OpenAPI document good according to our team’s rules?
Those are different checks.
For example, this can still pass validation:
- Operations have no
summary. - Schema properties have no
description. - Paths use inconsistent naming.
- Error responses are missing examples.
- Operation IDs do not follow your naming convention.
swagger-cli does not enforce those rules because they are style and governance rules, not core OpenAPI validity rules.
For linting, use a tool such as Redocly CLI.
Migrate from swagger-cli to Redocly CLI
Install Redocly CLI:
npm install -g @redocly/cli
The validation equivalent is lint.
To get behavior close to basic validation:
redocly lint --extends=minimal openapi.yaml
To use the default recommended ruleset:
redocly lint openapi.yaml
You can configure rules in redocly.yaml:
extends:
- recommended
rules:
operation-summary: error
operation-operationId: error
no-unused-components: warn
Then run:
redocly lint openapi.yaml
Bundling is similar:
redocly bundle openapi.yaml -o dist/openapi.yaml
Common command mapping:
| swagger-cli | Redocly CLI |
|---|---|
swagger-cli validate openapi.yaml |
redocly lint --extends=minimal openapi.yaml |
swagger-cli bundle openapi.yaml -o dist/openapi.yaml |
redocly bundle openapi.yaml -o dist/openapi.yaml |
-o, --outfile |
-o, --output |
-t, --type |
--ext |
-r, --dereference |
-d, --dereferenced |
For a wider comparison, see this breakdown of the best OpenAPI validator tools.
Short version:
- Starting fresh? Use Redocly CLI.
- Already using
swagger-clisuccessfully? You can keep it, but plan a migration path.
What spec tools cannot test
swagger-cli validate checks that the file is valid.
redocly lint checks that the file follows rules.
Neither sends a request to your running API.
A spec can be valid while the implementation:
- Returns
500. - Omits a required field.
- Returns the wrong status code.
- Ignores a query parameter.
- Breaks authentication.
- Returns a response shape that no longer matches the contract.
To catch that, you need functional API tests: send real requests, then assert on status codes, headers, body fields, and business logic.
That is where Apidog fits into the workflow.
Apidog is an all-in-one API platform. You can import an OpenAPI spec and use it to create interactive docs, mock servers, and test scenarios. These guides show how to import Swagger or OpenAPI and generate runnable requests and how to generate full test collections from OpenAPI specs.
Run API tests from the terminal with Apidog CLI
Install the CLI:
npm install -g apidog-cli
Run a saved test scenario:
apidog run --access-token $APIDOG_ACCESS_TOKEN -t 605067 -e 1629989 -r cli
Flag overview:
-
--access-token: your Apidog access token. -
-t: test scenario ID. -
-e: environment ID. -
-r: report format, such ascli,html,json, orjunit.
For CI, junit is often useful:
apidog run \
--access-token $APIDOG_ACCESS_TOKEN \
-t 605067 \
-e 1629989 \
-r junit
Like spec validation tools, Apidog CLI exits with a status code that CI can use. If an assertion fails, the pipeline fails.
The difference is what gets checked:
-
swagger-cli: checks the OpenAPI file. -
redocly: checks the OpenAPI file and lint rules. -
apidog-cli: checks live API behavior.
For all flags and CI examples, see the Apidog CLI complete guide, or run:
apidog run --help
To create the first scenario, download Apidog, import your spec, and copy the runner command from the scenario’s CI/CD tab.
A complete terminal workflow
A practical API quality gate should check both the contract and the implementation.
Example:
# 1. Validate and lint the OpenAPI contract.
redocly lint --extends=minimal openapi.yaml
# 2. Produce one distributable OpenAPI document.
redocly bundle openapi.yaml -o dist/openapi.yaml
# 3. Run live API tests against the target environment.
apidog run --access-token $APIDOG_ACCESS_TOKEN -t 605067 -e 1629989 -r junit
In CI, that gives you three gates:
- The spec is valid.
- The bundled artifact can be generated.
- The running API behaves as expected.
You can use the same pattern with swagger-cli if you are not ready to migrate:
swagger-cli validate openapi.yaml &&
swagger-cli bundle openapi.yaml -o dist/openapi.yaml -t yaml &&
apidog run --access-token $APIDOG_ACCESS_TOKEN -t 605067 -e 1629989 -r junit
Each command exits non-zero on failure, so the whole chain can run as one CI job.
If you are replacing older spec-conformance tooling, this article on validating an API against its spec without Dredd covers the same contract-versus-implementation problem from another angle.
A note on swagger-codegen
Some developers searching for “swagger cli” actually need swagger-codegen.
That is a different tool. It reads an OpenAPI spec and generates:
- Client SDKs.
- Server stubs.
- API documentation.
It is useful when you want to bootstrap typed clients or server interfaces from a published contract.
But it does not replace validation, linting, or live API testing. Code generation assumes the input spec is already correct. If the spec is broken, the generated output usually carries those problems forward.
A safer codegen workflow is:
# Validate or lint first.
redocly lint openapi.yaml
# Bundle if the generator expects one file.
redocly bundle openapi.yaml -o dist/openapi.yaml
# Then run code generation.
swagger-codegen generate -i dist/openapi.yaml -l typescript-fetch -o generated/client
Use codegen after your contract checks, not instead of them.
Top comments (0)