rdme Upload CLI and GitHub Action
Upload OpenAPI files and Markdown to ReadMe from a terminal or a CI job with rdme. If your project uses bi-directional sync, use the ReadMe CLI instead.
rdme uploads OpenAPI documents and Markdown pages to your ReadMe project from a terminal or a CI pipeline, so your docs update every time you ship code. Use it when your content lives outside a synced Git repository and you want to push it to ReadMe on deploy.
If your project has Bi-Directional Sync enabled, you don't need rdme. Publishing happens when you merge, and the ReadMe CLI (@readme/cli) handles validation, linting, and endpoint maintenance. Keep Your API Docs Synced With OpenAPI walks through that setup. The difference is direction: rdme pushes one way, from your files to ReadMe, so edits made in the ReadMe editor don't flow back to your repository, and there are no branches or reviews on the ReadMe side.
Prerequisites
- A ReadMe API key with write access to the project. Create one under Project Settings → API Keys.
- Node.js 20 or later, for running
npx rdmein CI. The GitHub Action supplies its own runtime. - The
rdmemajor version that matches your project architecture:
| Your project | CLI | GitHub Action |
|---|---|---|
| ReadMe Refactored | rdme@10 | readmeio/rdme@v10 |
| Legacy (not yet migrated) | rdme@9 | readmeio/rdme@v9 |
Every example on this page uses @v10. If you're on legacy, substitute @v9. To move between them, see the ReadMe Refactored migration guide. Configure Dependabot on your repository to keep the action version current.
Full installation instructions and the complete command list live in the rdme GitHub repository.
Commands
| Command | Uploads | Versioned (--branch) |
|---|---|---|
rdme openapi upload <url-or-path> | An OpenAPI or Swagger document to the API Reference, bundling external $refs and validating first (OpenAPI 3.1 included) | Yes |
rdme docs upload <path> | A Markdown file or directory to Guides | Yes |
rdme reference upload <path> | A Markdown file or directory to the API Reference | Yes |
rdme changelog upload <path> | A Markdown file or directory to the Changelog | No |
rdme custompages upload <path> | A Markdown or HTML file or directory to Custom Pages | Yes |
rdme docs export <path> | export <path>Downloads your Guides as Markdown files into a local directory | Yes |
rdme reference export <path> | Downloads your API Reference pages as Markdown files into a local directory | Yes |
| Flag | Applies to | Effect |
|---|---|---|
--key=<api-key> | All | Authenticates the request. Required. |
--branch=<name> | openapi, docs, reference, custompages | Targets a branch (formerly a version). Omit it to target your default branch. Changelog entries aren't versioned. |
--dry-run | Markdown uploads | Validates frontmatter and prints what would be created or updated without changing anything in ReadMe |
Run every Markdown command with --dry-run first when setting up new pages. The output lists each page, whether it would be created or updated, and every attribute it parsed. The export commands go the other way: they pull your published pages down as Markdown, which is useful for a backup, a migration, or moving a project onto bi-directional sync
rdme docs upload docs/ --key=$README_API_KEY --dry-runMarkdown File Setup
rdme is directory-agnostic. It reads each Markdown file's YAML frontmatter to decide where the page goes, so your local folder layout has no effect on the sidebar. Files without frontmatter are skipped.
If you'd rather have your directory structure mirror your sidebar, that's what Bi-Directional Sync does.
Required Attributes
| Attribute | changelog upload | custompages upload | docs upload | reference upload |
|---|---|---|---|---|
title | Required | Required | Required | Required |
category.uri | Not used | Not used | Required | Required |
These are required to create a page. Later uploads of the same file only need the attributes you're changing; anything you omit keeps its current value.
Category
Set category.uri to either the full URI from the Get all categories endpoint or just its final segment:
---
title: Syncing Docs via CLI / GitHub
category:
uri: /branches/3.0/categories/guides/documentation
------
title: Syncing Docs via CLI / GitHub
category:
uri: documentation
---Page Order and Parent Pages
Guides and API Reference pages have a sidebar, so they accept two more hierarchy attributes. position sets the page's order within its category. parent.uri makes the page a child of another page in the same category.
---
title: Example child page
category:
uri: documentation
parent:
uri: parent
position: 2
---Slugs
The slug comes from the file name: rdme.md uploaded to Guides publishes at /docs/rdme. File names are run through slugify, so spaces and special characters change on upload. To decouple the slug from the file name, set it explicitly:
---
title: Example page
category:
uri: documentation
slug: an-alternative-page-slug-example
---Other Attributes
Any attribute the ReadMe API accepts on page creation can go in frontmatter. privacy.view set to public or anyone_with_link publishes or hides the page. Changelog entries take a type such as added. Custom Pages set content.type to html or markdown automatically based on the file extension, and you can override it. The complete lists are on the create endpoints: Create doc, Create reference, Create changelog, Create custom page.
GitHub Actions
The readmeio/rdme action runs any rdme command inside a GitHub Actions workflow. The usual triggers are a push to the default branch, a deploy, or a release.
-
Create a workflow file in
.github/workflows/, or open an existing one. -
Set the
onproperty to the event that should trigger the upload. -
Add a checkout step and the
rdmestep:# Required so the action can read your repository's contents - uses: actions/checkout@v4 # Runs the rdme command against your repository - uses: readmeio/rdme@v10 with: rdme: [your command here]
The rdme input takes the same syntax as the CLI, minus the leading rdme. This CLI command:
rdme openapi upload openapi.yaml --key=$README_API_KEYbecomes this step:
- uses: readmeio/rdme@v10
with:
rdme: openapi upload openapi.yaml --key=${{ secrets.README_API_KEY }}Complete workflow files are on the two example pages: Syncing an OpenAPI definition and Syncing a directory of Markdown files.
⚠️ Store your API key as a repository secret, never in the workflow file. Create a secret named README_API_KEY under your repository's Settings → Secrets and variables → Actions, and reference it as ${{ secrets.README_API_KEY }}. This applies to private repositories as well as public ones; a key committed to a private repository is still in every clone and every fork. See GitHub's documentation on encrypted secrets.
This page is itself uploaded from the rdme repository by the rdme GitHub Action. The source file, the workflow, and its run history are public if you want a working example to copy.
Other CI Environments
rdme is a Node.js CLI, so any CI system that runs shell commands can call it with npx rdme@v10. Store the API key in your CI provider's secrets and load it as $README_API_KEY.
Bitbucket Pipelines, bitbucket-pipelines.yml:
image: node:20
pipelines:
default:
- step:
script:
- npx rdme@v10 openapi upload openapi.yaml --key=$README_API_KEYCircleCI, .circleci/config.yml:
version: 2.1
jobs:
sync-docs:
docker:
- image: cimg/node:20.0
steps:
- checkout
- run: npx rdme@v10 openapi upload openapi.yaml --key=$README_API_KEY
workflows:
sync:
jobs:
- sync-docsGitLab CI, .gitlab-ci.yml:
image: node:20
sync-docs:
script:
- npx rdme@v10 openapi upload openapi.yaml --key=$README_API_KEYTravis CI, .travis.yml:
language: node_js
node_js:
- 20
script:
- npx rdme@v10 openapi upload openapi.yaml --key=$README_API_KEYSecrets documentation for each: Bitbucket Pipelines, CircleCI, GitLab CI, Travis CI. If one of these examples stops working, open an issue on the rdme repository.
Troubleshooting
Pages were created in the wrong place, or overwritten. Run the same command with --dry-run and read the output. It shows the category, parent, slug, and create-or-update decision for every file before anything changes.
The CLI fails or does something unexpected. Set the DEBUG environment variable to print detailed logs:
DEBUG=rdme* rdme openapi upload openapi.yaml --key=$README_API_KEYInclude these logs, and a copy of the files you're uploading, when you contact support. Don't leave DEBUG set in production pipelines.
The GitHub Action fails. Set the repository secret ACTIONS_STEP_DEBUG to true to enable step debug logs, then rerun the workflow. GitHub's documentation covers viewing and downloading logs.
⚠️ Step debug logs can expose sensitive information. GitHub masks values loaded from secrets, but anything else in your workflow's environment is logged in full and visible to everyone with read access to the repository. Enable this only in a private repository. If you're working in a public one, reproduce the workflow in a private test repository first. If sensitive data does land in a log, delete the log.
Updated 4 days ago