Postman collection to OpenAPI specs

🛸 Convert Postman Collection v2.1 and v2.0 to OpenAPI v3.0, or in other words, transform this specification and also this one to this one

build codecov npm version CodeQL

Index

Features at a glance

  • Postman Collection v2.1 and v2.0.
  • OpenApi 3.0
  • Cli available
  • 🆕 Postman variables automatically replaced.
  • Basic info API from Postman info or customizable.
  • Basic method conversion (GET, POST, PUT…).
  • Support Postman folders as tags.
  • Transform query, headers and path parameters (description, required…).
  • Postman variables as Path parameters.
  • Automatic infer types from query and headers parameters.
  • Support postman “raw” body (Json and Text), “form-data” and “x-www-form-urlencoded”.
  • Postman Authorization parse or by configuration (Basic and Bearer).
  • Contact and License from variables or by configuration.
  • Provide meta-information as a markdown table.
  • Path depth configuration.
  • API Response parse from postman examples and from test code (status code).
  • x-logo extension support.

See Features section for more details about how to use each of this features.

Install

To use local in your Node.js project as a library

npm i postman-to-openapi --save

To use as a cli

npm i postman-to-openapi -g

Usage

As library

Use the library is as easy as use a single method async postmanToOpenApi(input, outputPath, options), the parameters are:

Param Description
input String. Path of the Postman collection file or value of the postman collection as String.
outputPath String. Path of the output file where the OpenAPi will be stored. This param is optional if not provided (undefined or null) no file will be saved.
options Object. Optional configuration, see options section for a detailed description.

The method return a promise string that contain the yml OpenAPI specification, only is saved to a file if the outputPath parameter is provided.

An example of usage:

const postmanToOpenApi = require('postman-to-openapi')

const postmanCollection = './path/to/postman/collection.json'
const outputFile = './api/collection.yml'

// Async/await
try {
    const result = await postmanToOpenApi(postmanCollection, outputFile, { defaultTag: 'General' })
    // Without save the result in a file
    const result2 = await postmanToOpenApi(postmanCollection, null, { defaultTag: 'General' })
    console.log(`OpenAPI specs: ${result}`)
} catch (err) {
    console.log(err)
}

// Promise callback style
postmanToOpenApi(postmanCollection, outputFile, { defaultTag: 'General' })
    .then(result => {
        console.log(`OpenAPI specs: ${result}`)
    })
    .catch(err => {
        console.log(err)
    })

As cli

After install just need to

p2o ./path/to/PostmantoCollection.json -f ./path/to/result.yml -o ./path/to/options.json

All the field described in options can be provided and used in the cli, for more info an all the available options just check the cli help

p2o -h

See demo in next gif:

Cli demo gif

Options

The third parameter used in the library method is an options object containing the optional parameters for the transformation, the allowed parameters are:

Param Description
info Basic API information
defaultTag Values of the default tag object.
pathDepth Number of subpaths that should be part of the operation path.
auth Global authorization definition object.
servers Server list for the OpenApi specs.
externalDocs Info about the API external documentation.
folders Config object for folders and nested folders in postman collection.
responseHeaders Indicate if should parse the response headers from the collection examples.
replaceVars Boolean value to indicate if postman variables should be replaced.
additionalVars Object to provide additional values for variables replacement.

info (Object)

The basic information of the API is obtained from Postman collection as described in section default info, but you can customize this parameters using the info options that can contain the next parameters:

Param Description
title String. The title of the API.
version String. The version of the OpenAPI document.
description String. A short description of the API.
termsOfService String. A URL to the Terms of Service for the API. MUST be in the format of a URL.
contact Object. The contact information for the exposed API. See details in License and Contact configuration section.
license Object. The license information for the exposed API.See details in License and Contact configuration section.
xLogo Object. Contain the info for the x-logo extension defined by redoc

Basically this are the required and relevant parameters defined in OpenAPI spec info object, an example of the option will be:

{
    info: {
        title: 'Options title',
        version: '6.0.7-beta',
        description: 'Description from options',
        termsOfService: 'http://tos.myweb.com',
        license: {
            name: 'MIT',
            url: 'https://es.wikipedia.org/wiki/Licencia_MIT'
        },
        contact: {
            name: 'My Support',
            url: 'http://www.api.com/support',
            email: 'support@api.com'
        },
        xLogo: {
            url: 'https://github.com/joolfe/logoBanner.png',
            backgroundColor: '#FFFFFF',
            altText: 'Example logo'
        }
    }
}

