Overview
Bruno supports importing OpenAPI (formerly Swagger) specifications to quickly generate API collections. Convert your API documentation into testable requests with a single command.
Importing OpenAPI Specifications
Basic Import
Import an OpenAPI file to a Bruno collection:
bru import openapi --source api.yml --output ~/Desktop/my-collection --collection-name "My API"
Import Options
The bru import openapi command supports various options:
Option Alias Description --source-sPath to the source file or URL (required) --output-oPath to the output directory --output-file-fPath to the output JSON file --collection-name-nName for the imported collection --insecure- Skip SSL certificate validation when fetching from URLs
Import Methods
From Local File
From URL
Export as JSON
Import from a local OpenAPI file: bru import openapi \
--source api.yml \
--output ~/Desktop/my-collection \
--collection-name "My API"
Import directly from a URL: bru import openapi \
--source https://example.com/api-spec.json \
--output ~/Desktop \
--collection-name "Remote API"
For URLs with self-signed certificates: bru import openapi \
--source https://localhost:8443/swagger.json \
--output ~/Desktop/api \
--collection-name "Local API" \
--insecure
Export the collection as a JSON file instead of a directory: bru import openapi \
--source api.yml \
--output-file ~/Desktop/my-collection.json \
--collection-name "My API"
This creates a single JSON file containing the entire collection.
Programmatic Usage
Use the @usebruno/converters package in your code:
Installation
npm install @usebruno/converters
Convert OpenAPI to Bruno
const { openApiToBruno } = require ( '@usebruno/converters' );
const fs = require ( 'fs/promises' );
const YAML = require ( 'js-yaml' );
async function convertOpenAPISpec () {
try {
// Read OpenAPI specification
const specContent = await fs . readFile ( 'api-spec.yaml' , 'utf8' );
const openApiSpec = YAML . load ( specContent );
// Convert to Bruno collection
const brunoCollection = openApiToBruno ( openApiSpec );
// Save Bruno collection
await fs . writeFile (
'bruno-collection.json' ,
JSON . stringify ( brunoCollection , null , 2 )
);
console . log ( 'OpenAPI import successful!' );
} catch ( error ) {
console . error ( 'Error during conversion:' , error );
}
}
convertOpenAPISpec ();
What Gets Imported
Bruno’s OpenAPI importer extracts the following:
Endpoints
All API endpoints with their HTTP methods (GET, POST, PUT, DELETE, etc.)
Parameters
Path parameters
Query parameters
Header parameters
Request bodies
Authentication
API Key authentication
Bearer token authentication
Basic authentication
OAuth2 flows
Organization
Requests are grouped by:
Tags (if defined in OpenAPI spec)
Paths (automatic grouping by path structure)
Server URLs
Base URLs from the servers section are converted to environment variables
Import Grouping Strategies
Bruno supports different ways to organize imported endpoints:
Tag-Based Grouping Groups endpoints by OpenAPI tags: my-collection/
├── Users/
│ ├── GET List Users.bru
│ └── POST Create User.bru
└── Posts/
├── GET List Posts.bru
└── POST Create Post.bru
Path-Based Grouping Groups endpoints by URL path structure: my-collection/
├── api/
│ ├── users/
│ │ ├── GET users.bru
│ │ └── POST users.bru
│ └── posts/
│ ├── GET posts.bru
│ └── POST posts.bru
Example OpenAPI Import
Given this OpenAPI specification:
openapi : 3.0.0
info :
title : Sample API
version : 1.0.0
servers :
- url : https://api.example.com/v1
description : Production server
- url : https://staging.example.com/v1
description : Staging server
paths :
/users :
get :
summary : List all users
tags :
- Users
parameters :
- name : limit
in : query
schema :
type : integer
responses :
'200' :
description : Successful response
post :
summary : Create a new user
tags :
- Users
requestBody :
required : true
content :
application/json :
schema :
type : object
properties :
name :
type : string
email :
type : string
responses :
'201' :
description : User created
/users/{userId} :
get :
summary : Get user by ID
tags :
- Users
parameters :
- name : userId
in : path
required : true
schema :
type : string
responses :
'200' :
description : User details
components :
securitySchemes :
bearerAuth :
type : http
scheme : bearer
bearerFormat : JWT
security :
- bearerAuth : []
Running the import:
bru import openapi -s openapi.yaml -o ~/Desktop/sample-api -n "Sample API"
Creates this structure:
sample-api/
├── bruno.json
├── environments/
│ ├── Production.bru
│ └── Staging.bru
└── Users/
├── GET List all users.bru
├── POST Create a new user.bru
└── GET Get user by ID.bru
Generated request file:
Users/GET List all users.bru
meta {
name: List all users
type: http
seq: 1
}
get {
url: {{baseUrl}}/users?limit=10
body: none
auth: inherit
}
params:query {
limit: 10
}
auth:bearer {
token: {{accessToken}}
}
Environment Variables
Imported collections automatically create environment variables:
environments/Production.bru
vars {
baseUrl: https://api.example.com/v1
accessToken: your_token_here
}
vars {
baseUrl: https://staging.example.com/v1
accessToken: your_staging_token
}
Authentication Import
Bruno maps OpenAPI security schemes to authentication types:
Bearer Token
API Key
Basic Auth
OAuth2
OpenAPI: securitySchemes :
bearerAuth :
type : http
scheme : bearer
Bruno: auth:bearer {
token: {{accessToken}}
}
OpenAPI: securitySchemes :
apiKey :
type : apiKey
in : header
name : X-API-Key
Bruno: headers {
X-API-Key: {{apiKey}}
}
OpenAPI: securitySchemes :
basicAuth :
type : http
scheme : basic
Bruno: auth:basic {
username: {{username}}
password: {{password}}
}
OpenAPI: securitySchemes :
oauth2 :
type : oauth2
flows :
authorizationCode :
authorizationUrl : https://example.com/oauth/authorize
tokenUrl : https://example.com/oauth/token
Bruno: auth:oauth2 {
grant_type: authorization_code
callback_url: http://localhost:3000/callback
authorization_url: https://example.com/oauth/authorize
access_token_url: https://example.com/oauth/token
}
Request Body Mapping
OpenAPI request bodies are converted to Bruno body formats:
meta {
name: Create User
type: http
}
post {
url: {{baseUrl}}/users
body: json
auth: inherit
}
body:json {
{
"name": "John Doe",
"email": "[email protected] "
}
}
Bruno supports importing from multiple API specification formats:
OpenAPI 3.0 Full support for OpenAPI 3.0.x specifications in YAML or JSON format.
Postman Collections bru import postman -s collection.json -o output/
Insomnia bru import insomnia -s insomnia.json -o output/
WSDL bru import wsdl -s service.wsdl -o output/
Post-Import Steps
Review Generated Requests
Open the collection in Bruno and review all imported requests for accuracy.
Update Environment Variables
Fill in authentication tokens and other environment-specific values: vars {
baseUrl: https://api.example.com
accessToken: your_actual_token_here
apiKey: your_api_key
}
Add Tests
Enhance requests with test assertions: tests {
test("Status is 200", function() {
expect(res.status).to.equal(200);
});
test("Response has users array", function() {
expect(res.body.users).to.be.an('array');
});
}
Customize Request Bodies
Update example values with real test data:
Organize Folders
Reorganize requests into a structure that makes sense for your team.
CI/CD Integration
Automate OpenAPI imports in your pipeline:
.github/workflows/import-openapi.yml
name : Import OpenAPI Spec
on :
push :
paths :
- 'api-spec/openapi.yaml'
jobs :
import :
runs-on : ubuntu-latest
steps :
- uses : actions/checkout@v6
- name : Setup Node.js
uses : actions/setup-node@v5
with :
node-version : '20'
- name : Install Bruno CLI
run : npm install -g @usebruno/cli
- name : Import OpenAPI Spec
run : |
bru import openapi \
--source api-spec/openapi.yaml \
--output bruno-collection \
--collection-name "API Tests"
- name : Commit Updated Collection
run : |
git config user.name github-actions
git config user.email [email protected]
git add bruno-collection/
git diff --quiet && git diff --staged --quiet || git commit -m "Update Bruno collection from OpenAPI spec"
git push
Best Practices
Keep OpenAPI spec as source of truth
Maintain your OpenAPI specification separately and re-import when it changes. This ensures your tests stay synchronized with your API documentation.
Version control your imports
Commit both the OpenAPI spec and the generated Bruno collection to Git: project/
├── api-spec/
│ └── openapi.yaml
└── bruno-tests/
├── bruno.json
└── requests/
The import creates a foundation. Add:
Test assertions
Pre-request scripts
Post-response scripts
Example data
Documentation notes
Handle circular references
Bruno automatically handles circular references in OpenAPI schemas, converting them to simplified structures.
Use tags for organization
Troubleshooting
Error: Failed to parse OpenAPI specification Ensure your OpenAPI file is valid YAML or JSON. Use a validator like Swagger Editor to check for syntax errors.
Missing authentication in requests Check that your OpenAPI spec includes a security section. Bruno can only import authentication if it’s defined in the specification.
Large specifications For very large OpenAPI specs (100+ endpoints), consider importing to a JSON file first, then selectively extracting the endpoints you need.
Next Steps
After importing your OpenAPI specification: