Migrate from another platform

Move documentation from Document360, Redocly, Scalar, Slate, a static site generator, or a custom platform to ReadMe with reusable content, Branches and Reviews, and an OpenAPI-generated API Reference.

Move documentation from another platform to ReadMe by selecting the easiest supported import path, converting source-specific syntax, and verifying content before cutover. Whatever you're moving from, you gain an OpenAPI-generated API Reference with Try It!, reusable content blocks, and structured review through Branches and Reviews.

Choose the easiest migration path

Your situationRecommended path
You want to evaluate public documentation quicklyUse the Importer with a URL, Markdown files, or an OpenAPI definition.
You have a prepared Markdown or MDX repositoryUse Git-based import with the supported repository structure.
You need repeatable bulk uploads or CI automationUse rdme@10.
You have a small content setCreate and review pages in the ReadMe editor.
You have a large, complex, or enterprise migrationAsk about Enterprise migration assistance.

Use bi-directional Git Sync after migration when you need ongoing two-way editing. It connects ReadMe to a new, empty GitHub or GitLab repository and does not import an existing repository.

What commonly doesn't transfer, and what replaces it

What doesn't transferRebuild it with
Custom components or theme-specific markupCustom MDX components
Platform-specific theming and brandingThemes and Appearance settings
Hand-written endpoint documentationAn API Reference generated from your OpenAPI file, with Try It!
Includes or content snippetsReusable content
No OpenAPI file yetBuild one with the API Designer
Ad hoc review of documentation changesBranches and Reviews

Export and inventory source content

SourceStart with
Document360Export articles, categories, and media.
RedoclyCollect Markdown, the OpenAPI definition, and redocly.yaml.
ScalarCollect the OpenAPI definition and separately maintained Markdown guides.
SlateConvert the Markdown source and includes into individual Guide pages.
Hugo, Jekyll, or MkDocsExport Markdown and retain site configuration for navigation and redirects.
SphinxConvert reStructuredText to Markdown, then review directives and cross-references.
StoplightExport the OpenAPI definition — often multi-file — plus any Markdown guides stored alongside it.
SwaggerHubExport the OpenAPI definition. Hand-written guides usually live elsewhere; inventory them separately.
PostmanExport the collection and convert it with rdme openapi convert.
ApiaryExport the API Blueprint or OpenAPI definition, and the Markdown around it.
Bump.shCollect the OpenAPI or AsyncAPI definition and any separately maintained Markdown.
ConfluenceExport spaces to HTML or Markdown, then map the page tree to categories before converting.
Nextra, VitePress, Starlight, or DocsifyExport Markdown and retain site configuration for navigation and redirects.
Antora or AsciiDocConvert AsciiDoc to Markdown, then review includes, attributes, and cross-references.
A custom CMSExport one Markdown file per page with metadata, assets, and its source URL.

Keep the original export unchanged. Inventory page metadata, navigation, reusable content, images, downloads, OpenAPI files, custom markup, access rules, and public URLs before conversion.

Convert content and navigation

Convert one representative page for each source-specific construct, verify the result, and then automate only the conversions you have tested. Resolve build-time variables before upload, replace includes with reusable or inline content, and rebuild custom components only when they fit the ReadMe MDX model.

For CLI uploads, every new Guide needs title and category.uri; use position and parent.uri to define navigation. For Git-based import, prepare the supported folders and _order.yaml files.

---
title: Install the SDK
category:
  uri: Getting Started
position: 2
---

Upload and validate

Validate and upload an OpenAPI definition when you have one, then preview Guides before publishing:

# See what's actually in your definition before you change anything
npx rdme@10 openapi inspect ./openapi.yaml

npx rdme@10 openapi validate ./openapi.yaml

# --slug pins the definition's identity so its file path can change later
npx rdme@10 openapi upload ./openapi.yaml --slug my-api --key="$README_API_KEY"

npx rdme@10 docs upload ./docs --key="$README_API_KEY" --dry-run
📘

How your definition becomes navigation