defaultTag (String)

By default the tag value “default” is added to all the operations during transformation, unless this operations are inside a folder as described in section folder as tags.

If you want to customize the default tag use the options defaultTag to indicate the desired value.

const result = await postmanToOpenApi(postmanCollection, outputFile, { defaultTag: 'API' })

pathDepth (number)

Sometimes the URL of an API depends of environments prefix or accounts id that are not part of the resource path, as for example http://api.io/dev/users, http://api.io/acc/235647467/users or http://api.io/v2/users, by default this will results in Paths as /dev/users, /acc/235647467/users and /v2/users.

To indicate the library that you want to avoid this prefixes to be part of the OpenAPI operation path you can use the pathDepth option, this option is a integer value that indicates how many paths/prefixs should be jump in the parse from the domain, as an example:

// Having a postman request with the url "http://api.io/dev/users"
const result = await postmanToOpenApi(postmanCollection, outputFile, { pathDepth: 1 })
// Will result in a path of "/users"
const result = await postmanToOpenApi(postmanCollection, outputFile, { pathDepth: 0 })
// Will result in a path of "/dev/users"

The default value is 0, so all prefix will be added to Open APi operations Paths.

auth (Object)

The global authorization info can be parse from the Postman collection as described in Postman authorization section, but you can customize this info using the auth option, this param is a Object that follow the structure of OpenAPI Security Scheme, in this moment only type http is supported and schemes basic and bearer, as an example of this option:

{
    myCustomAuth: {
        type: 'http',
        scheme: 'bearer',
        bearerFormat: 'A resource owner JWT',
        description: 'My awesome authentication using bearer'
    },
    myCustomAuth2: {
        type: 'http',
        scheme: 'basic',
        description: 'My awesome authentication using user and password'
    }
}

servers (Array)

The global servers list can be parse from the Postman collection as described in Global servers configuration section, but you can customize this info using the servers option, this param is an array of objects that follow the structure of OpenAPI Server Objects, only url and description field are supported in this moment, as an example of how to use this option:

{
    servers: [
    {
        url: 'https://awesome.api.sandbox.io',
        description: 'Sandbox environment server'
    },
    {
        url: 'https://awesome.api.io',
        description: 'Production environment server'
    }
    ]
}

externalDocs (Object)

The info about the API external documentation, as described in OpenAPI spec External Docs Object, as an example of how to use this option:

{
    externalDocs: {
        url: 'https://docs.example.com',
        description: 'Find more info here or there'
    }
}

This info can be provided as collection variables in the same way as described in section License and Contact configuration, you can setup the variables externalDocs.url and externalDocs.description for provide the information.

folders (Object)

This library support the use of folders and nested folders as OpenAPI tags, see Folders as tags section for more info, with this options you can configure the behavior of the tags calculation when there exist multiple level of folders in the Postman collection, the fields inside folders object are:

Param Description
concat Boolean. Indicated if in case of multiple levels of folders the tag used in the request is a concatenation of the folders name. Default value true.
separator String. Separator used to concatenate the names of the different folders. Default value ` > `

If we have a Postman collection with an structure as:

|- Domestic Payments (folder)
    |- Consent (folder)
        |- request 1
    |- request 2
|- Scheduled payments (folder)
    |- Consent (folder)
        |- request 3
    |- request 4

The tags for each request would be:

Request Default config Custom separator Avoid concatenation
request 1 Domestic Payments > Consent Domestic Payments-Consent Consent
request 2 Domestic Payments Domestic Payments Domestic Payments
request 3 Scheduled payments > Consent Scheduled payments-Consent Consent
request 4 Scheduled payments Scheduled payments Scheduled payments

Default config:

{
    concat = true,
    separator = ' > '
}

Custom separator:

{
    separator = '-'
}

Avoid concatenation

{
    concat = false
}

responseHeaders (Boolean)

This flag indicates if the headers that are saved as part of the postman collection examples (see feature Responses parsed from Postman collection examples) should be used in the OpenApi specification. This headers normally contain lot of unused headers but are automatically saved by postman when create an example, a better approach is to define response headers in a common way.

The default value is true, so headers are by default added to the response definition.

replaceVars (Boolean)

This flag indicates if the postman variables referenced in the postman collection should be replaced before generate the OpenAPI specs.

