Mintlify Setup & Migration Guide for API Portals

Mintlify is a hosted documentation platform that turns an OpenAPI document and a set of MDX pages into a deployed developer portal. This guide is part of Developer Portal Frameworks & UI Setup, and it covers initializing a Mintlify project, binding an OpenAPI spec, configuring CI validation, and migrating legacy documentation with 301 redirects and a zero-downtime cutover. It does not cover self-hosting — Mintlify’s deployment model is its managed cloud, and that constraint shapes every decision below.

The hard parts of a Mintlify migration are not the editor or the theme. They are the redirect map that preserves your existing search rankings and inbound links, the spec-version mismatch that produces broken reference pages silently, and the navigation entries that must line up exactly with files on disk. Get those three right and the rest is configuration.

Mintlify migration and deploy flow Legacy docs are audited and redirected, the spec is bound in docs.json, CI checks links, and Mintlify Cloud deploys. Migration and deploy flow legacy docs audit URLs docs.json spec + redirects CI: broken-links pre-merge gate Mintlify Cloud deploy on push 301 redirects preserve inbound links

Prerequisites & Environment Setup

  • Node.js 18+ to run the Mintlify CLI locally.
  • A GitHub repository connected to Mintlify through the dashboard (this is how deployment is triggered).
  • An OpenAPI 3.0.x or 3.1.x document. Swagger 2.0 is not supported and must be converted.
npm install -g mint     # the CLI package was renamed from `mintlify` to `mint`
mint dev                # local preview at http://localhost:3000
mint --version

The recommended repository layout keeps the spec and config at the root so the cloud build finds them without extra configuration:

docs/
├─ docs.json            # single config file (was mint.json)
├─ quickstart.mdx
├─ reference/
│  └─ openapi.yaml      # bound spec
└─ logo.svg

If you are migrating from Swagger 2.0, convert once and commit the OpenAPI output rather than converting on every build:

npx swagger2openapi swagger.yaml -o reference/openapi.yaml

Core Configuration

docs.json is the single source of configuration: navigation, theming, the bound spec, and redirects. It must live at the repository root and be committed. Mintlify reads it on every build to construct the navigation tree and mount the OpenAPI reference at the path matching the openapi key. Each significant key is annotated inline.

{
  "$schema": "https://mintlify.com/docs.json",
  "name": "API Portal",
  "logo": { "light": "/logo.svg", "dark": "/logo-dark.svg" },
  "favicon": "/favicon.svg",
  "colors": {
    "primary": "#16306d",          // brand accent used for links and buttons
    "light": "#4c9aff",            // primary tint for dark mode
    "dark": "#0b1120"
  },
  "navigation": {
    "groups": [
      { "group": "Getting Started", "pages": ["quickstart"] },
      { "group": "API Reference", "pages": ["reference/openapi"] }
    ]
  },
  "openapi": "/reference/openapi.yaml",  // path is relative to repo root; mounts the reference
  "redirects": [
    {
      "source": "/v1/docs/:path*",       // glob with a wildcard segment
      "destination": "/reference/:path*",
      "permanent": true                   // emits a 301 so rankings transfer
    }
  ]
}

The legacy mint.json uses the same keys under a flatter shape (a top-level navigation array of { "group", "pages" } objects). When you run mint dev against a mint.json project, the CLI writes the equivalent docs.json. New work should target docs.json directly.

Every string in a pages array must correspond to an .mdx file at that path relative to the root. A mismatch produces a build error naming the missing page — this is the most frequent first-run failure.

Integration Pattern

Mintlify Cloud deploys automatically when you push to the connected branch, so the CI job’s purpose is validation, not deployment. Run a link check and a spec lint before any merge so broken navigation never reaches the cloud build. This mirrors the fail-fast validation used in the Docusaurus for API Portals pipeline.

# .github/workflows/docs-validate.yml
name: Validate Docs
on:
  push:
    branches: [main]
  pull_request:
    branches: [main]
jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: '20'
      - name: Lint OpenAPI spec        # confirm version + validity before binding
        run: npx @redocly/cli@latest lint reference/openapi.yaml
      - name: Install Mintlify CLI
        run: npm install -g mint
      - name: Check internal links     # validates navigation against files on disk
        run: mint broken-links

Because Mintlify deploys on push, this validation job is the effective production gate: keep it required on the connected branch so a green check is a precondition for the cloud build picking up the change.

Advanced Options

Multiple specs and a version switcher

Declare one navigation group per spec, each with its own openapi reference, to host several API versions or several products side by side:

{
  "navigation": {
    "groups": [
      { "group": "API v2", "openapi": "/reference/v2.yaml", "pages": ["reference/v2/overview"] },
      { "group": "API v1", "openapi": "/reference/v1.yaml", "pages": ["reference/v1/overview"] }
    ]
  }
}

A polished version-switcher dropdown is not automatic; wire it through navigation tabs or anchors pointing at each group’s landing page.

Reusable MDX snippets

Factor repeated content — auth headers, rate-limit notes, status-code tables — into snippet components and import them across reference pages. This keeps the contract description consistent without duplicating prose, and pairs well with example reuse covered in Example Payload Management.

Theme parity for light and dark

Provide both logo.light and logo.dark and a colors.light tint so the reference reads correctly in both modes. The token discipline behind robust dual-theme portals is detailed in Multi-Theme & Dark Mode Support.

Verification & Testing

Validate locally before relying on the cloud build:

# 1. Confirm the spec parses and is the right version
npx @redocly/cli@latest lint reference/openapi.yaml   # expect no errors

# 2. Start the local preview and watch for navigation/page errors in the console
mint dev                                              # http://localhost:3000

# 3. Check that every navigation entry resolves to a real file and redirect target
mint broken-links                                     # expect "No broken links found"

A clean mint broken-links run plus a mint dev session with no missing-page warnings in the terminal means the build will succeed in the cloud. After cutover, request a handful of old URLs with curl -I and confirm each returns HTTP/1.1 301 pointing at the new path.

Troubleshooting

OpenAPI spec version mismatch — Mintlify requires OpenAPI 3.0.x or 3.1.x; a Swagger 2.0 document fails silently or renders broken reference pages. Run npx @redocly/cli lint reference/openapi.yaml to confirm the openapi: version field and overall validity, and convert with swagger2openapi before binding.

Navigation page not found at build — A string in a pages array has no matching .mdx file at that path relative to the root. The build error names the missing page; either create the file or correct the entry. Paths are case-sensitive on the cloud build even if they resolved on macOS.

Broken internal links after migration — Relative Markdown links that worked in a flat directory break under Mintlify’s nested navigation. Replace file-system links with the slugs declared in docs.json navigation entries, then re-run mint broken-links.

Old URLs return 404 after cutover — A redirect is missing from the redirects array or used "permanent": false (a 302 that does not transfer ranking). Audit the old site’s URL list, add a "permanent": true entry for every changed path, and verify each with curl -I before pointing DNS at the new portal.

FAQ

Does Mintlify support multi-version API documentation?

Mintlify supports multiple OpenAPI specs by declaring separate navigation groups, each pointing at a distinct spec path. A full version-switcher UI is not automatic and requires manual navigation configuration.

How do I migrate existing Markdown files without breaking links?

Rename the files to .mdx and commit them, add redirect entries for any path that changed, then run mint broken-links before pushing to your connected branch. The redirects preserve inbound links while the check catches dead internal navigation targets.

Can I integrate Mintlify with existing CI/CD pipelines?

Yes. Mintlify deploys on push to your connected branch, so any CI step that validates content and then merges to that branch triggers a deployment. The mint broken-links command is the main pre-merge gate available outside the cloud build environment.

Should I use docs.json or mint.json?

New projects use docs.json; mint.json is the legacy filename. Running the CLI on an existing mint.json project generates an equivalent docs.json automatically, and the configuration keys are otherwise unchanged.