One definition becomes one top-level category, named from info.title. The first tag on each operation becomes a page inside it, and each operation becomes a subpage titled from its summary. Operations without tags are grouped by URL; without a summary, subpages are titled by URL or by HTTP method.

Knowing this before you upload saves rearranging afterward. See Categories, Pages, and Subpages, the OpenAPI Compatibility Chart for what we support in the API Explorer, and OpenAPI Extensions for the x-readme options — including apply-tag-changes, which you'll want enabled while you're still restructuring.

An OpenAPI upload creates API Reference content from the operations in the definition. Compare it with hand-written endpoint content before removing that content, and retain workflows and conceptual guidance that the definition does not contain. Configure authentication before testing Try It!, and integrate the Metrics SDK separately when you need API-log data in the Developer Dashboard.

Set up redirects and cut over

Create redirects from the source sitemap, navigation, and traffic data. Under Admin Settings > Error Pages, add each redirect as oldurl -> newurl. Redirects are project settings rather than content, so they are not stored in your Git Sync repository and are not copied when a project is cloned — keep the map in source control as a plain text file so you can re-enter it. Verify source-specific markup is gone, assets load, navigation and access settings are correct, API Reference has the necessary supporting content, and redirects cover high-traffic URLs.

Keep the existing site available until you verify the migration and complete domain cutover.

Optional: continue in Git

After migration, connect a new empty repository through Settings > Git Connection for bi-directional Git Sync. Use folders and _order.yaml files to manage navigation in that ongoing workflow.


Developer nuances

🛠️

Details specific to your migration. For vendor extension compatibility, circular references, multi-file specs, and a full CI pipeline, see Developer Nuances.

Every Redocly & Redoc extension, and what to do with it

Covers both Redoc CE and Redocly. Find your extension in the left column — ReadMe either reads it, or there's something to do instead.