If set to true all variable references contained in the postman collection as “” will be replaced by his value defined at postman collection level or values provided the additionalVars Object.

Be aware that path variables defined as postman variables “” as for example a path like https://api.io/users/ will be also replaced if there exist a variable definition at postman collection or in the additionalVars Object.

The default value for this flag is false as variable replacement has a performance cost.

additionalVars (Object)

In postman, variables can be defined at different scopes level but only the ones defined at postman collection level will be saved inside collection file, to provide additional variable values, what we can call Global or Environment variables, there exist the additionalVars parameter.

This parameter is a json Object that contain as key the variable name and as value the variable value, as for example:

{
    additionalVars: {
        service : 'myService',
        company : 'myCompany'
    }
}

Take into account that variable values provided in the additionalVars Object supersede those defined at Postman collection level.

Features

Basic conversion

This library support the transformation from Postman collection to all the basic HTTP method as GET, POST, PUT… parse the body request of type “raw” (Json and Text), “form-data” (see “form-data” body section for more info about this mode) and “x-www-form-urlencoded” formats. Query parameters are also supported.

Have a look to the PostmantoOpenAPI collection file for an example of how to use this feature.

Basic API info

For fill the OpenAPI info object this library use the information defined in Postman collection level as “name” and “description”.

Postman don’t have any field at collection level that feat with OpenAPI “version” field (is a required field in OpenAPI specification), so this library look for a variable with name version in Postman collection variables or if variable is not defined then will use the default value 1.0.0.

You can customize all this information with the Info option.

For info about how to setup the contact and license properties have a look to section License and Contact configuration.

Have a look to the SimplePost collection file for an example of how to use this feature.

Folders as tags

In postman you can add folders inside your collection to group requests and keep the collection clean, in OpenAPI there are no folders but exist the concept of tags that has the same approximate meaning, this library automatically detect folders and use the name of the folder as tag name in the transformation.

If you have more than one level of folders you can configure the behavior to calculate the tag of the request, See option folders for more info about how to configure this feature and some examples.

As part of the implementation we now support description for tags, just add a description into the Postman Collection folder and automatically the tags section will be filled in the he OpenApi spec.

Have a look to the FolderCollection file for an example of how to use this feature.

Parameters parsing

This library automatically transform query and headers parameters from Postman operations tp OpenAPI specification, the populated info is the name, description and use the value of the parameter as an example.

The default schema used for parameters is string but the library try to infer the type of the parameters based on the value using regular expressions, the detected types are integer, number, boolean and string, if you find any problem in the inference process please open an issue.

This library now support the definition of path parameters using the postman notation defined in sending parameters,what basically consist in annotate params with a semicolon as for example /customer/:id, when postman detect this notation a new form appear in the request to define value and description of the parameters. This is the preferred way to define path parameters in a postman collection but also path parameters are automatically detected as postman variables, this library look for Postman variables in the url as “” and transform to a single curly brace expression as {variable} as supported by OpenAPI, also create the parameter definition using the variable name. To provide additional information about a path parameter you can Pass Meta-information as markdown. Be aware that if you use the replaceVar option the path parameter using Postman variables can be affected. See replaceVars option

For headers and query fields you can indicate that this parameter is mandatory/required adding into the description the literal [required]. The library use a case insensitive regexp so all variations are supported ([REQUIRED], [Required]…) and never mind the location inside the description (at the beginning, at the end…).

Have a look to the GetMethods collection, Headers collection and PathParams collection files for examples of how to use this features.

Postman authorization

The OpenAPI root security definition is filled using the authorization method defined at Postman Collection authorization config.

Only types ‘Basic Auth’ and ‘Bearer Token’ are supported by now. If you define an authorization at postman request level this will overwrite the global defined for this OpenAPI operation.

You can customize the global authorization definition using the Auth option.

Have a look to the collections AuthBasic, AuthBearer and AuthMultiple for examples of how to use this feature.

Global servers configuration

The OpenAPI root servers definition is filled parsing the urls used in the Postman collections requests, the library use all the different urls for create an array of server (removing duplicated), but normally this is not to usefully as Postman collection only will have one environment url, for this reason you can customize the global servers definition using the server option

If you don’t want to include a servers array in your OpenAPI spec file you just need to pass an empty array as server option, as for example:

const result = await postmanToOpenApi(postmanCollection, outputFile, { servers: [] })

