DEV Community

Cover image for How to Convert OpenAPI Specs to Clean Markdown Docs Automatically
Hassann
Hassann

Posted on • Originally published at apidog.com

How to Convert OpenAPI Specs to Clean Markdown Docs Automatically

Your OpenAPI file is the source of truth for your API: paths, parameters, request bodies, response schemas, and examples. But raw YAML or JSON is not the best format for everyday review. Backend engineers need a quick endpoint reference in the repo. Frontend developers need request/response fields they can scan in a PR. Technical writers need content they can paste into a wiki without rewriting the schema.

Try Apidog today

Markdown is the practical output format for that workflow. It renders in GitHub, Confluence, Notion, static site generators, and plain text editors. The implementation goal is simple: take an existing openapi.yaml and generate clean Markdown automatically so the docs stay aligned with the API.

Why generate Markdown from OpenAPI?

An OpenAPI document is machine-readable by design. Tools use it to generate clients, validate requests, run contract tests, and render interactive docs.

Markdown solves a different problem: distributing API information to humans in places that do not run an OpenAPI renderer.

Common use cases:

  • Add an API reference to README.md or /docs.
  • Include endpoint details in pull request descriptions.
  • Publish API contracts in Confluence, Notion, or an internal wiki.
  • Feed a static documentation site built with Docusaurus, MkDocs, or Hugo.

The important part is automation. A Markdown file written manually will drift. A Markdown file regenerated from the OpenAPI spec on every change stays accurate.

Before generating docs, validate the spec itself. If the source is broken, the output will be broken too. For validation options, see the OpenAPI validator tools guide.

Choose a conversion method

There is no single official OpenAPI command for Markdown export. In practice, you choose from converters, custom scripts, or an API documentation platform.

Method Best for Output
openapi-to-md / openapi-markdown Fast Markdown generation with minimal setup Single Markdown file or schema tables
Widdershins Static docs sites with code samples Themeable Markdown with language tabs
Custom script Team-specific layout Whatever you template
Apidog Spec import, hosted docs, and tests in one workspace Rendered docs plus Markdown content blocks

Method 1: Generate Markdown with a one-line converter

If you only need a quick repo reference, use a dedicated converter.

For Node.js projects, openapi-to-md can convert OpenAPI v2 or v3 YAML/JSON into Markdown:

npx openapi-to-md openapi.yaml api-reference.md
Enter fullscreen mode Exit fullscreen mode

For Python workflows, openapi-markdown provides a similar command:

pip install openapi-markdown
openapi2markdown openapi.yaml api-reference.md
Enter fullscreen mode Exit fullscreen mode

These tools read the spec, walk the paths and schemas, and generate headings, parameter tables, and response sections.

Use this when:

  • You want a single generated reference file.
  • The default layout is acceptable.
  • You want minimal setup.

Avoid this when:

  • You need custom section ordering.
  • You need language-specific code samples.
  • You need one page per tag/resource.

Method 2: Use Widdershins for docs sites and code samples

Widdershins converts OpenAPI/Swagger files into Slate-compatible Markdown. It is useful when your Markdown feeds a documentation site and you want code tabs.

Install and run it:

npm install -g widdershins
widdershins openapi.yaml -o api-reference.md
Enter fullscreen mode Exit fullscreen mode

Add language tabs:

widdershins \
  --language_tabs 'shell:cURL' 'python:Python' 'javascript:JavaScript' \
  --omitHeader \
  openapi.yaml \
  -o api-reference.md
Enter fullscreen mode Exit fullscreen mode

Use --omitHeader when your static site generator adds its own front matter or page wrapper.

Widdershins is a good fit when:

  • You publish docs with Docusaurus, MkDocs, Hugo, or a similar tool.
  • You want code samples next to endpoints.
  • You need more control than a basic converter provides.

The trade-off: you now own a template and a build step.

Method 3: Write a custom generator for an exact layout

If no converter matches your internal documentation style, parse the OpenAPI file and generate Markdown yourself.

This minimal Node.js script lists each operation and its parameters:

import { readFileSync, writeFileSync } from "node:fs";
import yaml from "js-yaml";

const spec = yaml.load(readFileSync("openapi.yaml", "utf8"));

const lines = [
  `# ${spec.info.title}`,
  "",
  spec.info.description ?? "",
  "",
];

for (const [path, methods] of Object.entries(spec.paths)) {
  for (const [method, op] of Object.entries(methods)) {
    lines.push(`## ${method.toUpperCase()} ${path}`);
    lines.push("");
    lines.push(op.summary ?? "");
    lines.push("");

    const params = op.parameters ?? [];

    if (params.length) {
      lines.push("| Name | In | Required | Description |");
      lines.push("| ---- | -- | -------- | ----------- |");

      for (const p of params) {
        lines.push(
          `| ${p.name} | ${p.in} | ${p.required ? "yes" : "no"} | ${p.description ?? ""} |`
        );
      }

      lines.push("");
    }
  }
}

writeFileSync("api-reference.md", lines.join("\n"));
Enter fullscreen mode Exit fullscreen mode