ExtensionWhat it does for youOn ReadMe
x-usePkcePKCE on an OAuth 2 authorizationCode flowSupported. Leave it as-is.
x-enumDescriptionsReadable labels for enum valuesSupported, same spelling, at the schema level.
x-internalHides an operationSupported, per operation or at the root.
x-code-samplesCustom code samples (Redocly's old spelling)✅ Works by coincidence — it matches ReadMe's own root-level alias for x-readme.code-samples.
x-codeSamplesCustom code samples (Redocly's current name)⚠️ Not read — matches neither ReadMe spelling. Rename and remap the fields — see below.
x-tagGroupsGroups tags in the sidebarSplit your spec per group with rdme openapi reduce — see the next section.
x-traitTagMarks a tag as a label, not a grouping⚠️ Every tag becomes a page on ReadMe, so a trait tag creates an empty page. Remove it.
x-displayNameHuman-friendly tag nameRename the tag itself in tags[].name — on ReadMe the tag name is the page name.
x-badgesBadges on operationsPut them in the operation description, which renders as Markdown.
x-logoLogo above the side menuUpload your logo under Appearance settings.
x-serversExtra target hosts (OAS 2.x backport)Use the standard servers array.
x-webhooksWebhooks on older OpenAPI versionsUse the native webhooks object. Requires OpenAPI 3.1.
x-hideReplayDisables Replay on an operationUse x-readme.explorer-enabled: false, per operation or at the root.
x-summaryShort response summary for the button labelUse the response description.
x-keywordsBoosts or excludes search resultsUse metadata.keywords in the page's frontmatter.
x-seoSEO meta tags on operation pagesUse metadata.title and metadata.description in the page's frontmatter.
x-metadataCustom metadata in infoUse the page's metadata frontmatter.
x-rbacAccess control on OpenAPI objectsUse x-internal plus Internal Documentation access controls.
x-mcpDocuments MCP servers and toolsReadMe generates its own MCP server from your definition.
x-explicitMappingOnlyLimits discriminator mappings to explicit onesDefine discriminator.mapping explicitly — ReadMe supports discriminators and mappings natively.
x-additionalPropertiesNameNames the key in an additionalProperties mapNo equivalent. Describe the key format in the schema description.
x-tagsPuts schemas in the nav beside operationsNo equivalent. Document shared schemas in a Guide instead.
x-assertionTypeOAuth flow assertion typeNo equivalent.
x-nullableNullable schema (OAS 2.x)Resolved on conversion. Use nullable: true (3.0) or type: [string, "null"] (3.1).
x-examplesRequest examples on body params (OAS 2.x)Resolved on conversion. Use the standard examples map.
📘

Anything not listed here is ignored rather than rejected, so it will never fail an upload — convenient if you're publishing the same file to more than one tool.

Custom code samples need two changes, not one

ReadMe reads custom code samples from x-readme.code-samples. As with every ReadMe extension, you can also write it at the root as x-code-samples.

Redocly's extension was also called x-code-samples once, so older Redocly specs happen to line up and work unchanged. Redocly has since renamed it to x-codeSamples in camelCase — and that matches neither ReadMe spelling. On a current Redocly spec, every hand-written sample disappears on upload and the operation silently falls back to auto-generated snippets.

Renaming the key is only half the job — the field names inside each sample differ too:

RedoclyReadMe
langlanguage
sourcecode
labelname

So this:

x-codeSamples:
  - lang: python
    label: Python 3
    source: |
      import requests

becomes this:

x-readme:
  code-samples:
    - language: python
      name: Python 3
      code: |
        import requests

Convert one operation by hand and confirm it renders before scripting the rest, then check them all with npx rdme@10 openapi inspect ./openapi.yaml --feature readme.

Redocly: keeping one source of truth without x-tagGroups

ReadMe's reference navigation is one definition per category, tags as pages, operations as subpages. x-tagGroups adds a level above tags that has nowhere to land.

Don't split your spec by hand — you'd lose your single source of truth. Split it at build time instead, using --title to name each resulting category:

npx rdme@10 openapi reduce ./openapi.yaml \
  --tag store --tag inventory \
  --title "Store & Inventory" \
  --out ./dist/store.json

npx rdme@10 openapi upload ./dist/store.json \
  --slug store --key="$README_API_KEY"

Repeat per group and run it in CI. Your repository still holds exactly one definition. See Developer Nuances for the full walkthrough.

Stoplight and SwaggerHub: your spec is already the hard part

Both are OpenAPI-native, which makes these the most straightforward migrations. Export the definition, run openapi inspect on it, and upload.

The one thing to check is how the definition is stored. Stoplight projects are frequently multi-file with relative $refs, which the dashboard and API reject — use rdme openapi upload, which bundles them. Hand-written Markdown guides stored alongside the spec migrate like any other Markdown.

Sphinx: convert first, fix cross-references second

Convert reStructuredText to Markdown with a tool like Pandoc, then treat cross-references as a separate pass. :ref: and :doc: roles become plain relative links, and most can be resolved from the reference labels with a script once you know the final slug for each page.

Directives without a Markdown equivalent (.. toctree::, .. autodoc::) need a decision each: toctree becomes your _order.yaml, and generated API documentation is usually better replaced by an OpenAPI definition than converted.

A custom CMS or no Markdown export at all

Write one Markdown file per page out of your platform's API, and capture more than the body text. You need the title, the source URL (for redirects), the parent page, its ordering, its visibility state, and the assets it references.

Export the source URL especially — it's the only thing that lets you build a redirect map afterward, and it's the field people most often forget until the old site is already down.

After you migrate

Run a Docs Audit to check content quality, build guided walkthroughs with Recipes, and use My Developers to see how developers use your API once your Metrics integration is live.

Frequently asked questions

We do not have a Markdown export. What should we do?

Use the platform API or an export tool to create one Markdown file per page. Include the title, source URL, parent page, ordering data, assets, and visibility state so you can reproduce the published site accurately.

We're on Sphinx and our cross-references are everywhere.

Convert with a tool such as Pandoc, then handle cross-references as a second pass. They usually become plain relative links, and a script can resolve most of them from the reference labels.

Do we need to migrate everything at once?

No. You can publish API Reference content from a validated OpenAPI definition separately from your Guides. Keep the existing documentation available until you have reviewed both areas and prepared redirects.


Did this page help you?