This will remove the servers field from the yml specification result.

Pass data as postman collection variables

Inside the info object of OpenAPI definition exist some Object fields as contact, license or xLogo, this fields are very useful for provide information to developers, but inside a Postman collection not exist any “standard” way to save this information, for this reason we use Postman collection variables to define this options and maintain this info indie the postman collection.

Is as easy as define the values in the “Edit Collection” form page inside the tab “Variables”, as showed in the next image:

contact and license variables

The variables names will be in dot notation, for example for contact fields will be as contact.name, contact.url… Take into account that fields that are required by OpenAPI specs, as contact.name, if not provided then all the section will be ignored.

You can also customize this information using the Info option, note that info provided by options will overwrite the variables inside the Postman collection (has more priority) but values will be merged from both sources (postman variables and options).

Pass Meta-information as markdown

Note: postman already provide a way to define path variables that is recommended over use this solution, take into account that “Meta-information as markdown” would be probably deprecated in the future.

As Postman don’t provide a free way to pass meta information in all the sections, for example you cannot describe a Path parameter in Postman, the easy way we have found is to provide this information in the options parameter when calling the library, although this solution is not a bad solution, and give lot of freedom about where you store the info, we think that have all the info about the API in the Postman Collection is the best solution as you only have a source of information for document your APIs.

That’s the reason why API version can be defined as a postman collection variable, as described in Basic API Info section, but for some other information as for example describing a Path parameter where you should indicate multiples values as the description, if it is required, an example, schema type…. the solution of use collection variables don’t fit too well, for this reason we have add support for provide Meta-Information as a markdown table.

Taking advantage that Postman support markdown in description fields we have defined a especial section delimited with a md header # postman-to-openapi, where you can define a markdown table for provide Meta-Information. As an example:

# postman-to-openapi

| object | name     | description                    | required | type   | example   |
|--------|----------|--------------------------------|----------|--------|-----------|
| path   | user_id  | This is just a user identifier | true     | number | 476587598 |
| path   | group_id | Group of the user              | true     | string | RETAIL    |

This table is providing additional information about a Path parameter, the supported field in this moment are the column thats appear in the example. This way of provide Meta-information is supported in the Postman request description in this moment.

Take into account that postman-to-openapi remove from the description all the content after the key header # postman-to-openapi, so the meta-information table should be the last content of the description field.

Have a look to the collections PathParams for examples of how to use this feature.

Response status code parse from Test

By default the library use the value 200 as the response status code in all the operations, but this can be customize from Postman test “Test” script, if you operation contain a status check in the tests tab as:

pm.response.to.have.status(201)
// or
pm.expect(pm.response.code).to.eql(202)

The status code will be automatically parsed and used in the OpenAPI specification, take into account that feature Responses parsed from Postman collection examples has priority over this feature.

Responses parsed from Postman collection examples

As described in Postman docs is possible to save real responses from a server or create manually responses to save as examples in a postman request, this examples contain all the information about the request (method, url, headers, parameters…) and the corresponding response (body, headers, status code…) and will be automatically parsed by postman-to-openapi and added as an operation Response Object Example/Examples in the result OpenAPI specification.

Note that this examples will be added in OpenAPI specification as a ‘Operation Object > Responses Objects > content > Media Type Object > example or examples’ and not as a schema.

Actually multiple examples in the same request are supported with the same or different status code response as OpenAPI support the description of more than one example. The Supported Media Types in this moment are application/json and text/plain.

Take into account that this feature has priority over the Response status code parse from Test one so if postman-to-openapi detect that some example exist in the postman collection will no parse the test script.

If there are more than one example at request level the used headers will be the ones that appear in the last example in the postman collection.

“form-data” Body

Library postman-to-openapi is able to parse the Postman collection body request of type “form-data”, as Postman only support the parameter types Text and File (as you can see in next image) this are the only supported types for the Library.

form-data options

A “form-data” request body will be describe as a multipart/form-data content with schema of type object. For Text parameter postman-to-openapi will parse just as a type: string parameter and for type File following OpenAPI specs is parsed as type: string, format: binary

Postman collection examples

All the featured described in this doc are unit tested using real postman collections files as examples, we encourage you to use this collections files as an example of your own implementation.

You can found the examples collections inside the github repo in postman-to-openapi/test/resources/input/ folder, names of the files are self-descriptive.