Install the YAML parser:

npm install js-yaml
Enter fullscreen mode Exit fullscreen mode

Run the script:

node generate-docs.js
Enter fullscreen mode Exit fullscreen mode

Extend it as needed:

  • Split files by tag.
  • Add request body schemas.
  • Add response examples.
  • Add authentication notes.
  • Generate an endpoint index.
  • Match your internal table format.

Use this method when the generated structure matters more than broad OpenAPI feature coverage. If you want to compare maintained tools before writing your own, see this roundup of API documentation generators with Markdown export.

Method 4: Keep specs, docs, and tests together in Apidog

One-shot converters generate Markdown, but the output can still drift if nobody reruns the command.

Apidog approaches this differently. You import your existing openapi.yaml, and Apidog reads the paths, schemas, and examples into a project. From there, it generates hosted API documentation from the imported spec without a separate Markdown build step.

Useful starting points:

Apidog is useful when you want generated reference docs and hand-written content in the same workspace. You can add Markdown content blocks for:

  • Getting started guides
  • Authentication notes
  • Changelogs
  • Usage examples
  • Internal review notes

See these documentation creation tips with Apidog Markdown for the authoring workflow.

The same imported spec can also become the basis for tests. You build requests and assertions against the endpoints defined by the spec, then run them to verify that the live API still matches the contract.

To try that workflow, download Apidog, import your spec, and open the generated docs in the project.

Automate Markdown generation in CI

A converter you run manually will eventually be forgotten. Run generation automatically whenever the OpenAPI spec changes.

Here is a GitHub Actions workflow that regenerates docs/api-reference.md when openapi.yaml changes:

name: Generate API docs

on:
  push:
    paths:
      - "openapi.yaml"

jobs:
  docs:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: "20"

      - name: Convert spec to Markdown
        run: npx openapi-to-md openapi.yaml docs/api-reference.md

      - name: Commit regenerated docs
        run: |
          git config user.name "docs-bot"
          git config user.email "docs-bot@users.noreply.github.com"
          git add docs/api-reference.md
          git diff --staged --quiet || git commit -m "docs: regenerate API reference"
          git push
Enter fullscreen mode Exit fullscreen mode

This keeps the generated Markdown at most one commit behind the spec.

You can swap the conversion step for Widdershins:

- name: Convert spec to Markdown
  run: |
    npm install -g widdershins
    widdershins \
      --language_tabs 'shell:cURL' 'python:Python' 'javascript:JavaScript' \
      --omitHeader \
      openapi.yaml \
      -o docs/api-reference.md
Enter fullscreen mode Exit fullscreen mode

Or call your custom script:

- name: Convert spec to Markdown
  run: node scripts/generate-docs.js
Enter fullscreen mode Exit fullscreen mode

Add contract tests to the same pipeline

Generated docs are only useful if the OpenAPI spec still matches the live API. Add a test step after generation.

The Apidog CLI can run test scenarios headlessly:

npm install -g apidog-cli
apidog run --access-token $APIDOG_ACCESS_TOKEN -t 605067 -e 1629989 -r cli
Enter fullscreen mode Exit fullscreen mode

If an assertion fails, the command exits non-zero and fails the build.

References:

This gives you a tighter loop:

  1. OpenAPI spec changes.
  2. Markdown docs regenerate.
  3. API contract tests run.
  4. CI blocks stale or inaccurate documentation.

Clean up generated Markdown

Generated Markdown usually needs a few rules to stay readable.

  • Strip front matter when your renderer does not need it. Widdershins supports --omitHeader.
  • Decide whether to generate one file or split by tag/resource.
  • Keep examples realistic in the OpenAPI spec. Most converters reuse example and examples values.
  • Do not hand-edit generated files. Put manual content in separate Markdown files.
  • Validate the spec before generating docs.

If the output looks messy, fix the source spec first. Cleaner OpenAPI produces cleaner Markdown. The OpenAPI validator tools post covers tools for catching issues before generation.

Which method should you use?

Use this as a quick decision guide:

  • Need a simple repo reference? Use openapi-to-md or openapi-markdown.
  • Building a docs site with code tabs? Use Widdershins.
  • Need a strict internal layout? Write a small custom generator.
  • Want hosted docs, Markdown content, imported specs, and tests in one workspace? Use Apidog.

These approaches can also be combined. For example, you can use Apidog for hosted docs and testing, while also generating a Markdown reference in CI for offline repo browsing.

Final workflow

Treat Markdown as a generated artifact, not the source of truth.

A practical implementation looks like this:

  1. Maintain openapi.yaml as the canonical API contract.
  2. Validate the spec before publishing.
  3. Generate Markdown with a converter, Widdershins, or a custom script.
  4. Run generation in CI whenever the spec changes.
  5. Run API tests to confirm the implementation still matches the contract.
  6. Keep hand-written guides separate from generated reference files.

Once that pipeline is in place, your Markdown docs stay useful because they are continuously regenerated from the same OpenAPI contract your tools and tests already depend on.

Top comments (0)